sf: Change interface definition methodology (#1074)
* sf: Begin experimenting with new interface declaration format * sf: convert fs interfaces to new format * sf: finish conversion of libstrat to new definitions * sf: convert loader to new format * sf: convert spl to new format * sf: update ncm for new format * sf: convert pm to new format * sf: convert ro/sm to new format * sf: update fatal for new format * sf: support building dmnt under new scheme * sf: update ams.mitm for new format * sf: correct invocation def for pointer holder * fs: correct 10.x+ user bindings for Get*SpaceSize
This commit is contained in:
@@ -37,7 +37,7 @@ namespace ams::mitm::bpc_ams {
|
||||
{
|
||||
Handle bpcams_h;
|
||||
R_ABORT_UNLESS(svcManageNamedPort(&bpcams_h, AtmosphereServiceName.name, AtmosphereMaxSessions));
|
||||
g_server_manager.RegisterServer<bpc::AtmosphereService>(bpcams_h);
|
||||
g_server_manager.RegisterServer<bpc::impl::IAtmosphereInterface, bpc::AtmosphereService>(bpcams_h);
|
||||
}
|
||||
|
||||
/* Loop forever, servicing our services. */
|
||||
|
||||
@@ -18,20 +18,21 @@
|
||||
|
||||
namespace ams::mitm::bpc {
|
||||
|
||||
class AtmosphereService final : public sf::IServiceObject {
|
||||
private:
|
||||
enum class CommandId {
|
||||
RebootToFatalError = 65000,
|
||||
SetRebootPayload = 65001,
|
||||
};
|
||||
private:
|
||||
namespace impl {
|
||||
|
||||
#define AMS_BPC_MITM_ATMOSPHERE_INTERFACE_INTERFACE_INFO(C, H) \
|
||||
AMS_SF_METHOD_INFO(C, H, 65000, void, RebootToFatalError, (const ams::FatalErrorContext &ctx)) \
|
||||
AMS_SF_METHOD_INFO(C, H, 65001, void, SetRebootPayload, (const ams::sf::InBuffer &payload))
|
||||
|
||||
AMS_SF_DEFINE_INTERFACE(IAtmosphereInterface, AMS_BPC_MITM_ATMOSPHERE_INTERFACE_INTERFACE_INFO)
|
||||
|
||||
}
|
||||
|
||||
class AtmosphereService final {
|
||||
public:
|
||||
void RebootToFatalError(const ams::FatalErrorContext &ctx);
|
||||
void SetRebootPayload(const ams::sf::InBuffer &payload);
|
||||
public:
|
||||
DEFINE_SERVICE_DISPATCH_TABLE {
|
||||
MAKE_SERVICE_COMMAND_META(RebootToFatalError),
|
||||
MAKE_SERVICE_COMMAND_META(SetRebootPayload),
|
||||
};
|
||||
};
|
||||
static_assert(impl::IsIAtmosphereInterface<AtmosphereService>);
|
||||
|
||||
}
|
||||
|
||||
@@ -18,12 +18,19 @@
|
||||
|
||||
namespace ams::mitm::bpc {
|
||||
|
||||
class BpcMitmService : public sf::IMitmServiceObject {
|
||||
private:
|
||||
enum class CommandId {
|
||||
ShutdownSystem = 0,
|
||||
RebootSystem = 1,
|
||||
};
|
||||
namespace impl {
|
||||
|
||||
#define AMS_BPC_MITM_INTERFACE_INFO(C, H) \
|
||||
AMS_SF_METHOD_INFO(C, H, 0, Result, ShutdownSystem, ()) \
|
||||
AMS_SF_METHOD_INFO(C, H, 1, Result, RebootSystem, ())
|
||||
|
||||
AMS_SF_DEFINE_MITM_INTERFACE(IBpcMitmInterface, AMS_BPC_MITM_INTERFACE_INFO)
|
||||
|
||||
}
|
||||
|
||||
class BpcMitmService : public sf::MitmServiceImplBase {
|
||||
public:
|
||||
using MitmServiceImplBase::MitmServiceImplBase;
|
||||
public:
|
||||
static bool ShouldMitm(const sm::MitmProcessInfo &client_info) {
|
||||
/* We will mitm:
|
||||
@@ -36,16 +43,10 @@ namespace ams::mitm::bpc {
|
||||
client_info.override_status.IsHbl();
|
||||
}
|
||||
public:
|
||||
SF_MITM_SERVICE_OBJECT_CTOR(BpcMitmService) { /* ... */ }
|
||||
protected:
|
||||
/* Overridden commands. */
|
||||
Result ShutdownSystem();
|
||||
Result RebootSystem();
|
||||
public:
|
||||
DEFINE_SERVICE_DISPATCH_TABLE {
|
||||
MAKE_SERVICE_COMMAND_META(ShutdownSystem),
|
||||
MAKE_SERVICE_COMMAND_META(RebootSystem),
|
||||
};
|
||||
};
|
||||
static_assert(impl::IsIBpcMitmInterface<BpcMitmService>);
|
||||
|
||||
}
|
||||
|
||||
@@ -39,7 +39,7 @@ namespace ams::mitm::bpc {
|
||||
|
||||
/* Create bpc mitm. */
|
||||
const sm::ServiceName service_name = (hos::GetVersion() >= hos::Version_2_0_0) ? MitmServiceName : DeprecatedMitmServiceName;
|
||||
R_ABORT_UNLESS(g_server_manager.RegisterMitmServer<BpcMitmService>(service_name));
|
||||
R_ABORT_UNLESS((g_server_manager.RegisterMitmServer<impl::IBpcMitmInterface, BpcMitmService>(service_name)));
|
||||
|
||||
/* Loop forever, servicing our services. */
|
||||
g_server_manager.LoopProcess();
|
||||
|
||||
@@ -35,9 +35,9 @@ namespace ams::mitm::fs {
|
||||
|
||||
os::Mutex g_data_storage_lock(false);
|
||||
os::Mutex g_storage_cache_lock(false);
|
||||
std::unordered_map<u64, std::weak_ptr<IStorageInterface>> g_storage_cache;
|
||||
std::unordered_map<u64, std::weak_ptr<ams::fssrv::sf::IStorage>> g_storage_cache;
|
||||
|
||||
std::shared_ptr<IStorageInterface> GetStorageCacheEntry(ncm::ProgramId program_id) {
|
||||
std::shared_ptr<ams::fssrv::sf::IStorage> GetStorageCacheEntry(ncm::ProgramId program_id) {
|
||||
std::scoped_lock lk(g_storage_cache_lock);
|
||||
|
||||
auto it = g_storage_cache.find(static_cast<u64>(program_id));
|
||||
@@ -48,7 +48,7 @@ namespace ams::mitm::fs {
|
||||
return it->second.lock();
|
||||
}
|
||||
|
||||
void SetStorageCacheEntry(ncm::ProgramId program_id, std::shared_ptr<IStorageInterface> *new_intf) {
|
||||
void SetStorageCacheEntry(ncm::ProgramId program_id, std::shared_ptr<ams::fssrv::sf::IStorage> *new_intf) {
|
||||
std::scoped_lock lk(g_storage_cache_lock);
|
||||
|
||||
auto it = g_storage_cache.find(static_cast<u64>(program_id));
|
||||
@@ -69,7 +69,17 @@ namespace ams::mitm::fs {
|
||||
return (tmp != 0);
|
||||
}
|
||||
|
||||
Result OpenHblWebContentFileSystem(sf::Out<std::shared_ptr<IFileSystemInterface>> &out, ncm::ProgramId client_program_id, ncm::ProgramId program_id, FsFileSystemType filesystem_type) {
|
||||
template<typename... Arguments>
|
||||
constexpr ALWAYS_INLINE auto MakeSharedFileSystem(Arguments &&... args) {
|
||||
return sf::MakeShared<ams::fssrv::sf::IFileSystem, ams::fssrv::impl::FileSystemInterfaceAdapter>(std::forward<Arguments>(args)...);
|
||||
}
|
||||
|
||||
template<typename... Arguments>
|
||||
constexpr ALWAYS_INLINE auto MakeSharedStorage(Arguments &&... args) {
|
||||
return sf::MakeShared<ams::fssrv::sf::IStorage, ams::fssrv::impl::StorageInterfaceAdapter>(std::forward<Arguments>(args)...);
|
||||
}
|
||||
|
||||
Result OpenHblWebContentFileSystem(sf::Out<std::shared_ptr<ams::fssrv::sf::IFileSystem>> &out, ncm::ProgramId client_program_id, ncm::ProgramId program_id, FsFileSystemType filesystem_type) {
|
||||
/* Verify eligibility. */
|
||||
bool is_hbl;
|
||||
R_UNLESS(R_SUCCEEDED(pm::info::IsHblProgramId(&is_hbl, program_id)), sm::mitm::ResultShouldForwardToSession());
|
||||
@@ -88,11 +98,11 @@ namespace ams::mitm::fs {
|
||||
const sf::cmif::DomainObjectId target_object_id{serviceGetObjectId(&sd_fs.s)};
|
||||
std::unique_ptr<fs::fsa::IFileSystem> sd_ifs = std::make_unique<fs::RemoteFileSystem>(sd_fs);
|
||||
|
||||
out.SetValue(std::make_shared<IFileSystemInterface>(std::make_shared<fs::ReadOnlyFileSystem>(std::make_unique<fssystem::SubDirectoryFileSystem>(std::move(sd_ifs), AtmosphereHblWebContentDir)), false), target_object_id);
|
||||
out.SetValue(MakeSharedFileSystem(std::make_shared<fs::ReadOnlyFileSystem>(std::make_unique<fssystem::SubDirectoryFileSystem>(std::move(sd_ifs), AtmosphereHblWebContentDir)), false), target_object_id);
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
Result OpenProgramSpecificWebContentFileSystem(sf::Out<std::shared_ptr<IFileSystemInterface>> &out, ncm::ProgramId client_program_id, ncm::ProgramId program_id, FsFileSystemType filesystem_type, Service *fwd, const fssrv::sf::Path *path, bool with_id) {
|
||||
Result OpenProgramSpecificWebContentFileSystem(sf::Out<std::shared_ptr<ams::fssrv::sf::IFileSystem>> &out, ncm::ProgramId client_program_id, ncm::ProgramId program_id, FsFileSystemType filesystem_type, Service *fwd, const fssrv::sf::Path *path, bool with_id) {
|
||||
/* Directory must exist. */
|
||||
{
|
||||
FsDir d;
|
||||
@@ -132,13 +142,13 @@ namespace ams::mitm::fs {
|
||||
new_fs = std::make_shared<fs::ReadOnlyFileSystem>(std::move(subdir_fs));
|
||||
}
|
||||
|
||||
out.SetValue(std::make_shared<IFileSystemInterface>(std::move(new_fs), false), target_object_id);
|
||||
out.SetValue(MakeSharedFileSystem(std::move(new_fs), false), target_object_id);
|
||||
}
|
||||
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
Result OpenWebContentFileSystem(sf::Out<std::shared_ptr<IFileSystemInterface>> &out, ncm::ProgramId client_program_id, ncm::ProgramId program_id, FsFileSystemType filesystem_type, Service *fwd, const fssrv::sf::Path *path, bool with_id, bool try_program_specific) {
|
||||
Result OpenWebContentFileSystem(sf::Out<std::shared_ptr<ams::fssrv::sf::IFileSystem>> &out, ncm::ProgramId client_program_id, ncm::ProgramId program_id, FsFileSystemType filesystem_type, Service *fwd, const fssrv::sf::Path *path, bool with_id, bool try_program_specific) {
|
||||
/* Check first that we're a web applet opening web content. */
|
||||
R_UNLESS(ncm::IsWebAppletId(client_program_id), sm::mitm::ResultShouldForwardToSession());
|
||||
R_UNLESS(filesystem_type == FsFileSystemType_ContentManual, sm::mitm::ResultShouldForwardToSession());
|
||||
@@ -155,15 +165,15 @@ namespace ams::mitm::fs {
|
||||
|
||||
}
|
||||
|
||||
Result FsMitmService::OpenFileSystemWithPatch(sf::Out<std::shared_ptr<IFileSystemInterface>> out, ncm::ProgramId program_id, u32 _filesystem_type) {
|
||||
Result FsMitmService::OpenFileSystemWithPatch(sf::Out<std::shared_ptr<ams::fssrv::sf::IFileSystem>> out, ncm::ProgramId program_id, u32 _filesystem_type) {
|
||||
return OpenWebContentFileSystem(out, this->client_info.program_id, program_id, static_cast<FsFileSystemType>(_filesystem_type), this->forward_service.get(), nullptr, false, this->client_info.override_status.IsProgramSpecific());
|
||||
}
|
||||
|
||||
Result FsMitmService::OpenFileSystemWithId(sf::Out<std::shared_ptr<IFileSystemInterface>> out, const fssrv::sf::Path &path, ncm::ProgramId program_id, u32 _filesystem_type) {
|
||||
Result FsMitmService::OpenFileSystemWithId(sf::Out<std::shared_ptr<ams::fssrv::sf::IFileSystem>> out, const fssrv::sf::Path &path, ncm::ProgramId program_id, u32 _filesystem_type) {
|
||||
return OpenWebContentFileSystem(out, this->client_info.program_id, program_id, static_cast<FsFileSystemType>(_filesystem_type), this->forward_service.get(), std::addressof(path), true, this->client_info.override_status.IsProgramSpecific());
|
||||
}
|
||||
|
||||
Result FsMitmService::OpenSdCardFileSystem(sf::Out<std::shared_ptr<IFileSystemInterface>> out) {
|
||||
Result FsMitmService::OpenSdCardFileSystem(sf::Out<std::shared_ptr<ams::fssrv::sf::IFileSystem>> out) {
|
||||
/* We only care about redirecting this for NS/emummc. */
|
||||
R_UNLESS(this->client_info.program_id == ncm::SystemProgramId::Ns, sm::mitm::ResultShouldForwardToSession());
|
||||
R_UNLESS(emummc::IsActive(), sm::mitm::ResultShouldForwardToSession());
|
||||
@@ -175,11 +185,11 @@ namespace ams::mitm::fs {
|
||||
|
||||
/* Return output filesystem. */
|
||||
std::shared_ptr<fs::fsa::IFileSystem> redir_fs = std::make_shared<fssystem::DirectoryRedirectionFileSystem>(std::make_shared<RemoteFileSystem>(sd_fs), "/Nintendo", emummc::GetNintendoDirPath());
|
||||
out.SetValue(std::make_shared<IFileSystemInterface>(std::move(redir_fs), false), target_object_id);
|
||||
out.SetValue(MakeSharedFileSystem(std::move(redir_fs), false), target_object_id);
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
Result FsMitmService::OpenSaveDataFileSystem(sf::Out<std::shared_ptr<IFileSystemInterface>> out, u8 _space_id, const fs::SaveDataAttribute &attribute) {
|
||||
Result FsMitmService::OpenSaveDataFileSystem(sf::Out<std::shared_ptr<ams::fssrv::sf::IFileSystem>> out, u8 _space_id, const fs::SaveDataAttribute &attribute) {
|
||||
/* We only want to intercept saves for games, right now. */
|
||||
const bool is_game_or_hbl = this->client_info.override_status.IsHbl() || ncm::IsApplicationId(this->client_info.program_id);
|
||||
R_UNLESS(is_game_or_hbl, sm::mitm::ResultShouldForwardToSession());
|
||||
@@ -240,11 +250,11 @@ namespace ams::mitm::fs {
|
||||
}
|
||||
|
||||
/* Set output. */
|
||||
out.SetValue(std::make_shared<IFileSystemInterface>(std::move(dirsave_ifs), false), target_object_id);
|
||||
out.SetValue(MakeSharedFileSystem(std::move(dirsave_ifs), false), target_object_id);
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
Result FsMitmService::OpenBisStorage(sf::Out<std::shared_ptr<IStorageInterface>> out, u32 _bis_partition_id) {
|
||||
Result FsMitmService::OpenBisStorage(sf::Out<std::shared_ptr<ams::fssrv::sf::IStorage>> out, u32 _bis_partition_id) {
|
||||
const ::FsBisPartitionId bis_partition_id = static_cast<::FsBisPartitionId>(_bis_partition_id);
|
||||
|
||||
/* Try to open a storage for the partition. */
|
||||
@@ -265,23 +275,23 @@ namespace ams::mitm::fs {
|
||||
|
||||
/* Set output storage. */
|
||||
if (bis_partition_id == FsBisPartitionId_BootPartition1Root) {
|
||||
out.SetValue(std::make_shared<IStorageInterface>(new Boot0Storage(bis_storage, this->client_info)), target_object_id);
|
||||
out.SetValue(MakeSharedStorage(new Boot0Storage(bis_storage, this->client_info)), target_object_id);
|
||||
} else if (bis_partition_id == FsBisPartitionId_CalibrationBinary) {
|
||||
out.SetValue(std::make_shared<IStorageInterface>(new CalibrationBinaryStorage(bis_storage, this->client_info)), target_object_id);
|
||||
out.SetValue(MakeSharedStorage(new CalibrationBinaryStorage(bis_storage, this->client_info)), target_object_id);
|
||||
} else {
|
||||
if (can_write_bis || can_write_bis_for_choi_support) {
|
||||
/* We can write, so create a writable storage. */
|
||||
out.SetValue(std::make_shared<IStorageInterface>(new RemoteStorage(bis_storage)), target_object_id);
|
||||
out.SetValue(MakeSharedStorage(new RemoteStorage(bis_storage)), target_object_id);
|
||||
} else {
|
||||
/* We can only read, so create a readable storage. */
|
||||
out.SetValue(std::make_shared<IStorageInterface>(new ReadOnlyStorageAdapter(new RemoteStorage(bis_storage))), target_object_id);
|
||||
out.SetValue(MakeSharedStorage(new ReadOnlyStorageAdapter(new RemoteStorage(bis_storage))), target_object_id);
|
||||
}
|
||||
}
|
||||
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
Result FsMitmService::OpenDataStorageByCurrentProcess(sf::Out<std::shared_ptr<IStorageInterface>> out) {
|
||||
Result FsMitmService::OpenDataStorageByCurrentProcess(sf::Out<std::shared_ptr<ams::fssrv::sf::IStorage>> out) {
|
||||
/* Only mitm if we should override contents for the current process. */
|
||||
R_UNLESS(this->client_info.override_status.IsProgramSpecific(), sm::mitm::ResultShouldForwardToSession());
|
||||
|
||||
@@ -298,7 +308,7 @@ namespace ams::mitm::fs {
|
||||
|
||||
/* Try to get a storage from the cache. */
|
||||
{
|
||||
std::shared_ptr<IStorageInterface> cached_storage = GetStorageCacheEntry(this->client_info.program_id);
|
||||
std::shared_ptr<ams::fssrv::sf::IStorage> cached_storage = GetStorageCacheEntry(this->client_info.program_id);
|
||||
if (cached_storage != nullptr) {
|
||||
out.SetValue(std::move(cached_storage), target_object_id);
|
||||
return ResultSuccess();
|
||||
@@ -307,18 +317,18 @@ namespace ams::mitm::fs {
|
||||
|
||||
/* Make a new layered romfs, and cache to storage. */
|
||||
{
|
||||
std::shared_ptr<IStorageInterface> new_storage_intf = nullptr;
|
||||
std::shared_ptr<ams::fssrv::sf::IStorage> new_storage_intf = nullptr;
|
||||
|
||||
/* Create the layered storage. */
|
||||
FsFile data_file;
|
||||
if (R_SUCCEEDED(OpenAtmosphereSdFile(&data_file, this->client_info.program_id, "romfs.bin", OpenMode_Read))) {
|
||||
auto layered_storage = std::make_shared<LayeredRomfsStorage>(std::make_unique<ReadOnlyStorageAdapter>(new RemoteStorage(data_storage)), std::make_unique<ReadOnlyStorageAdapter>(new FileStorage(new RemoteFile(data_file))), this->client_info.program_id);
|
||||
layered_storage->BeginInitialize();
|
||||
new_storage_intf = std::make_shared<IStorageInterface>(layered_storage);
|
||||
new_storage_intf = MakeSharedStorage(layered_storage);
|
||||
} else {
|
||||
auto layered_storage = std::make_shared<LayeredRomfsStorage>(std::make_unique<ReadOnlyStorageAdapter>(new RemoteStorage(data_storage)), nullptr, this->client_info.program_id);
|
||||
layered_storage->BeginInitialize();
|
||||
new_storage_intf = std::make_shared<IStorageInterface>(layered_storage);
|
||||
new_storage_intf = MakeSharedStorage(layered_storage);
|
||||
}
|
||||
|
||||
SetStorageCacheEntry(this->client_info.program_id, &new_storage_intf);
|
||||
@@ -328,7 +338,7 @@ namespace ams::mitm::fs {
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
Result FsMitmService::OpenDataStorageByDataId(sf::Out<std::shared_ptr<IStorageInterface>> out, ncm::DataId _data_id, u8 storage_id) {
|
||||
Result FsMitmService::OpenDataStorageByDataId(sf::Out<std::shared_ptr<ams::fssrv::sf::IStorage>> out, ncm::DataId _data_id, u8 storage_id) {
|
||||
/* Only mitm if we should override contents for the current process. */
|
||||
R_UNLESS(this->client_info.override_status.IsProgramSpecific(), sm::mitm::ResultShouldForwardToSession());
|
||||
|
||||
@@ -348,7 +358,7 @@ namespace ams::mitm::fs {
|
||||
|
||||
/* Try to get a storage from the cache. */
|
||||
{
|
||||
std::shared_ptr<IStorageInterface> cached_storage = GetStorageCacheEntry(data_id);
|
||||
std::shared_ptr<ams::fssrv::sf::IStorage> cached_storage = GetStorageCacheEntry(data_id);
|
||||
if (cached_storage != nullptr) {
|
||||
out.SetValue(std::move(cached_storage), target_object_id);
|
||||
return ResultSuccess();
|
||||
@@ -357,18 +367,18 @@ namespace ams::mitm::fs {
|
||||
|
||||
/* Make a new layered romfs, and cache to storage. */
|
||||
{
|
||||
std::shared_ptr<IStorageInterface> new_storage_intf = nullptr;
|
||||
std::shared_ptr<ams::fssrv::sf::IStorage> new_storage_intf = nullptr;
|
||||
|
||||
/* Create the layered storage. */
|
||||
FsFile data_file;
|
||||
if (R_SUCCEEDED(OpenAtmosphereSdFile(&data_file, data_id, "romfs.bin", OpenMode_Read))) {
|
||||
auto layered_storage = std::make_shared<LayeredRomfsStorage>(std::make_unique<ReadOnlyStorageAdapter>(new RemoteStorage(data_storage)), std::make_unique<ReadOnlyStorageAdapter>(new FileStorage(new RemoteFile(data_file))), data_id);
|
||||
layered_storage->BeginInitialize();
|
||||
new_storage_intf = std::make_shared<IStorageInterface>(layered_storage);
|
||||
new_storage_intf = MakeSharedStorage(layered_storage);
|
||||
} else {
|
||||
auto layered_storage = std::make_shared<LayeredRomfsStorage>(std::make_unique<ReadOnlyStorageAdapter>(new RemoteStorage(data_storage)), nullptr, data_id);
|
||||
layered_storage->BeginInitialize();
|
||||
new_storage_intf = std::make_shared<IStorageInterface>(layered_storage);
|
||||
new_storage_intf = MakeSharedStorage(layered_storage);
|
||||
}
|
||||
|
||||
SetStorageCacheEntry(data_id, &new_storage_intf);
|
||||
|
||||
@@ -20,30 +20,26 @@
|
||||
|
||||
namespace ams::mitm::fs {
|
||||
|
||||
using IStorageInterface = ams::fssrv::impl::StorageInterfaceAdapter;
|
||||
using IFileSystemInterface = ams::fssrv::impl::FileSystemInterfaceAdapter;
|
||||
namespace {
|
||||
|
||||
/* TODO: Consider re-enabling the mitm flag logic. */
|
||||
#define AMS_FS_MITM_INTERFACE_INFO(C, H) \
|
||||
AMS_SF_METHOD_INFO(C, H, 7, Result, OpenFileSystemWithPatch, (sf::Out<std::shared_ptr<ams::fssrv::sf::IFileSystem>> out, ncm::ProgramId program_id, u32 _filesystem_type), hos::Version_2_0_0) \
|
||||
AMS_SF_METHOD_INFO(C, H, 8, Result, OpenFileSystemWithId, (sf::Out<std::shared_ptr<ams::fssrv::sf::IFileSystem>> out, const fssrv::sf::Path &path, ncm::ProgramId program_id, u32 _filesystem_type), hos::Version_2_0_0) \
|
||||
AMS_SF_METHOD_INFO(C, H, 18, Result, OpenSdCardFileSystem, (sf::Out<std::shared_ptr<ams::fssrv::sf::IFileSystem>> out)) \
|
||||
AMS_SF_METHOD_INFO(C, H, 51, Result, OpenSaveDataFileSystem, (sf::Out<std::shared_ptr<ams::fssrv::sf::IFileSystem>> out, u8 space_id, const ams::fs::SaveDataAttribute &attribute)) \
|
||||
AMS_SF_METHOD_INFO(C, H, 12, Result, OpenBisStorage, (sf::Out<std::shared_ptr<ams::fssrv::sf::IStorage>> out, u32 bis_partition_id)) \
|
||||
AMS_SF_METHOD_INFO(C, H, 200, Result, OpenDataStorageByCurrentProcess, (sf::Out<std::shared_ptr<ams::fssrv::sf::IStorage>> out)) \
|
||||
AMS_SF_METHOD_INFO(C, H, 202, Result, OpenDataStorageByDataId, (sf::Out<std::shared_ptr<ams::fssrv::sf::IStorage>> out, ncm::DataId data_id, u8 storage_id))
|
||||
|
||||
class FsMitmService : public sf::IMitmServiceObject {
|
||||
private:
|
||||
enum class CommandId {
|
||||
OpenFileSystemDeprecated = 0,
|
||||
AMS_SF_DEFINE_MITM_INTERFACE(IFsMitmInterface, AMS_FS_MITM_INTERFACE_INFO)
|
||||
|
||||
SetCurrentProcess = 1,
|
||||
OpenFileSystemWithPatch = 7,
|
||||
OpenFileSystemWithId = 8,
|
||||
}
|
||||
|
||||
OpenSdCardFileSystem = 18,
|
||||
|
||||
OpenSaveDataFileSystem = 51,
|
||||
|
||||
OpenBisStorage = 12,
|
||||
OpenDataStorageByCurrentProcess = 200,
|
||||
OpenDataStorageByDataId = 202,
|
||||
};
|
||||
class FsMitmService : public sf::MitmServiceImplBase {
|
||||
public:
|
||||
NX_CONSTEXPR bool ShouldMitmProgramId(const ncm::ProgramId program_id) {
|
||||
using MitmServiceImplBase::MitmServiceImplBase;
|
||||
public:
|
||||
static constexpr ALWAYS_INLINE bool ShouldMitmProgramId(const ncm::ProgramId program_id) {
|
||||
/* We want to mitm everything that isn't a system-module. */
|
||||
if (!ncm::IsSystemProgramId(program_id)) {
|
||||
return true;
|
||||
@@ -81,26 +77,14 @@ namespace ams::mitm::fs {
|
||||
return has_launched_qlaunch || ShouldMitmProgramId(client_info.program_id);
|
||||
}
|
||||
public:
|
||||
SF_MITM_SERVICE_OBJECT_CTOR(FsMitmService) { /* ... */ }
|
||||
protected:
|
||||
/* Overridden commands. */
|
||||
Result OpenFileSystemWithPatch(sf::Out<std::shared_ptr<IFileSystemInterface>> out, ncm::ProgramId program_id, u32 _filesystem_type);
|
||||
Result OpenFileSystemWithId(sf::Out<std::shared_ptr<IFileSystemInterface>> out, const fssrv::sf::Path &path, ncm::ProgramId program_id, u32 _filesystem_type);
|
||||
Result OpenSdCardFileSystem(sf::Out<std::shared_ptr<IFileSystemInterface>> out);
|
||||
Result OpenSaveDataFileSystem(sf::Out<std::shared_ptr<IFileSystemInterface>> out, u8 space_id, const ams::fs::SaveDataAttribute &attribute);
|
||||
Result OpenBisStorage(sf::Out<std::shared_ptr<IStorageInterface>> out, u32 bis_partition_id);
|
||||
Result OpenDataStorageByCurrentProcess(sf::Out<std::shared_ptr<IStorageInterface>> out);
|
||||
Result OpenDataStorageByDataId(sf::Out<std::shared_ptr<IStorageInterface>> out, ncm::DataId data_id, u8 storage_id);
|
||||
public:
|
||||
DEFINE_SERVICE_DISPATCH_TABLE {
|
||||
MAKE_SERVICE_COMMAND_META(OpenFileSystemWithPatch, hos::Version_2_0_0),
|
||||
MAKE_SERVICE_COMMAND_META(OpenFileSystemWithId, hos::Version_2_0_0),
|
||||
MAKE_SERVICE_COMMAND_META(OpenSdCardFileSystem),
|
||||
MAKE_SERVICE_COMMAND_META(OpenSaveDataFileSystem),
|
||||
MAKE_SERVICE_COMMAND_META(OpenBisStorage),
|
||||
MAKE_SERVICE_COMMAND_META(OpenDataStorageByCurrentProcess),
|
||||
MAKE_SERVICE_COMMAND_META(OpenDataStorageByDataId),
|
||||
};
|
||||
Result OpenFileSystemWithPatch(sf::Out<std::shared_ptr<ams::fssrv::sf::IFileSystem>> out, ncm::ProgramId program_id, u32 _filesystem_type);
|
||||
Result OpenFileSystemWithId(sf::Out<std::shared_ptr<ams::fssrv::sf::IFileSystem>> out, const fssrv::sf::Path &path, ncm::ProgramId program_id, u32 _filesystem_type);
|
||||
Result OpenSdCardFileSystem(sf::Out<std::shared_ptr<ams::fssrv::sf::IFileSystem>> out);
|
||||
Result OpenSaveDataFileSystem(sf::Out<std::shared_ptr<ams::fssrv::sf::IFileSystem>> out, u8 space_id, const ams::fs::SaveDataAttribute &attribute);
|
||||
Result OpenBisStorage(sf::Out<std::shared_ptr<ams::fssrv::sf::IStorage>> out, u32 bis_partition_id);
|
||||
Result OpenDataStorageByCurrentProcess(sf::Out<std::shared_ptr<ams::fssrv::sf::IStorage>> out);
|
||||
Result OpenDataStorageByDataId(sf::Out<std::shared_ptr<ams::fssrv::sf::IStorage>> out, ncm::DataId data_id, u8 storage_id);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -78,7 +78,7 @@ namespace ams::mitm::fs {
|
||||
|
||||
void MitmModule::ThreadFunction(void *arg) {
|
||||
/* Create fs mitm. */
|
||||
R_ABORT_UNLESS(g_server_manager.RegisterMitmServer<FsMitmService>(MitmServiceName));
|
||||
R_ABORT_UNLESS((g_server_manager.RegisterMitmServer<IFsMitmInterface, FsMitmService>(MitmServiceName)));
|
||||
|
||||
/* Process for the server. */
|
||||
ProcessForServerOnAllThreads();
|
||||
|
||||
@@ -19,11 +19,18 @@
|
||||
|
||||
namespace ams::mitm::hid {
|
||||
|
||||
class HidMitmService : public sf::IMitmServiceObject {
|
||||
private:
|
||||
enum class CommandId {
|
||||
SetSupportedNpadStyleSet = 100,
|
||||
};
|
||||
namespace {
|
||||
|
||||
#define AMS_HID_MITM_INTERFACE_INFO(C, H) \
|
||||
AMS_SF_METHOD_INFO(C, H, 100, Result, SetSupportedNpadStyleSet, (const sf::ClientAppletResourceUserId &client_aruid, u32 style_set))
|
||||
|
||||
AMS_SF_DEFINE_MITM_INTERFACE(IHidMitmInterface, AMS_HID_MITM_INTERFACE_INFO)
|
||||
|
||||
}
|
||||
|
||||
class HidMitmService : public sf::MitmServiceImplBase {
|
||||
public:
|
||||
using MitmServiceImplBase::MitmServiceImplBase;
|
||||
public:
|
||||
static bool ShouldMitm(const sm::MitmProcessInfo &client_info) {
|
||||
/* TODO: Remove in Atmosphere 0.10.2. */
|
||||
@@ -33,14 +40,9 @@ namespace ams::mitm::hid {
|
||||
return client_info.override_status.IsHbl();
|
||||
}
|
||||
public:
|
||||
SF_MITM_SERVICE_OBJECT_CTOR(HidMitmService) { /* ... */ }
|
||||
protected:
|
||||
/* Overridden commands. */
|
||||
Result SetSupportedNpadStyleSet(const sf::ClientAppletResourceUserId &client_aruid, u32 style_set);
|
||||
public:
|
||||
DEFINE_SERVICE_DISPATCH_TABLE {
|
||||
MAKE_SERVICE_COMMAND_META(SetSupportedNpadStyleSet),
|
||||
};
|
||||
};
|
||||
static_assert(IsIHidMitmInterface<HidMitmService>);
|
||||
|
||||
}
|
||||
|
||||
@@ -59,7 +59,7 @@ namespace ams::mitm::hid {
|
||||
}
|
||||
|
||||
/* Create hid mitm. */
|
||||
R_ABORT_UNLESS(g_server_manager.RegisterMitmServer<HidMitmService>(MitmServiceName));
|
||||
R_ABORT_UNLESS((g_server_manager.RegisterMitmServer<IHidMitmInterface, HidMitmService>(MitmServiceName)));
|
||||
|
||||
/* Loop forever, servicing our services. */
|
||||
g_server_manager.LoopProcess();
|
||||
|
||||
@@ -18,13 +18,20 @@
|
||||
|
||||
namespace ams::mitm::ns {
|
||||
|
||||
class NsAmMitmService : public sf::IMitmServiceObject {
|
||||
private:
|
||||
enum class CommandId {
|
||||
GetApplicationContentPath = 21,
|
||||
ResolveApplicationContentPath = 23,
|
||||
GetRunningApplicationProgramId = 92,
|
||||
};
|
||||
namespace impl {
|
||||
|
||||
#define AMS_NS_AM_MITM_INTERFACE_INFO(C, H) \
|
||||
AMS_SF_METHOD_INFO(C, H, 21, Result, GetApplicationContentPath, (const sf::OutBuffer &out_path, ncm::ProgramId application_id, u8 content_type)) \
|
||||
AMS_SF_METHOD_INFO(C, H, 23, Result, ResolveApplicationContentPath, (ncm::ProgramId application_id, u8 content_type)) \
|
||||
AMS_SF_METHOD_INFO(C, H, 92, Result, GetRunningApplicationProgramId, (sf::Out<ncm::ProgramId> out, ncm::ProgramId application_id), hos::Version_6_0_0)
|
||||
|
||||
AMS_SF_DEFINE_MITM_INTERFACE(IAmMitmInterface, AMS_NS_AM_MITM_INTERFACE_INFO)
|
||||
|
||||
}
|
||||
|
||||
class NsAmMitmService : public sf::MitmServiceImplBase {
|
||||
public:
|
||||
using MitmServiceImplBase::MitmServiceImplBase;
|
||||
public:
|
||||
static bool ShouldMitm(const sm::MitmProcessInfo &client_info) {
|
||||
/* We will mitm:
|
||||
@@ -33,18 +40,11 @@ namespace ams::mitm::ns {
|
||||
return ncm::IsWebAppletId(client_info.program_id);
|
||||
}
|
||||
public:
|
||||
SF_MITM_SERVICE_OBJECT_CTOR(NsAmMitmService) { /* ... */ }
|
||||
protected:
|
||||
/* Actual command API. */
|
||||
Result GetApplicationContentPath(const sf::OutBuffer &out_path, ncm::ProgramId application_id, u8 content_type);
|
||||
Result ResolveApplicationContentPath(ncm::ProgramId application_id, u8 content_type);
|
||||
Result GetRunningApplicationProgramId(sf::Out<ncm::ProgramId> out, ncm::ProgramId application_id);
|
||||
public:
|
||||
DEFINE_SERVICE_DISPATCH_TABLE {
|
||||
MAKE_SERVICE_COMMAND_META(GetApplicationContentPath),
|
||||
MAKE_SERVICE_COMMAND_META(ResolveApplicationContentPath),
|
||||
MAKE_SERVICE_COMMAND_META(GetRunningApplicationProgramId, hos::Version_6_0_0),
|
||||
};
|
||||
};
|
||||
static_assert(impl::IsIAmMitmInterface<NsAmMitmService>);
|
||||
|
||||
}
|
||||
|
||||
@@ -37,13 +37,13 @@ namespace ams::mitm::ns {
|
||||
return nswebGetRunningApplicationProgramId(this->srv.get(), reinterpret_cast<u64 *>(out.GetPointer()), static_cast<u64>(application_id));
|
||||
}
|
||||
|
||||
Result NsWebMitmService::GetDocumentInterface(sf::Out<std::shared_ptr<NsDocumentService>> out) {
|
||||
Result NsWebMitmService::GetDocumentInterface(sf::Out<std::shared_ptr<impl::IDocumentInterface>> out) {
|
||||
/* Open a document interface. */
|
||||
NsDocumentInterface doc;
|
||||
R_TRY(nsGetDocumentInterfaceFwd(this->forward_service.get(), &doc));
|
||||
const sf::cmif::DomainObjectId target_object_id{serviceGetObjectId(&doc.s)};
|
||||
|
||||
out.SetValue(std::make_shared<NsDocumentService>(this->client_info, std::make_unique<NsDocumentInterface>(doc)), target_object_id);
|
||||
out.SetValue(sf::MakeShared<impl::IDocumentInterface, NsDocumentService>(this->client_info, std::make_unique<NsDocumentInterface>(doc)), target_object_id);
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
|
||||
@@ -20,13 +20,23 @@
|
||||
|
||||
namespace ams::mitm::ns {
|
||||
|
||||
class NsDocumentService : public sf::IServiceObject {
|
||||
private:
|
||||
enum class CommandId {
|
||||
GetApplicationContentPath = 21,
|
||||
ResolveApplicationContentPath = 23,
|
||||
GetRunningApplicationProgramId = 92,
|
||||
};
|
||||
namespace impl {
|
||||
|
||||
#define AMS_NS_DOCUMENT_MITM_INTERFACE_INFO(C, H) \
|
||||
AMS_SF_METHOD_INFO(C, H, 21, Result, GetApplicationContentPath, (const sf::OutBuffer &out_path, ncm::ProgramId application_id, u8 content_type)) \
|
||||
AMS_SF_METHOD_INFO(C, H, 23, Result, ResolveApplicationContentPath, (ncm::ProgramId application_id, u8 content_type)) \
|
||||
AMS_SF_METHOD_INFO(C, H, 92, Result, GetRunningApplicationProgramId, (sf::Out<ncm::ProgramId> out, ncm::ProgramId application_id), hos::Version_6_0_0)
|
||||
|
||||
AMS_SF_DEFINE_INTERFACE(IDocumentInterface, AMS_NS_DOCUMENT_MITM_INTERFACE_INFO)
|
||||
|
||||
#define AMS_NS_WEB_MITM_INTERFACE_INFO(C, H) \
|
||||
AMS_SF_METHOD_INFO(C, H, 7999, Result, GetDocumentInterface, (sf::Out<std::shared_ptr<IDocumentInterface>> out))
|
||||
|
||||
AMS_SF_DEFINE_MITM_INTERFACE(IWebMitmInterface, AMS_NS_WEB_MITM_INTERFACE_INFO)
|
||||
|
||||
}
|
||||
|
||||
class NsDocumentService {
|
||||
private:
|
||||
sm::MitmProcessInfo client_info;
|
||||
std::unique_ptr<::NsDocumentInterface> srv;
|
||||
@@ -36,24 +46,17 @@ namespace ams::mitm::ns {
|
||||
virtual ~NsDocumentService() {
|
||||
nsDocumentInterfaceClose(this->srv.get());
|
||||
}
|
||||
protected:
|
||||
public:
|
||||
/* Actual command API. */
|
||||
Result GetApplicationContentPath(const sf::OutBuffer &out_path, ncm::ProgramId application_id, u8 content_type);
|
||||
Result ResolveApplicationContentPath(ncm::ProgramId application_id, u8 content_type);
|
||||
Result GetRunningApplicationProgramId(sf::Out<ncm::ProgramId> out, ncm::ProgramId application_id);
|
||||
public:
|
||||
DEFINE_SERVICE_DISPATCH_TABLE {
|
||||
MAKE_SERVICE_COMMAND_META(GetApplicationContentPath),
|
||||
MAKE_SERVICE_COMMAND_META(ResolveApplicationContentPath),
|
||||
MAKE_SERVICE_COMMAND_META(GetRunningApplicationProgramId, hos::Version_6_0_0),
|
||||
};
|
||||
};
|
||||
static_assert(impl::IsIDocumentInterface<NsDocumentService>);
|
||||
|
||||
class NsWebMitmService : public sf::IMitmServiceObject {
|
||||
private:
|
||||
enum class CommandId {
|
||||
GetDocumentInterface = 7999,
|
||||
};
|
||||
class NsWebMitmService : public sf::MitmServiceImplBase {
|
||||
public:
|
||||
using MitmServiceImplBase::MitmServiceImplBase;
|
||||
public:
|
||||
static bool ShouldMitm(const sm::MitmProcessInfo &client_info) {
|
||||
/* We will mitm:
|
||||
@@ -62,13 +65,8 @@ namespace ams::mitm::ns {
|
||||
return ncm::IsWebAppletId(client_info.program_id);
|
||||
}
|
||||
public:
|
||||
SF_MITM_SERVICE_OBJECT_CTOR(NsWebMitmService) { /* ... */ }
|
||||
protected:
|
||||
Result GetDocumentInterface(sf::Out<std::shared_ptr<NsDocumentService>> out);
|
||||
public:
|
||||
DEFINE_SERVICE_DISPATCH_TABLE {
|
||||
MAKE_SERVICE_COMMAND_META(GetDocumentInterface),
|
||||
};
|
||||
Result GetDocumentInterface(sf::Out<std::shared_ptr<impl::IDocumentInterface>> out);
|
||||
};
|
||||
static_assert(impl::IsIWebMitmInterface<NsWebMitmService>);
|
||||
|
||||
}
|
||||
|
||||
@@ -39,9 +39,9 @@ namespace ams::mitm::ns {
|
||||
|
||||
/* Create mitm servers. */
|
||||
if (hos::GetVersion() < hos::Version_3_0_0) {
|
||||
R_ABORT_UNLESS(g_server_manager.RegisterMitmServer<NsAmMitmService>(NsAmMitmServiceName));
|
||||
R_ABORT_UNLESS((g_server_manager.RegisterMitmServer<impl::IAmMitmInterface, NsAmMitmService>(NsAmMitmServiceName)));
|
||||
} else {
|
||||
R_ABORT_UNLESS(g_server_manager.RegisterMitmServer<NsWebMitmService>(NsWebMitmServiceName));
|
||||
R_ABORT_UNLESS((g_server_manager.RegisterMitmServer<impl::IWebMitmInterface, NsWebMitmService>(NsWebMitmServiceName)));
|
||||
}
|
||||
|
||||
/* Loop forever, servicing our services. */
|
||||
|
||||
@@ -18,16 +18,23 @@
|
||||
|
||||
namespace ams::mitm::settings {
|
||||
|
||||
class SetMitmService : public sf::IMitmServiceObject {
|
||||
private:
|
||||
enum class CommandId {
|
||||
GetLanguageCode = 0,
|
||||
GetRegionCode = 4,
|
||||
};
|
||||
namespace {
|
||||
|
||||
#define AMS_SETTINGS_MITM_INTERFACE_INFO(C, H) \
|
||||
AMS_SF_METHOD_INFO(C, H, 0, Result, GetLanguageCode, (sf::Out<ams::settings::LanguageCode> out)) \
|
||||
AMS_SF_METHOD_INFO(C, H, 4, Result, GetRegionCode, (sf::Out<ams::settings::RegionCode> out))
|
||||
|
||||
AMS_SF_DEFINE_MITM_INTERFACE(ISetMitmInterface, AMS_SETTINGS_MITM_INTERFACE_INFO)
|
||||
|
||||
}
|
||||
|
||||
class SetMitmService : public sf::MitmServiceImplBase {
|
||||
private:
|
||||
os::Mutex lock{false};
|
||||
cfg::OverrideLocale locale;
|
||||
bool got_locale;
|
||||
bool got_locale = false;
|
||||
public:
|
||||
using MitmServiceImplBase::MitmServiceImplBase;
|
||||
public:
|
||||
static bool ShouldMitm(const sm::MitmProcessInfo &client_info) {
|
||||
/* We will mitm:
|
||||
@@ -36,20 +43,12 @@ namespace ams::mitm::settings {
|
||||
const bool is_game = (ncm::IsApplicationId(client_info.program_id) && !client_info.override_status.IsHbl());
|
||||
return client_info.program_id == ncm::SystemProgramId::Ns || is_game;
|
||||
}
|
||||
public:
|
||||
SF_MITM_SERVICE_OBJECT_CTOR(SetMitmService) {
|
||||
this->got_locale = false;
|
||||
}
|
||||
private:
|
||||
Result EnsureLocale();
|
||||
protected:
|
||||
public:
|
||||
Result GetLanguageCode(sf::Out<ams::settings::LanguageCode> out);
|
||||
Result GetRegionCode(sf::Out<ams::settings::RegionCode> out);
|
||||
public:
|
||||
DEFINE_SERVICE_DISPATCH_TABLE {
|
||||
MAKE_SERVICE_COMMAND_META(GetLanguageCode),
|
||||
MAKE_SERVICE_COMMAND_META(GetRegionCode),
|
||||
};
|
||||
};
|
||||
static_assert(IsISetMitmInterface<SetMitmService>);
|
||||
|
||||
}
|
||||
|
||||
@@ -43,8 +43,8 @@ namespace ams::mitm::settings {
|
||||
mitm::WaitInitialized();
|
||||
|
||||
/* Create mitm servers. */
|
||||
R_ABORT_UNLESS(g_server_manager.RegisterMitmServer<SetMitmService>(SetMitmServiceName));
|
||||
R_ABORT_UNLESS(g_server_manager.RegisterMitmServer<SetSysMitmService>(SetSysMitmServiceName));
|
||||
R_ABORT_UNLESS((g_server_manager.RegisterMitmServer<ISetMitmInterface, SetMitmService>(SetMitmServiceName)));
|
||||
R_ABORT_UNLESS((g_server_manager.RegisterMitmServer<ISetSysMitmInterface, SetSysMitmService>(SetSysMitmServiceName)));
|
||||
|
||||
/* Loop forever, servicing our services. */
|
||||
g_server_manager.LoopProcess();
|
||||
|
||||
@@ -18,15 +18,21 @@
|
||||
|
||||
namespace ams::mitm::settings {
|
||||
|
||||
class SetSysMitmService : public sf::IMitmServiceObject {
|
||||
private:
|
||||
enum class CommandId {
|
||||
GetFirmwareVersion = 3,
|
||||
GetFirmwareVersion2 = 4,
|
||||
namespace {
|
||||
|
||||
GetSettingsItemValueSize = 37,
|
||||
GetSettingsItemValue = 38,
|
||||
};
|
||||
#define AMS_SETTINGS_SYSTEM_MITM_INTERFACE_INFO(C, H) \
|
||||
AMS_SF_METHOD_INFO(C, H, 3, Result, GetFirmwareVersion, (sf::Out<ams::settings::FirmwareVersion> out)) \
|
||||
AMS_SF_METHOD_INFO(C, H, 4, Result, GetFirmwareVersion2, (sf::Out<ams::settings::FirmwareVersion> out)) \
|
||||
AMS_SF_METHOD_INFO(C, H, 37, Result, GetSettingsItemValueSize, (sf::Out<u64> out_size, const ams::settings::fwdbg::SettingsName &name, const ams::settings::fwdbg::SettingsItemKey &key)) \
|
||||
AMS_SF_METHOD_INFO(C, H, 38, Result, GetSettingsItemValue, (sf::Out<u64> out_size, const sf::OutBuffer &out, const ams::settings::fwdbg::SettingsName &name, const ams::settings::fwdbg::SettingsItemKey &key))
|
||||
|
||||
AMS_SF_DEFINE_MITM_INTERFACE(ISetSysMitmInterface, AMS_SETTINGS_SYSTEM_MITM_INTERFACE_INFO)
|
||||
|
||||
}
|
||||
|
||||
class SetSysMitmService : public sf::MitmServiceImplBase {
|
||||
public:
|
||||
using MitmServiceImplBase::MitmServiceImplBase;
|
||||
public:
|
||||
static bool ShouldMitm(const sm::MitmProcessInfo &client_info) {
|
||||
/* We will mitm:
|
||||
@@ -35,19 +41,11 @@ namespace ams::mitm::settings {
|
||||
return true;
|
||||
}
|
||||
public:
|
||||
SF_MITM_SERVICE_OBJECT_CTOR(SetSysMitmService) { /* ... */ }
|
||||
protected:
|
||||
Result GetFirmwareVersion(sf::Out<ams::settings::FirmwareVersion> out);
|
||||
Result GetFirmwareVersion2(sf::Out<ams::settings::FirmwareVersion> out);
|
||||
Result GetSettingsItemValueSize(sf::Out<u64> out_size, const ams::settings::fwdbg::SettingsName &name, const ams::settings::fwdbg::SettingsItemKey &key);
|
||||
Result GetSettingsItemValue(sf::Out<u64> out_size, const sf::OutBuffer &out, const ams::settings::fwdbg::SettingsName &name, const ams::settings::fwdbg::SettingsItemKey &key);
|
||||
public:
|
||||
DEFINE_SERVICE_DISPATCH_TABLE {
|
||||
MAKE_SERVICE_COMMAND_META(GetFirmwareVersion),
|
||||
MAKE_SERVICE_COMMAND_META(GetFirmwareVersion2),
|
||||
MAKE_SERVICE_COMMAND_META(GetSettingsItemValueSize),
|
||||
MAKE_SERVICE_COMMAND_META(GetSettingsItemValue),
|
||||
};
|
||||
};
|
||||
static_assert(IsISetSysMitmInterface<SetSysMitmService>);
|
||||
|
||||
}
|
||||
|
||||
@@ -15,7 +15,6 @@
|
||||
*/
|
||||
#pragma once
|
||||
#include <stratosphere.hpp>
|
||||
#include "sysupdater_i_async_result.hpp"
|
||||
#include "sysupdater_thread_allocator.hpp"
|
||||
|
||||
namespace ams::mitm::sysupdater {
|
||||
@@ -59,18 +58,18 @@ namespace ams::mitm::sysupdater {
|
||||
}
|
||||
};
|
||||
|
||||
class AsyncBase : public IAsyncBase {
|
||||
class AsyncBase {
|
||||
public:
|
||||
virtual ~AsyncBase() { /* ... */ }
|
||||
|
||||
static Result ToAsyncResult(Result result);
|
||||
|
||||
virtual Result Cancel() override final {
|
||||
Result Cancel() {
|
||||
this->CancelImpl();
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
virtual Result GetErrorContext(sf::Out<err::ErrorContext> out) override {
|
||||
virtual Result GetErrorContext(sf::Out<err::ErrorContext> out) {
|
||||
*out = {};
|
||||
return ResultSuccess();
|
||||
}
|
||||
@@ -78,29 +77,17 @@ namespace ams::mitm::sysupdater {
|
||||
virtual void CancelImpl() = 0;
|
||||
};
|
||||
|
||||
class AsyncResultBase : public IAsyncResult {
|
||||
class AsyncResultBase : public AsyncBase {
|
||||
public:
|
||||
virtual ~AsyncResultBase() { /* ... */ }
|
||||
|
||||
static Result ToAsyncResult(Result result) { return AsyncBase::ToAsyncResult(result); }
|
||||
|
||||
virtual Result Cancel() override final {
|
||||
this->CancelImpl();
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
virtual Result Get() override final {
|
||||
Result Get() {
|
||||
return ToAsyncResult(this->GetImpl());
|
||||
}
|
||||
|
||||
virtual Result GetErrorContext(sf::Out<err::ErrorContext> out) override {
|
||||
*out = {};
|
||||
return ResultSuccess();
|
||||
}
|
||||
private:
|
||||
virtual void CancelImpl() = 0;
|
||||
virtual Result GetImpl() = 0;
|
||||
};
|
||||
static_assert(ns::impl::IsIAsyncResult<AsyncResultBase>);
|
||||
|
||||
/* NOTE: Based off of ns AsyncPrepareCardUpdateImpl. */
|
||||
/* We don't implement the RequestServer::ManagedStop details, as we don't implement stoppable request list. */
|
||||
|
||||
@@ -1,44 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2020 Atmosphère-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#pragma once
|
||||
#include <stratosphere.hpp>
|
||||
|
||||
namespace ams::mitm::sysupdater {
|
||||
|
||||
class IAsyncBase : public sf::IServiceObject {
|
||||
public:
|
||||
virtual Result Cancel() = 0;
|
||||
virtual Result GetErrorContext(sf::Out<err::ErrorContext> out) = 0;
|
||||
};
|
||||
|
||||
class IAsyncResult : public IAsyncBase {
|
||||
private:
|
||||
enum class CommandId {
|
||||
Get = 0,
|
||||
Cancel = 1,
|
||||
GetErrorContext = 2,
|
||||
};
|
||||
public:
|
||||
virtual Result Get() = 0;
|
||||
public:
|
||||
DEFINE_SERVICE_DISPATCH_TABLE {
|
||||
MAKE_SERVICE_COMMAND_META(Get),
|
||||
MAKE_SERVICE_COMMAND_META(Cancel),
|
||||
MAKE_SERVICE_COMMAND_META(GetErrorContext),
|
||||
};
|
||||
};
|
||||
|
||||
}
|
||||
@@ -50,7 +50,7 @@ namespace ams::mitm::sysupdater {
|
||||
ON_SCOPE_EXIT { nim::FinalizeForNetworkInstallManager(); };
|
||||
|
||||
/* Register ams:su. */
|
||||
R_ABORT_UNLESS((g_server_manager.RegisterServer<sysupdater::SystemUpdateService>(SystemUpdateServiceName, SystemUpdateMaxSessions, sf::ServiceObjectTraits<sysupdater::SystemUpdateService>::SharedPointerHelper::GetEmptyDeleteSharedPointer(std::addressof(g_system_update_service_object)))));
|
||||
R_ABORT_UNLESS((g_server_manager.RegisterServer<sysupdater::impl::ISystemUpdateInterface, sysupdater::SystemUpdateService>(SystemUpdateServiceName, SystemUpdateMaxSessions, sf::GetSharedPointerTo<sysupdater::impl::ISystemUpdateInterface>(g_system_update_service_object))));
|
||||
|
||||
/* Loop forever, servicing our services. */
|
||||
g_server_manager.LoopProcess();
|
||||
|
||||
@@ -411,21 +411,21 @@ namespace ams::mitm::sysupdater {
|
||||
return this->SetupUpdateImpl(transfer_memory.GetValue(), transfer_memory_size, path, exfat, firmware_variation_id);
|
||||
}
|
||||
|
||||
Result SystemUpdateService::RequestPrepareUpdate(sf::OutCopyHandle out_event_handle, sf::Out<std::shared_ptr<IAsyncResult>> out_async) {
|
||||
Result SystemUpdateService::RequestPrepareUpdate(sf::OutCopyHandle out_event_handle, sf::Out<std::shared_ptr<ns::impl::IAsyncResult>> out_async) {
|
||||
/* Ensure the update is setup but not prepared. */
|
||||
R_UNLESS(this->setup_update, ns::ResultCardUpdateNotSetup());
|
||||
R_UNLESS(!this->requested_update, ns::ResultPrepareCardUpdateAlreadyRequested());
|
||||
|
||||
/* Create the async result. */
|
||||
auto async_result = std::make_shared<AsyncPrepareSdCardUpdateImpl>(std::addressof(*this->update_task));
|
||||
auto async_result = sf::MakeShared<ns::impl::IAsyncResult, AsyncPrepareSdCardUpdateImpl>(std::addressof(*this->update_task));
|
||||
R_UNLESS(async_result != nullptr, ns::ResultOutOfMaxRunningTask());
|
||||
|
||||
/* Run the task. */
|
||||
R_TRY(async_result->Run());
|
||||
R_TRY(async_result->GetImpl().Run());
|
||||
|
||||
/* We prepared the task! */
|
||||
this->requested_update = true;
|
||||
out_event_handle.SetValue(async_result->GetEvent().GetReadableHandle());
|
||||
out_event_handle.SetValue(async_result->GetImpl().GetEvent().GetReadableHandle());
|
||||
out_async.SetValue(std::move(async_result));
|
||||
|
||||
return ResultSuccess();
|
||||
|
||||
@@ -15,7 +15,6 @@
|
||||
*/
|
||||
#pragma once
|
||||
#include <stratosphere.hpp>
|
||||
#include "sysupdater_i_async_result.hpp"
|
||||
#include "sysupdater_apply_manager.hpp"
|
||||
|
||||
namespace ams::mitm::sysupdater {
|
||||
@@ -39,18 +38,25 @@ namespace ams::mitm::sysupdater {
|
||||
s64 total_size;
|
||||
};
|
||||
|
||||
class SystemUpdateService final : public sf::IServiceObject {
|
||||
private:
|
||||
enum class CommandId {
|
||||
GetUpdateInformation = 0,
|
||||
ValidateUpdate = 1,
|
||||
SetupUpdate = 2,
|
||||
SetupUpdateWithVariation = 3,
|
||||
RequestPrepareUpdate = 4,
|
||||
GetPrepareUpdateProgress = 5,
|
||||
HasPreparedUpdate = 6,
|
||||
ApplyPreparedUpdate = 7,
|
||||
};
|
||||
namespace impl {
|
||||
|
||||
#define AMS_SYSUPDATER_SYSTEM_UPDATE_INTERFACE_INFO(C, H) \
|
||||
AMS_SF_METHOD_INFO(C, H, 0, Result, GetUpdateInformation, (sf::Out<UpdateInformation> out, const ncm::Path &path)) \
|
||||
AMS_SF_METHOD_INFO(C, H, 1, Result, ValidateUpdate, (sf::Out<Result> out_validate_result, sf::Out<UpdateValidationInfo> out_validate_info, const ncm::Path &path)) \
|
||||
AMS_SF_METHOD_INFO(C, H, 2, Result, SetupUpdate, (sf::CopyHandle transfer_memory, u64 transfer_memory_size, const ncm::Path &path, bool exfat)) \
|
||||
AMS_SF_METHOD_INFO(C, H, 3, Result, SetupUpdateWithVariation, (sf::CopyHandle transfer_memory, u64 transfer_memory_size, const ncm::Path &path, bool exfat, ncm::FirmwareVariationId firmware_variation_id)) \
|
||||
AMS_SF_METHOD_INFO(C, H, 4, Result, RequestPrepareUpdate, (sf::OutCopyHandle out_event_handle, sf::Out<std::shared_ptr<ns::impl::IAsyncResult>> out_async)) \
|
||||
AMS_SF_METHOD_INFO(C, H, 5, Result, GetPrepareUpdateProgress, (sf::Out<SystemUpdateProgress> out)) \
|
||||
AMS_SF_METHOD_INFO(C, H, 6, Result, HasPreparedUpdate, (sf::Out<bool> out)) \
|
||||
AMS_SF_METHOD_INFO(C, H, 7, Result, ApplyPreparedUpdate, ())
|
||||
|
||||
AMS_SF_DEFINE_INTERFACE(ISystemUpdateInterface, AMS_SYSUPDATER_SYSTEM_UPDATE_INTERFACE_INFO)
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
class SystemUpdateService final {
|
||||
private:
|
||||
SystemUpdateApplyManager apply_manager;
|
||||
std::optional<ncm::PackageSystemDowngradeTask> update_task;
|
||||
@@ -62,26 +68,16 @@ namespace ams::mitm::sysupdater {
|
||||
private:
|
||||
Result SetupUpdateImpl(os::ManagedHandle transfer_memory, u64 transfer_memory_size, const ncm::Path &path, bool exfat, ncm::FirmwareVariationId firmware_variation_id);
|
||||
Result InitializeUpdateTask(os::ManagedHandle &transfer_memory, u64 transfer_memory_size, const ncm::Path &path, bool exfat, ncm::FirmwareVariationId firmware_variation_id);
|
||||
private:
|
||||
public:
|
||||
Result GetUpdateInformation(sf::Out<UpdateInformation> out, const ncm::Path &path);
|
||||
Result ValidateUpdate(sf::Out<Result> out_validate_result, sf::Out<UpdateValidationInfo> out_validate_info, const ncm::Path &path);
|
||||
Result SetupUpdate(sf::CopyHandle transfer_memory, u64 transfer_memory_size, const ncm::Path &path, bool exfat);
|
||||
Result SetupUpdateWithVariation(sf::CopyHandle transfer_memory, u64 transfer_memory_size, const ncm::Path &path, bool exfat, ncm::FirmwareVariationId firmware_variation_id);
|
||||
Result RequestPrepareUpdate(sf::OutCopyHandle out_event_handle, sf::Out<std::shared_ptr<IAsyncResult>> out_async);
|
||||
Result RequestPrepareUpdate(sf::OutCopyHandle out_event_handle, sf::Out<std::shared_ptr<ns::impl::IAsyncResult>> out_async);
|
||||
Result GetPrepareUpdateProgress(sf::Out<SystemUpdateProgress> out);
|
||||
Result HasPreparedUpdate(sf::Out<bool> out);
|
||||
Result ApplyPreparedUpdate();
|
||||
public:
|
||||
DEFINE_SERVICE_DISPATCH_TABLE {
|
||||
MAKE_SERVICE_COMMAND_META(GetUpdateInformation),
|
||||
MAKE_SERVICE_COMMAND_META(ValidateUpdate),
|
||||
MAKE_SERVICE_COMMAND_META(SetupUpdate),
|
||||
MAKE_SERVICE_COMMAND_META(SetupUpdateWithVariation),
|
||||
MAKE_SERVICE_COMMAND_META(RequestPrepareUpdate),
|
||||
MAKE_SERVICE_COMMAND_META(GetPrepareUpdateProgress),
|
||||
MAKE_SERVICE_COMMAND_META(HasPreparedUpdate),
|
||||
MAKE_SERVICE_COMMAND_META(ApplyPreparedUpdate),
|
||||
};
|
||||
};
|
||||
static_assert(impl::IsISystemUpdateInterface<SystemUpdateService>);
|
||||
|
||||
}
|
||||
|
||||
@@ -18,43 +18,42 @@
|
||||
|
||||
namespace ams::dmnt::cheat {
|
||||
|
||||
class CheatService final : public sf::IServiceObject {
|
||||
private:
|
||||
enum class CommandId {
|
||||
/* Meta */
|
||||
HasCheatProcess = 65000,
|
||||
GetCheatProcessEvent = 65001,
|
||||
GetCheatProcessMetadata = 65002,
|
||||
ForceOpenCheatProcess = 65003,
|
||||
PauseCheatProcess = 65004,
|
||||
ResumeCheatProcess = 65005,
|
||||
/* TODO: In libstratosphere, eventually? */
|
||||
namespace impl {
|
||||
|
||||
/* Interact with Memory */
|
||||
GetCheatProcessMappingCount = 65100,
|
||||
GetCheatProcessMappings = 65101,
|
||||
ReadCheatProcessMemory = 65102,
|
||||
WriteCheatProcessMemory = 65103,
|
||||
QueryCheatProcessMemory = 65104,
|
||||
#define AMS_DMNT_I_CHEAT_INTERFACE_INTERFACE_INFO(C, H) \
|
||||
AMS_SF_METHOD_INFO(C, H, 65000, void, HasCheatProcess, (sf::Out<bool> out)) \
|
||||
AMS_SF_METHOD_INFO(C, H, 65001, void, GetCheatProcessEvent, (sf::OutCopyHandle out_event)) \
|
||||
AMS_SF_METHOD_INFO(C, H, 65002, Result, GetCheatProcessMetadata, (sf::Out<CheatProcessMetadata> out_metadata)) \
|
||||
AMS_SF_METHOD_INFO(C, H, 65003, Result, ForceOpenCheatProcess, ()) \
|
||||
AMS_SF_METHOD_INFO(C, H, 65004, Result, PauseCheatProcess, ()) \
|
||||
AMS_SF_METHOD_INFO(C, H, 65005, Result, ResumeCheatProcess, ()) \
|
||||
AMS_SF_METHOD_INFO(C, H, 65100, Result, GetCheatProcessMappingCount, (sf::Out<u64> out_count)) \
|
||||
AMS_SF_METHOD_INFO(C, H, 65101, Result, GetCheatProcessMappings, (const sf::OutArray<MemoryInfo> &mappings, sf::Out<u64> out_count, u64 offset)) \
|
||||
AMS_SF_METHOD_INFO(C, H, 65102, Result, ReadCheatProcessMemory, (const sf::OutBuffer &buffer, u64 address, u64 out_size)) \
|
||||
AMS_SF_METHOD_INFO(C, H, 65103, Result, WriteCheatProcessMemory, (const sf::InBuffer &buffer, u64 address, u64 in_size)) \
|
||||
AMS_SF_METHOD_INFO(C, H, 65104, Result, QueryCheatProcessMemory, (sf::Out<MemoryInfo> mapping, u64 address)) \
|
||||
AMS_SF_METHOD_INFO(C, H, 65200, Result, GetCheatCount, (sf::Out<u64> out_count)) \
|
||||
AMS_SF_METHOD_INFO(C, H, 65201, Result, GetCheats, (const sf::OutArray<CheatEntry> &cheats, sf::Out<u64> out_count, u64 offset)) \
|
||||
AMS_SF_METHOD_INFO(C, H, 65202, Result, GetCheatById, (sf::Out<CheatEntry> cheat, u32 cheat_id)) \
|
||||
AMS_SF_METHOD_INFO(C, H, 65203, Result, ToggleCheat, (u32 cheat_id)) \
|
||||
AMS_SF_METHOD_INFO(C, H, 65204, Result, AddCheat, (const CheatDefinition &cheat, sf::Out<u32> out_cheat_id, bool enabled)) \
|
||||
AMS_SF_METHOD_INFO(C, H, 65205, Result, RemoveCheat, (u32 cheat_id)) \
|
||||
AMS_SF_METHOD_INFO(C, H, 65206, Result, ReadStaticRegister, (sf::Out<u64> out, u8 which)) \
|
||||
AMS_SF_METHOD_INFO(C, H, 65207, Result, WriteStaticRegister, (u8 which, u64 value)) \
|
||||
AMS_SF_METHOD_INFO(C, H, 65208, Result, ResetStaticRegisters, ()) \
|
||||
AMS_SF_METHOD_INFO(C, H, 65300, Result, GetFrozenAddressCount, (sf::Out<u64> out_count)) \
|
||||
AMS_SF_METHOD_INFO(C, H, 65301, Result, GetFrozenAddresses, (const sf::OutArray<FrozenAddressEntry> &addresses, sf::Out<u64> out_count, u64 offset)) \
|
||||
AMS_SF_METHOD_INFO(C, H, 65302, Result, GetFrozenAddress, (sf::Out<FrozenAddressEntry> entry, u64 address)) \
|
||||
AMS_SF_METHOD_INFO(C, H, 65303, Result, EnableFrozenAddress, (sf::Out<u64> out_value, u64 address, u64 width)) \
|
||||
AMS_SF_METHOD_INFO(C, H, 65304, Result, DisableFrozenAddress, (u64 address))
|
||||
|
||||
/* Interact with Cheats */
|
||||
GetCheatCount = 65200,
|
||||
GetCheats = 65201,
|
||||
GetCheatById = 65202,
|
||||
ToggleCheat = 65203,
|
||||
AddCheat = 65204,
|
||||
RemoveCheat = 65205,
|
||||
ReadStaticRegister = 65206,
|
||||
WriteStaticRegister = 65207,
|
||||
ResetStaticRegisters = 65208,
|
||||
AMS_SF_DEFINE_INTERFACE(ICheatInterface, AMS_DMNT_I_CHEAT_INTERFACE_INTERFACE_INFO)
|
||||
|
||||
/* Interact with Frozen Addresses */
|
||||
GetFrozenAddressCount = 65300,
|
||||
GetFrozenAddresses = 65301,
|
||||
GetFrozenAddress = 65302,
|
||||
EnableFrozenAddress = 65303,
|
||||
DisableFrozenAddress = 65304,
|
||||
};
|
||||
private:
|
||||
}
|
||||
|
||||
class CheatService final {
|
||||
public:
|
||||
void HasCheatProcess(sf::Out<bool> out);
|
||||
void GetCheatProcessEvent(sf::OutCopyHandle out_event);
|
||||
Result GetCheatProcessMetadata(sf::Out<CheatProcessMetadata> out_metadata);
|
||||
@@ -83,38 +82,7 @@ namespace ams::dmnt::cheat {
|
||||
Result GetFrozenAddress(sf::Out<FrozenAddressEntry> entry, u64 address);
|
||||
Result EnableFrozenAddress(sf::Out<u64> out_value, u64 address, u64 width);
|
||||
Result DisableFrozenAddress(u64 address);
|
||||
|
||||
public:
|
||||
DEFINE_SERVICE_DISPATCH_TABLE {
|
||||
MAKE_SERVICE_COMMAND_META(HasCheatProcess),
|
||||
MAKE_SERVICE_COMMAND_META(GetCheatProcessEvent),
|
||||
MAKE_SERVICE_COMMAND_META(GetCheatProcessMetadata),
|
||||
MAKE_SERVICE_COMMAND_META(ForceOpenCheatProcess),
|
||||
MAKE_SERVICE_COMMAND_META(PauseCheatProcess),
|
||||
MAKE_SERVICE_COMMAND_META(ResumeCheatProcess),
|
||||
|
||||
MAKE_SERVICE_COMMAND_META(GetCheatProcessMappingCount),
|
||||
MAKE_SERVICE_COMMAND_META(GetCheatProcessMappings),
|
||||
MAKE_SERVICE_COMMAND_META(ReadCheatProcessMemory),
|
||||
MAKE_SERVICE_COMMAND_META(WriteCheatProcessMemory),
|
||||
MAKE_SERVICE_COMMAND_META(QueryCheatProcessMemory),
|
||||
|
||||
MAKE_SERVICE_COMMAND_META(GetCheatCount),
|
||||
MAKE_SERVICE_COMMAND_META(GetCheats),
|
||||
MAKE_SERVICE_COMMAND_META(GetCheatById),
|
||||
MAKE_SERVICE_COMMAND_META(ToggleCheat),
|
||||
MAKE_SERVICE_COMMAND_META(AddCheat),
|
||||
MAKE_SERVICE_COMMAND_META(RemoveCheat),
|
||||
MAKE_SERVICE_COMMAND_META(ReadStaticRegister),
|
||||
MAKE_SERVICE_COMMAND_META(WriteStaticRegister),
|
||||
MAKE_SERVICE_COMMAND_META(ResetStaticRegisters),
|
||||
|
||||
MAKE_SERVICE_COMMAND_META(GetFrozenAddressCount),
|
||||
MAKE_SERVICE_COMMAND_META(GetFrozenAddresses),
|
||||
MAKE_SERVICE_COMMAND_META(GetFrozenAddress),
|
||||
MAKE_SERVICE_COMMAND_META(EnableFrozenAddress),
|
||||
MAKE_SERVICE_COMMAND_META(DisableFrozenAddress),
|
||||
};
|
||||
};
|
||||
static_assert(impl::IsICheatInterface<CheatService>);
|
||||
|
||||
}
|
||||
|
||||
@@ -140,7 +140,7 @@ int main(int argc, char **argv)
|
||||
/* Create services. */
|
||||
/* TODO: Implement rest of dmnt:- in ams.tma development branch. */
|
||||
/* R_ABORT_UNLESS((g_server_manager.RegisterServer<dmnt::cheat::CheatService>(DebugMonitorServiceName, DebugMonitorMaxSessions))); */
|
||||
R_ABORT_UNLESS((g_server_manager.RegisterServer<dmnt::cheat::CheatService>(CheatServiceName, CheatMaxSessions)));
|
||||
R_ABORT_UNLESS((g_server_manager.RegisterServer<dmnt::cheat::impl::ICheatInterface, dmnt::cheat::CheatService>(CheatServiceName, CheatMaxSessions)));
|
||||
|
||||
/* Loop forever, servicing our services. */
|
||||
/* Nintendo loops four threads processing on the manager -- we'll loop an extra fifth for our cheat service. */
|
||||
|
||||
@@ -57,7 +57,8 @@ namespace ams::dmnt {
|
||||
|
||||
static_assert(util::is_pod<TargetIOFileHandle>::value && sizeof(TargetIOFileHandle) == sizeof(u64), "TargetIOFileHandle");
|
||||
|
||||
class DebugMonitorService final : public sf::IServiceObject {
|
||||
/* TODO: Convert to new sf format in the future. */
|
||||
class DebugMonitorService final {
|
||||
private:
|
||||
enum class CommandId {
|
||||
BreakDebugProcess = 0,
|
||||
@@ -131,61 +132,6 @@ namespace ams::dmnt {
|
||||
Result TargetIO_FileSetSize(const sf::InBuffer &input, s64 size);
|
||||
Result TargetIO_FileDelete(const sf::InBuffer &path);
|
||||
Result TargetIO_FileMove(const sf::InBuffer &src_path, const sf::InBuffer &dst_path);
|
||||
public:
|
||||
DEFINE_SERVICE_DISPATCH_TABLE {
|
||||
MAKE_SERVICE_COMMAND_META(BreakDebugProcess),
|
||||
MAKE_SERVICE_COMMAND_META(TerminateDebugProcess),
|
||||
MAKE_SERVICE_COMMAND_META(CloseHandle),
|
||||
// MAKE_SERVICE_COMMAND_META(LoadImage),
|
||||
MAKE_SERVICE_COMMAND_META(GetProcessId),
|
||||
MAKE_SERVICE_COMMAND_META(GetProcessHandle),
|
||||
MAKE_SERVICE_COMMAND_META(WaitSynchronization),
|
||||
//MAKE_SERVICE_COMMAND_META(GetDebugEvent),
|
||||
// MAKE_SERVICE_COMMAND_META(GetProcessModuleInfo),
|
||||
// MAKE_SERVICE_COMMAND_META(GetProcessList),
|
||||
// MAKE_SERVICE_COMMAND_META(GetThreadList),
|
||||
// MAKE_SERVICE_COMMAND_META(GetDebugThreadContext),
|
||||
// MAKE_SERVICE_COMMAND_META(ContinueDebugEvent),
|
||||
// MAKE_SERVICE_COMMAND_META(ReadDebugProcessMemory),
|
||||
// MAKE_SERVICE_COMMAND_META(WriteDebugProcessMemory),
|
||||
// MAKE_SERVICE_COMMAND_META(SetDebugThreadContext),
|
||||
// MAKE_SERVICE_COMMAND_META(GetDebugThreadParam),
|
||||
// MAKE_SERVICE_COMMAND_META(InitializeThreadInfo),
|
||||
// MAKE_SERVICE_COMMAND_META(SetHardwareBreakPoint),
|
||||
// MAKE_SERVICE_COMMAND_META(QueryDebugProcessMemory),
|
||||
// MAKE_SERVICE_COMMAND_META(GetProcessMemoryDetails),
|
||||
// MAKE_SERVICE_COMMAND_META(AttachByProgramId),
|
||||
// MAKE_SERVICE_COMMAND_META(AttachOnLaunch),
|
||||
// MAKE_SERVICE_COMMAND_META(GetDebugMonitorProcessId),
|
||||
// MAKE_SERVICE_COMMAND_META(GetJitDebugProcessList),
|
||||
// MAKE_SERVICE_COMMAND_META(CreateCoreDump),
|
||||
// MAKE_SERVICE_COMMAND_META(GetAllDebugThreadInfo),
|
||||
MAKE_SERVICE_COMMAND_META(TargetIO_FileOpen),
|
||||
MAKE_SERVICE_COMMAND_META(TargetIO_FileClose),
|
||||
MAKE_SERVICE_COMMAND_META(TargetIO_FileRead),
|
||||
MAKE_SERVICE_COMMAND_META(TargetIO_FileWrite),
|
||||
MAKE_SERVICE_COMMAND_META(TargetIO_FileSetAttributes),
|
||||
MAKE_SERVICE_COMMAND_META(TargetIO_FileGetInformation),
|
||||
MAKE_SERVICE_COMMAND_META(TargetIO_FileSetTime),
|
||||
MAKE_SERVICE_COMMAND_META(TargetIO_FileSetSize),
|
||||
MAKE_SERVICE_COMMAND_META(TargetIO_FileDelete),
|
||||
MAKE_SERVICE_COMMAND_META(TargetIO_FileMove),
|
||||
// MAKE_SERVICE_COMMAND_META(TargetIO_DirectoryCreate),
|
||||
// MAKE_SERVICE_COMMAND_META(TargetIO_DirectoryDelete),
|
||||
// MAKE_SERVICE_COMMAND_META(TargetIO_DirectoryRename),
|
||||
// MAKE_SERVICE_COMMAND_META(TargetIO_DirectoryGetCount),
|
||||
// MAKE_SERVICE_COMMAND_META(TargetIO_DirectoryOpen),
|
||||
// MAKE_SERVICE_COMMAND_META(TargetIO_DirectoryGetNext),
|
||||
// MAKE_SERVICE_COMMAND_META(TargetIO_DirectoryClose),
|
||||
// MAKE_SERVICE_COMMAND_META(TargetIO_GetFreeSpace),
|
||||
// MAKE_SERVICE_COMMAND_META(TargetIO_GetVolumeInformation),
|
||||
// MAKE_SERVICE_COMMAND_META(InitiateCoreDump),
|
||||
// MAKE_SERVICE_COMMAND_META(ContinueCoreDump),
|
||||
// MAKE_SERVICE_COMMAND_META(AddTTYToCoreDump),
|
||||
// MAKE_SERVICE_COMMAND_META(AddImageToCoreDump),
|
||||
// MAKE_SERVICE_COMMAND_META(CloseCoreDump),
|
||||
// MAKE_SERVICE_COMMAND_META(CancelAttach),
|
||||
};
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -156,11 +156,10 @@ int main(int argc, char **argv)
|
||||
fatal::srv::CheckRepairStatus();
|
||||
|
||||
/* Create services. */
|
||||
R_ABORT_UNLESS((g_server_manager.RegisterServer<fatal::srv::PrivateService>(PrivateServiceName, PrivateMaxSessions)));
|
||||
R_ABORT_UNLESS((g_server_manager.RegisterServer<fatal::srv::UserService>(UserServiceName, UserMaxSessions)));
|
||||
R_ABORT_UNLESS((g_server_manager.RegisterServer<fatal::impl::IPrivateService, fatal::srv::PrivateService>(PrivateServiceName, PrivateMaxSessions)));
|
||||
R_ABORT_UNLESS((g_server_manager.RegisterServer<fatal::impl::IService, fatal::srv::Service>(UserServiceName, UserMaxSessions)));
|
||||
|
||||
/* Add dirty event holder. */
|
||||
/* TODO: s_server_manager.AddWaitable(ams::fatal::srv::GetFatalDirtyEvent()); */
|
||||
auto *dirty_event_holder = ams::fatal::srv::GetFatalDirtyWaitableHolder();
|
||||
g_server_manager.AddUserWaitableHolder(dirty_event_holder);
|
||||
|
||||
|
||||
@@ -133,15 +133,15 @@ namespace ams::fatal::srv {
|
||||
return g_context.ThrowFatalWithPolicy(result, os::GetCurrentProcessId(), FatalPolicy_ErrorScreen);
|
||||
}
|
||||
|
||||
Result UserService::ThrowFatal(Result result, const sf::ClientProcessId &client_pid) {
|
||||
Result Service::ThrowFatal(Result result, const sf::ClientProcessId &client_pid) {
|
||||
return g_context.ThrowFatal(result, client_pid.GetValue());
|
||||
}
|
||||
|
||||
Result UserService::ThrowFatalWithPolicy(Result result, const sf::ClientProcessId &client_pid, FatalPolicy policy) {
|
||||
Result Service::ThrowFatalWithPolicy(Result result, const sf::ClientProcessId &client_pid, FatalPolicy policy) {
|
||||
return g_context.ThrowFatalWithPolicy(result, client_pid.GetValue(), policy);
|
||||
}
|
||||
|
||||
Result UserService::ThrowFatalWithCpuContext(Result result, const sf::ClientProcessId &client_pid, FatalPolicy policy, const CpuContext &cpu_ctx) {
|
||||
Result Service::ThrowFatalWithCpuContext(Result result, const sf::ClientProcessId &client_pid, FatalPolicy policy, const CpuContext &cpu_ctx) {
|
||||
return g_context.ThrowFatalWithCpuContext(result, client_pid.GetValue(), policy, cpu_ctx);
|
||||
}
|
||||
|
||||
|
||||
@@ -18,39 +18,19 @@
|
||||
|
||||
namespace ams::fatal::srv {
|
||||
|
||||
class UserService final : public sf::IServiceObject {
|
||||
private:
|
||||
enum class CommandId {
|
||||
ThrowFatal = 0,
|
||||
ThrowFatalWithPolicy = 1,
|
||||
ThrowFatalWithCpuContext = 2,
|
||||
};
|
||||
private:
|
||||
/* Actual commands. */
|
||||
class Service final {
|
||||
public:
|
||||
Result ThrowFatal(Result error, const sf::ClientProcessId &client_pid);
|
||||
Result ThrowFatalWithPolicy(Result error, const sf::ClientProcessId &client_pid, FatalPolicy policy);
|
||||
Result ThrowFatalWithCpuContext(Result error, const sf::ClientProcessId &client_pid, FatalPolicy policy, const CpuContext &cpu_ctx);
|
||||
public:
|
||||
DEFINE_SERVICE_DISPATCH_TABLE {
|
||||
MAKE_SERVICE_COMMAND_META(ThrowFatal),
|
||||
MAKE_SERVICE_COMMAND_META(ThrowFatalWithPolicy),
|
||||
MAKE_SERVICE_COMMAND_META(ThrowFatalWithCpuContext),
|
||||
};
|
||||
};
|
||||
static_assert(fatal::impl::IsIService<Service>);
|
||||
|
||||
class PrivateService final : public sf::IServiceObject {
|
||||
private:
|
||||
enum class CommandId {
|
||||
GetFatalEvent = 0,
|
||||
};
|
||||
private:
|
||||
/* Actual commands. */
|
||||
Result GetFatalEvent(sf::OutCopyHandle out_h);
|
||||
class PrivateService final {
|
||||
public:
|
||||
DEFINE_SERVICE_DISPATCH_TABLE {
|
||||
MAKE_SERVICE_COMMAND_META(GetFatalEvent),
|
||||
};
|
||||
Result GetFatalEvent(sf::OutCopyHandle out_h);
|
||||
};
|
||||
static_assert(fatal::impl::IsIPrivateService<PrivateService>);
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -18,101 +18,27 @@
|
||||
|
||||
namespace ams::ldr {
|
||||
|
||||
class LoaderService : public sf::IServiceObject {
|
||||
protected:
|
||||
class LoaderService final {
|
||||
public:
|
||||
/* Official commands. */
|
||||
virtual Result CreateProcess(sf::OutMoveHandle proc_h, PinId id, u32 flags, sf::CopyHandle reslimit_h);
|
||||
virtual Result GetProgramInfo(sf::Out<ProgramInfo> out_program_info, const ncm::ProgramLocation &loc);
|
||||
virtual Result PinProgram(sf::Out<PinId> out_id, const ncm::ProgramLocation &loc);
|
||||
virtual Result UnpinProgram(PinId id);
|
||||
virtual Result SetProgramArguments(ncm::ProgramId program_id, const sf::InPointerBuffer &args, u32 args_size);
|
||||
virtual Result FlushArguments();
|
||||
virtual Result GetProcessModuleInfo(sf::Out<u32> count, const sf::OutPointerArray<ModuleInfo> &out, os::ProcessId process_id);
|
||||
virtual Result SetEnabledProgramVerification(bool enabled);
|
||||
Result CreateProcess(sf::OutMoveHandle proc_h, PinId id, u32 flags, sf::CopyHandle reslimit_h);
|
||||
Result GetProgramInfo(sf::Out<ProgramInfo> out_program_info, const ncm::ProgramLocation &loc);
|
||||
Result PinProgram(sf::Out<PinId> out_id, const ncm::ProgramLocation &loc);
|
||||
Result UnpinProgram(PinId id);
|
||||
Result SetProgramArguments(ncm::ProgramId program_id, const sf::InPointerBuffer &args, u32 args_size);
|
||||
Result FlushArguments();
|
||||
Result GetProcessModuleInfo(sf::Out<u32> count, const sf::OutPointerArray<ModuleInfo> &out, os::ProcessId process_id);
|
||||
Result SetEnabledProgramVerification(bool enabled);
|
||||
|
||||
/* Atmosphere commands. */
|
||||
virtual Result AtmosphereRegisterExternalCode(sf::OutMoveHandle out, ncm::ProgramId program_id);
|
||||
virtual void AtmosphereUnregisterExternalCode(ncm::ProgramId program_id);
|
||||
virtual void AtmosphereHasLaunchedProgram(sf::Out<bool> out, ncm::ProgramId program_id);
|
||||
virtual Result AtmosphereGetProgramInfo(sf::Out<ProgramInfo> out_program_info, sf::Out<cfg::OverrideStatus> out_status, const ncm::ProgramLocation &loc);
|
||||
virtual Result AtmospherePinProgram(sf::Out<PinId> out_id, const ncm::ProgramLocation &loc, const cfg::OverrideStatus &override_status);
|
||||
Result AtmosphereRegisterExternalCode(sf::OutMoveHandle out, ncm::ProgramId program_id);
|
||||
void AtmosphereUnregisterExternalCode(ncm::ProgramId program_id);
|
||||
void AtmosphereHasLaunchedProgram(sf::Out<bool> out, ncm::ProgramId program_id);
|
||||
Result AtmosphereGetProgramInfo(sf::Out<ProgramInfo> out_program_info, sf::Out<cfg::OverrideStatus> out_status, const ncm::ProgramLocation &loc);
|
||||
Result AtmospherePinProgram(sf::Out<PinId> out_id, const ncm::ProgramLocation &loc, const cfg::OverrideStatus &override_status);
|
||||
};
|
||||
|
||||
namespace pm {
|
||||
|
||||
class ProcessManagerInterface final : public LoaderService {
|
||||
protected:
|
||||
enum class CommandId {
|
||||
CreateProcess = 0,
|
||||
GetProgramInfo = 1,
|
||||
PinProgram = 2,
|
||||
UnpinProgram = 3,
|
||||
SetEnabledProgramVerification = 4,
|
||||
|
||||
AtmosphereHasLaunchedProgram = 65000,
|
||||
AtmosphereGetProgramInfo = 65001,
|
||||
AtmospherePinProgram = 65002,
|
||||
};
|
||||
public:
|
||||
DEFINE_SERVICE_DISPATCH_TABLE {
|
||||
MAKE_SERVICE_COMMAND_META(CreateProcess),
|
||||
MAKE_SERVICE_COMMAND_META(GetProgramInfo),
|
||||
MAKE_SERVICE_COMMAND_META(PinProgram),
|
||||
MAKE_SERVICE_COMMAND_META(UnpinProgram),
|
||||
MAKE_SERVICE_COMMAND_META(SetEnabledProgramVerification, hos::Version_10_0_0),
|
||||
|
||||
MAKE_SERVICE_COMMAND_META(AtmosphereHasLaunchedProgram),
|
||||
MAKE_SERVICE_COMMAND_META(AtmosphereGetProgramInfo),
|
||||
MAKE_SERVICE_COMMAND_META(AtmospherePinProgram),
|
||||
};
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
namespace dmnt {
|
||||
|
||||
class DebugMonitorInterface final : public LoaderService {
|
||||
protected:
|
||||
enum class CommandId {
|
||||
SetProgramArguments = 0,
|
||||
FlushArguments = 1,
|
||||
GetProcessModuleInfo = 2,
|
||||
|
||||
AtmosphereHasLaunchedProgram = 65000,
|
||||
};
|
||||
public:
|
||||
DEFINE_SERVICE_DISPATCH_TABLE {
|
||||
MAKE_SERVICE_COMMAND_META(SetProgramArguments),
|
||||
MAKE_SERVICE_COMMAND_META(FlushArguments),
|
||||
MAKE_SERVICE_COMMAND_META(GetProcessModuleInfo),
|
||||
|
||||
MAKE_SERVICE_COMMAND_META(AtmosphereHasLaunchedProgram),
|
||||
};
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
namespace shell {
|
||||
|
||||
class ShellInterface final : public LoaderService {
|
||||
protected:
|
||||
enum class CommandId {
|
||||
SetProgramArguments = 0,
|
||||
FlushArguments = 1,
|
||||
|
||||
AtmosphereRegisterExternalCode = 65000,
|
||||
AtmosphereUnregisterExternalCode = 65001,
|
||||
};
|
||||
public:
|
||||
DEFINE_SERVICE_DISPATCH_TABLE {
|
||||
MAKE_SERVICE_COMMAND_META(SetProgramArguments),
|
||||
MAKE_SERVICE_COMMAND_META(FlushArguments),
|
||||
|
||||
MAKE_SERVICE_COMMAND_META(AtmosphereRegisterExternalCode),
|
||||
MAKE_SERVICE_COMMAND_META(AtmosphereUnregisterExternalCode),
|
||||
};
|
||||
};
|
||||
|
||||
}
|
||||
static_assert(ams::ldr::impl::IsIProcessManagerInterface<LoaderService>);
|
||||
static_assert(ams::ldr::impl::IsIDebugMonitorInterface<LoaderService>);
|
||||
static_assert(ams::ldr::impl::IsIShellInterface<LoaderService>);
|
||||
|
||||
}
|
||||
|
||||
@@ -129,9 +129,9 @@ int main(int argc, char **argv)
|
||||
ldr::SetDevelopmentForAcidSignatureCheck(spl::IsDevelopment());
|
||||
|
||||
/* Add services to manager. */
|
||||
R_ABORT_UNLESS((g_server_manager.RegisterServer<ldr::pm::ProcessManagerInterface>(ProcessManagerServiceName, ProcessManagerMaxSessions)));
|
||||
R_ABORT_UNLESS((g_server_manager.RegisterServer<ldr::shell::ShellInterface>(ShellServiceName, ShellMaxSessions)));
|
||||
R_ABORT_UNLESS((g_server_manager.RegisterServer<ldr::dmnt::DebugMonitorInterface>(DebugMonitorServiceName, DebugMonitorMaxSessions)));
|
||||
R_ABORT_UNLESS((g_server_manager.RegisterServer<ldr::impl::IProcessManagerInterface, ldr::LoaderService>(ProcessManagerServiceName, ProcessManagerMaxSessions)));
|
||||
R_ABORT_UNLESS((g_server_manager.RegisterServer<ldr::impl::IShellInterface, ldr::LoaderService>(ShellServiceName, ShellMaxSessions)));
|
||||
R_ABORT_UNLESS((g_server_manager.RegisterServer<ldr::impl::IDebugMonitorInterface, ldr::LoaderService>(DebugMonitorServiceName, DebugMonitorMaxSessions)));
|
||||
|
||||
/* Loop forever, servicing our services. */
|
||||
g_server_manager.LoopProcess();
|
||||
|
||||
@@ -153,24 +153,21 @@ namespace {
|
||||
|
||||
class ContentManagerServerManager : public sf::hipc::ServerManager<ContentManagerNumServers, ContentManagerServerOptions, ContentManagerMaxSessions> {
|
||||
private:
|
||||
using ServiceType = ncm::ContentManagerImpl;
|
||||
using Interface = ncm::IContentManager;
|
||||
using ServiceImpl = ncm::ContentManagerImpl;
|
||||
private:
|
||||
os::ThreadType thread;
|
||||
std::shared_ptr<ServiceType> ncm_manager;
|
||||
std::shared_ptr<Interface> ncm_manager;
|
||||
private:
|
||||
static void ThreadFunction(void *_this) {
|
||||
reinterpret_cast<ContentManagerServerManager *>(_this)->LoopProcess();
|
||||
}
|
||||
public:
|
||||
ContentManagerServerManager(ServiceType *m)
|
||||
: ncm_manager()
|
||||
{
|
||||
/* ... */
|
||||
}
|
||||
ContentManagerServerManager() : ncm_manager() { /* ... */ }
|
||||
|
||||
ams::Result Initialize(std::shared_ptr<ServiceType> manager_obj) {
|
||||
ams::Result Initialize(std::shared_ptr<Interface> manager_obj) {
|
||||
this->ncm_manager = manager_obj;
|
||||
return this->RegisterServer<ServiceType>(ContentManagerServiceName, ContentManagerManagerSessions, this->ncm_manager);
|
||||
return this->RegisterServer<Interface, ServiceImpl>(ContentManagerServiceName, ContentManagerManagerSessions, this->ncm_manager);
|
||||
}
|
||||
|
||||
ams::Result StartThreads() {
|
||||
@@ -200,23 +197,20 @@ namespace {
|
||||
|
||||
class LocationResolverServerManager : public sf::hipc::ServerManager<LocationResolverNumServers, LocationResolverServerOptions, LocationResolverMaxSessions> {
|
||||
private:
|
||||
using ServiceType = lr::LocationResolverManagerImpl;
|
||||
using Interface = lr::ILocationResolverManager;
|
||||
using ServiceImpl = lr::LocationResolverManagerImpl;
|
||||
private:
|
||||
os::ThreadType thread;
|
||||
std::shared_ptr<ServiceType> lr_manager;
|
||||
std::shared_ptr<Interface> lr_manager;
|
||||
private:
|
||||
static void ThreadFunction(void *_this) {
|
||||
reinterpret_cast<LocationResolverServerManager *>(_this)->LoopProcess();
|
||||
}
|
||||
public:
|
||||
LocationResolverServerManager(ServiceType *m)
|
||||
: lr_manager(sf::ServiceObjectTraits<ServiceType>::SharedPointerHelper::GetEmptyDeleteSharedPointer(m))
|
||||
{
|
||||
/* ... */
|
||||
}
|
||||
LocationResolverServerManager(ServiceImpl &m) : lr_manager(sf::GetSharedPointerTo<Interface>(m)) { /* ... */ }
|
||||
|
||||
ams::Result Initialize() {
|
||||
return this->RegisterServer<ServiceType>(LocationResolverServiceName, LocationResolverManagerSessions, this->lr_manager);
|
||||
return this->RegisterServer<Interface, ServiceImpl>(LocationResolverServiceName, LocationResolverManagerSessions, this->lr_manager);
|
||||
}
|
||||
|
||||
ams::Result StartThreads() {
|
||||
@@ -232,14 +226,10 @@ namespace {
|
||||
};
|
||||
|
||||
ncm::ContentManagerImpl g_ncm_manager_service_object;
|
||||
ContentManagerServerManager g_ncm_server_manager(std::addressof(g_ncm_manager_service_object));
|
||||
ContentManagerServerManager g_ncm_server_manager;
|
||||
|
||||
lr::LocationResolverManagerImpl g_lr_manager_service_object;
|
||||
LocationResolverServerManager g_lr_server_manager(std::addressof(g_lr_manager_service_object));
|
||||
|
||||
ALWAYS_INLINE std::shared_ptr<ncm::ContentManagerImpl> GetSharedPointerToContentManager() {
|
||||
return sf::ServiceObjectTraits<ncm::ContentManagerImpl>::SharedPointerHelper::GetEmptyDeleteSharedPointer(std::addressof(g_ncm_manager_service_object));
|
||||
}
|
||||
LocationResolverServerManager g_lr_server_manager(g_lr_manager_service_object);
|
||||
|
||||
/* Compile-time configuration. */
|
||||
#ifdef NCM_BUILD_FOR_INTITIALIZE
|
||||
@@ -270,8 +260,8 @@ int main(int argc, char **argv)
|
||||
AMS_ASSERT(os::GetThreadPriority(os::GetCurrentThread()) == AMS_GET_SYSTEM_THREAD_PRIORITY(ncm, MainWaitThreads));
|
||||
|
||||
/* Create and initialize the content manager. */
|
||||
auto content_manager = GetSharedPointerToContentManager();
|
||||
R_ABORT_UNLESS(content_manager->Initialize(ManagerConfig));
|
||||
auto content_manager = sf::GetSharedPointerTo<ncm::IContentManager>(g_ncm_manager_service_object);
|
||||
R_ABORT_UNLESS(content_manager->GetImpl().Initialize(ManagerConfig));
|
||||
|
||||
/* Initialize ncm's server and start threads. */
|
||||
R_ABORT_UNLESS(g_ncm_server_manager.Initialize(content_manager));
|
||||
|
||||
@@ -66,12 +66,8 @@ namespace ams::pgl {
|
||||
|
||||
constinit pgl::srv::ShellInterface g_shell_interface;
|
||||
|
||||
ALWAYS_INLINE std::shared_ptr<pgl::srv::ShellInterface> GetSharedPointerToShellInterface() {
|
||||
return ams::sf::ServiceObjectTraits<pgl::srv::ShellInterface>::SharedPointerHelper::GetEmptyDeleteSharedPointer(std::addressof(g_shell_interface));
|
||||
}
|
||||
|
||||
void RegisterServiceSession() {
|
||||
R_ABORT_UNLESS(g_server_manager.RegisterServer<pgl::srv::ShellInterface>(ShellServiceName, ShellMaxSessions, GetSharedPointerToShellInterface()));
|
||||
R_ABORT_UNLESS((g_server_manager.RegisterServer<pgl::sf::IShellInterface, pgl::srv::ShellInterface>(ShellServiceName, ShellMaxSessions, ams::sf::GetSharedPointerTo<pgl::sf::IShellInterface>(g_shell_interface))));
|
||||
}
|
||||
|
||||
void LoopProcess() {
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
#include <stratosphere.hpp>
|
||||
#include "pm_boot_mode_service.hpp"
|
||||
|
||||
namespace ams::pm::bm {
|
||||
namespace ams::pm {
|
||||
|
||||
namespace {
|
||||
|
||||
@@ -26,12 +26,16 @@ namespace ams::pm::bm {
|
||||
}
|
||||
|
||||
/* Override of weakly linked boot_mode_api functions. */
|
||||
BootMode GetBootMode() {
|
||||
return g_boot_mode;
|
||||
}
|
||||
namespace bm {
|
||||
|
||||
BootMode GetBootMode() {
|
||||
return g_boot_mode;
|
||||
}
|
||||
|
||||
void SetMaintenanceBoot() {
|
||||
g_boot_mode = BootMode::Maintenance;
|
||||
}
|
||||
|
||||
void SetMaintenanceBoot() {
|
||||
g_boot_mode = BootMode::Maintenance;
|
||||
}
|
||||
|
||||
/* Service command implementations. */
|
||||
|
||||
@@ -16,23 +16,13 @@
|
||||
#pragma once
|
||||
#include <stratosphere.hpp>
|
||||
|
||||
namespace ams::pm::bm {
|
||||
namespace ams::pm {
|
||||
|
||||
class BootModeService final : public sf::IServiceObject {
|
||||
private:
|
||||
enum class CommandId {
|
||||
GetBootMode = 0,
|
||||
SetMaintenanceBoot = 1,
|
||||
};
|
||||
private:
|
||||
/* Actual command implementations. */
|
||||
class BootModeService final {
|
||||
public:
|
||||
void GetBootMode(sf::Out<u32> out);
|
||||
void SetMaintenanceBoot();
|
||||
public:
|
||||
DEFINE_SERVICE_DISPATCH_TABLE {
|
||||
MAKE_SERVICE_COMMAND_META(GetBootMode),
|
||||
MAKE_SERVICE_COMMAND_META(SetMaintenanceBoot),
|
||||
};
|
||||
};
|
||||
static_assert(pm::impl::IsIBootModeInterface<BootModeService>);
|
||||
|
||||
}
|
||||
|
||||
@@ -17,49 +17,49 @@
|
||||
#include "pm_debug_monitor_service.hpp"
|
||||
#include "impl/pm_process_manager.hpp"
|
||||
|
||||
namespace ams::pm::dmnt {
|
||||
namespace ams::pm {
|
||||
|
||||
/* Actual command implementations. */
|
||||
Result DebugMonitorServiceBase::GetModuleIdList(sf::Out<u32> out_count, const sf::OutBuffer &out_buf, u64 unused) {
|
||||
Result DebugMonitorService::GetModuleIdList(sf::Out<u32> out_count, const sf::OutBuffer &out_buf, u64 unused) {
|
||||
R_UNLESS(out_buf.GetSize() <= std::numeric_limits<s32>::max(), pm::ResultInvalidSize());
|
||||
return impl::GetModuleIdList(out_count.GetPointer(), out_buf.GetPointer(), out_buf.GetSize(), unused);
|
||||
}
|
||||
|
||||
Result DebugMonitorServiceBase::GetExceptionProcessIdList(sf::Out<u32> out_count, const sf::OutArray<os::ProcessId> &out_process_ids) {
|
||||
Result DebugMonitorService::GetExceptionProcessIdList(sf::Out<u32> out_count, const sf::OutArray<os::ProcessId> &out_process_ids) {
|
||||
R_UNLESS(out_process_ids.GetSize() <= std::numeric_limits<s32>::max(), pm::ResultInvalidSize());
|
||||
return impl::GetExceptionProcessIdList(out_count.GetPointer(), out_process_ids.GetPointer(), out_process_ids.GetSize());
|
||||
}
|
||||
|
||||
Result DebugMonitorServiceBase::StartProcess(os::ProcessId process_id) {
|
||||
Result DebugMonitorService::StartProcess(os::ProcessId process_id) {
|
||||
return impl::StartProcess(process_id);
|
||||
}
|
||||
|
||||
Result DebugMonitorServiceBase::GetProcessId(sf::Out<os::ProcessId> out, ncm::ProgramId program_id) {
|
||||
Result DebugMonitorService::GetProcessId(sf::Out<os::ProcessId> out, ncm::ProgramId program_id) {
|
||||
return impl::GetProcessId(out.GetPointer(), program_id);
|
||||
}
|
||||
|
||||
Result DebugMonitorServiceBase::HookToCreateProcess(sf::OutCopyHandle out_hook, ncm::ProgramId program_id) {
|
||||
Result DebugMonitorService::HookToCreateProcess(sf::OutCopyHandle out_hook, ncm::ProgramId program_id) {
|
||||
return impl::HookToCreateProcess(out_hook.GetHandlePointer(), program_id);
|
||||
}
|
||||
|
||||
Result DebugMonitorServiceBase::GetApplicationProcessId(sf::Out<os::ProcessId> out) {
|
||||
Result DebugMonitorService::GetApplicationProcessId(sf::Out<os::ProcessId> out) {
|
||||
return impl::GetApplicationProcessId(out.GetPointer());
|
||||
}
|
||||
|
||||
Result DebugMonitorServiceBase::HookToCreateApplicationProcess(sf::OutCopyHandle out_hook) {
|
||||
Result DebugMonitorService::HookToCreateApplicationProcess(sf::OutCopyHandle out_hook) {
|
||||
return impl::HookToCreateApplicationProcess(out_hook.GetHandlePointer());
|
||||
}
|
||||
|
||||
Result DebugMonitorServiceBase::ClearHook(u32 which) {
|
||||
Result DebugMonitorService::ClearHook(u32 which) {
|
||||
return impl::ClearHook(which);
|
||||
}
|
||||
|
||||
/* Atmosphere extension commands. */
|
||||
Result DebugMonitorServiceBase::AtmosphereGetProcessInfo(sf::OutCopyHandle out_process_handle, sf::Out<ncm::ProgramLocation> out_loc, sf::Out<cfg::OverrideStatus> out_status, os::ProcessId process_id) {
|
||||
Result DebugMonitorService::AtmosphereGetProcessInfo(sf::OutCopyHandle out_process_handle, sf::Out<ncm::ProgramLocation> out_loc, sf::Out<cfg::OverrideStatus> out_status, os::ProcessId process_id) {
|
||||
return impl::AtmosphereGetProcessInfo(out_process_handle.GetHandlePointer(), out_loc.GetPointer(), out_status.GetPointer(), process_id);
|
||||
}
|
||||
|
||||
Result DebugMonitorServiceBase::AtmosphereGetCurrentLimitInfo(sf::Out<s64> out_cur_val, sf::Out<s64> out_lim_val, u32 group, u32 resource) {
|
||||
Result DebugMonitorService::AtmosphereGetCurrentLimitInfo(sf::Out<s64> out_cur_val, sf::Out<s64> out_lim_val, u32 group, u32 resource) {
|
||||
return impl::AtmosphereGetCurrentLimitInfo(out_cur_val.GetPointer(), out_lim_val.GetPointer(), group, resource);
|
||||
}
|
||||
|
||||
|
||||
@@ -16,90 +16,24 @@
|
||||
#pragma once
|
||||
#include <stratosphere.hpp>
|
||||
|
||||
namespace ams::pm::dmnt {
|
||||
namespace ams::pm {
|
||||
|
||||
class DebugMonitorServiceBase : public sf::IServiceObject {
|
||||
protected:
|
||||
class DebugMonitorService final {
|
||||
public:
|
||||
/* Actual command implementations. */
|
||||
virtual Result GetModuleIdList(sf::Out<u32> out_count, const sf::OutBuffer &out_buf, u64 unused);
|
||||
virtual Result GetExceptionProcessIdList(sf::Out<u32> out_count, const sf::OutArray<os::ProcessId> &out_process_ids);
|
||||
virtual Result StartProcess(os::ProcessId process_id);
|
||||
virtual Result GetProcessId(sf::Out<os::ProcessId> out, ncm::ProgramId program_id);
|
||||
virtual Result HookToCreateProcess(sf::OutCopyHandle out_hook, ncm::ProgramId program_id);
|
||||
virtual Result GetApplicationProcessId(sf::Out<os::ProcessId> out);
|
||||
virtual Result HookToCreateApplicationProcess(sf::OutCopyHandle out_hook);
|
||||
virtual Result ClearHook(u32 which);
|
||||
Result GetModuleIdList(sf::Out<u32> out_count, const sf::OutBuffer &out_buf, u64 unused);
|
||||
Result GetExceptionProcessIdList(sf::Out<u32> out_count, const sf::OutArray<os::ProcessId> &out_process_ids);
|
||||
Result StartProcess(os::ProcessId process_id);
|
||||
Result GetProcessId(sf::Out<os::ProcessId> out, ncm::ProgramId program_id);
|
||||
Result HookToCreateProcess(sf::OutCopyHandle out_hook, ncm::ProgramId program_id);
|
||||
Result GetApplicationProcessId(sf::Out<os::ProcessId> out);
|
||||
Result HookToCreateApplicationProcess(sf::OutCopyHandle out_hook);
|
||||
Result ClearHook(u32 which);
|
||||
|
||||
/* Atmosphere extension commands. */
|
||||
virtual Result AtmosphereGetProcessInfo(sf::OutCopyHandle out_process_handle, sf::Out<ncm::ProgramLocation> out_loc, sf::Out<cfg::OverrideStatus> out_status, os::ProcessId process_id);
|
||||
virtual Result AtmosphereGetCurrentLimitInfo(sf::Out<s64> out_cur_val, sf::Out<s64> out_lim_val, u32 group, u32 resource);
|
||||
};
|
||||
|
||||
/* This represents modern DebugMonitorService (5.0.0+). */
|
||||
class DebugMonitorService final : public DebugMonitorServiceBase {
|
||||
private:
|
||||
enum class CommandId {
|
||||
GetExceptionProcessIdList = 0,
|
||||
StartProcess = 1,
|
||||
GetProcessId = 2,
|
||||
HookToCreateProcess = 3,
|
||||
GetApplicationProcessId = 4,
|
||||
HookToCreateApplicationProcess = 5,
|
||||
|
||||
ClearHook = 6,
|
||||
|
||||
AtmosphereGetProcessInfo = 65000,
|
||||
AtmosphereGetCurrentLimitInfo = 65001,
|
||||
};
|
||||
public:
|
||||
DEFINE_SERVICE_DISPATCH_TABLE {
|
||||
/* 5.0.0-* */
|
||||
MAKE_SERVICE_COMMAND_META(GetExceptionProcessIdList),
|
||||
MAKE_SERVICE_COMMAND_META(StartProcess),
|
||||
MAKE_SERVICE_COMMAND_META(GetProcessId),
|
||||
MAKE_SERVICE_COMMAND_META(HookToCreateProcess),
|
||||
MAKE_SERVICE_COMMAND_META(GetApplicationProcessId),
|
||||
MAKE_SERVICE_COMMAND_META(HookToCreateApplicationProcess),
|
||||
|
||||
/* 6.0.0-* */
|
||||
MAKE_SERVICE_COMMAND_META(ClearHook, hos::Version_6_0_0),
|
||||
|
||||
/* Atmosphere extensions. */
|
||||
MAKE_SERVICE_COMMAND_META(AtmosphereGetProcessInfo),
|
||||
MAKE_SERVICE_COMMAND_META(AtmosphereGetCurrentLimitInfo),
|
||||
};
|
||||
};
|
||||
|
||||
/* This represents deprecated DebugMonitorService (1.0.0-4.1.0). */
|
||||
class DebugMonitorServiceDeprecated final : public DebugMonitorServiceBase {
|
||||
private:
|
||||
enum class CommandId {
|
||||
GetModuleIdList = 0,
|
||||
GetExceptionProcessIdList = 1,
|
||||
StartProcess = 2,
|
||||
GetProcessId = 3,
|
||||
HookToCreateProcess = 4,
|
||||
GetApplicationProcessId = 5,
|
||||
HookToCreateApplicationProcess = 6,
|
||||
|
||||
AtmosphereGetProcessInfo = 65000,
|
||||
AtmosphereGetCurrentLimitInfo = 65001,
|
||||
};
|
||||
public:
|
||||
DEFINE_SERVICE_DISPATCH_TABLE {
|
||||
/* 1.0.0-4.1.0 */
|
||||
MAKE_SERVICE_COMMAND_META(GetModuleIdList),
|
||||
MAKE_SERVICE_COMMAND_META(GetExceptionProcessIdList),
|
||||
MAKE_SERVICE_COMMAND_META(StartProcess),
|
||||
MAKE_SERVICE_COMMAND_META(GetProcessId),
|
||||
MAKE_SERVICE_COMMAND_META(HookToCreateProcess),
|
||||
MAKE_SERVICE_COMMAND_META(GetApplicationProcessId),
|
||||
MAKE_SERVICE_COMMAND_META(HookToCreateApplicationProcess),
|
||||
|
||||
/* Atmosphere extensions. */
|
||||
MAKE_SERVICE_COMMAND_META(AtmosphereGetProcessInfo),
|
||||
MAKE_SERVICE_COMMAND_META(AtmosphereGetCurrentLimitInfo),
|
||||
};
|
||||
Result AtmosphereGetProcessInfo(sf::OutCopyHandle out_process_handle, sf::Out<ncm::ProgramLocation> out_loc, sf::Out<cfg::OverrideStatus> out_status, os::ProcessId process_id);
|
||||
Result AtmosphereGetCurrentLimitInfo(sf::Out<s64> out_cur_val, sf::Out<s64> out_lim_val, u32 group, u32 resource);
|
||||
};
|
||||
static_assert(pm::impl::IsIDebugMonitorInterface<DebugMonitorService>);
|
||||
|
||||
}
|
||||
|
||||
@@ -17,11 +17,15 @@
|
||||
#include "pm_info_service.hpp"
|
||||
#include "impl/pm_process_manager.hpp"
|
||||
|
||||
namespace ams::pm::info {
|
||||
namespace ams::pm {
|
||||
|
||||
/* Overrides for libstratosphere pm::info commands. */
|
||||
Result HasLaunchedProgram(bool *out, ncm::ProgramId program_id) {
|
||||
return ldr::pm::HasLaunchedProgram(out, program_id);
|
||||
namespace info {
|
||||
|
||||
Result HasLaunchedProgram(bool *out, ncm::ProgramId program_id) {
|
||||
return ldr::pm::HasLaunchedProgram(out, program_id);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* Actual command implementations. */
|
||||
|
||||
@@ -16,18 +16,10 @@
|
||||
#pragma once
|
||||
#include <stratosphere.hpp>
|
||||
|
||||
namespace ams::pm::info {
|
||||
namespace ams::pm {
|
||||
|
||||
class InformationService final : public sf::IServiceObject {
|
||||
private:
|
||||
enum class CommandId {
|
||||
GetProgramId = 0,
|
||||
|
||||
AtmosphereGetProcessId = 65000,
|
||||
AtmosphereHasLaunchedProgram = 65001,
|
||||
AtmosphereGetProcessInfo = 65002,
|
||||
};
|
||||
private:
|
||||
class InformationService final {
|
||||
public:
|
||||
/* Actual command implementations. */
|
||||
Result GetProgramId(sf::Out<ncm::ProgramId> out, os::ProcessId process_id);
|
||||
|
||||
@@ -35,14 +27,7 @@ namespace ams::pm::info {
|
||||
Result AtmosphereGetProcessId(sf::Out<os::ProcessId> out, ncm::ProgramId program_id);
|
||||
Result AtmosphereHasLaunchedProgram(sf::Out<bool> out, ncm::ProgramId program_id);
|
||||
Result AtmosphereGetProcessInfo(sf::Out<ncm::ProgramLocation> out_loc, sf::Out<cfg::OverrideStatus> out_status, os::ProcessId process_id);
|
||||
public:
|
||||
DEFINE_SERVICE_DISPATCH_TABLE {
|
||||
MAKE_SERVICE_COMMAND_META(GetProgramId),
|
||||
|
||||
MAKE_SERVICE_COMMAND_META(AtmosphereGetProcessId),
|
||||
MAKE_SERVICE_COMMAND_META(AtmosphereHasLaunchedProgram),
|
||||
MAKE_SERVICE_COMMAND_META(AtmosphereGetProcessInfo),
|
||||
};
|
||||
};
|
||||
static_assert(pm::impl::IsIInformationInterface<InformationService>);
|
||||
|
||||
}
|
||||
|
||||
@@ -196,14 +196,14 @@ int main(int argc, char **argv)
|
||||
/* NOTE: Extra sessions have been added to pm:bm and pm:info to facilitate access by the rest of stratosphere. */
|
||||
/* Also Note: PM was rewritten in 5.0.0, so the shell and dmnt services are different before/after. */
|
||||
if (hos::GetVersion() >= hos::Version_5_0_0) {
|
||||
R_ABORT_UNLESS((g_server_manager.RegisterServer<pm::shell::ShellService>(ShellServiceName, ShellMaxSessions)));
|
||||
R_ABORT_UNLESS((g_server_manager.RegisterServer<pm::dmnt::DebugMonitorService>(DebugMonitorServiceName, DebugMonitorMaxSessions)));
|
||||
R_ABORT_UNLESS((g_server_manager.RegisterServer<pm::impl::IShellInterface, pm::ShellService>(ShellServiceName, ShellMaxSessions)));
|
||||
R_ABORT_UNLESS((g_server_manager.RegisterServer<pm::impl::IDebugMonitorInterface, pm::DebugMonitorService>(DebugMonitorServiceName, DebugMonitorMaxSessions)));
|
||||
} else {
|
||||
R_ABORT_UNLESS((g_server_manager.RegisterServer<pm::shell::ShellServiceDeprecated>(ShellServiceName, ShellMaxSessions)));
|
||||
R_ABORT_UNLESS((g_server_manager.RegisterServer<pm::dmnt::DebugMonitorServiceDeprecated>(DebugMonitorServiceName, DebugMonitorMaxSessions)));
|
||||
R_ABORT_UNLESS((g_server_manager.RegisterServer<pm::impl::IDeprecatedShellInterface, pm::ShellService>(ShellServiceName, ShellMaxSessions)));
|
||||
R_ABORT_UNLESS((g_server_manager.RegisterServer<pm::impl::IDeprecatedDebugMonitorInterface, pm::DebugMonitorService>(DebugMonitorServiceName, DebugMonitorMaxSessions)));
|
||||
}
|
||||
R_ABORT_UNLESS((g_server_manager.RegisterServer<pm::bm::BootModeService>(BootModeServiceName, BootModeMaxSessions)));
|
||||
R_ABORT_UNLESS((g_server_manager.RegisterServer<pm::info::InformationService>(InformationServiceName, InformationMaxSessions)));
|
||||
R_ABORT_UNLESS((g_server_manager.RegisterServer<pm::impl::IBootModeInterface, pm::BootModeService>(BootModeServiceName, BootModeMaxSessions)));
|
||||
R_ABORT_UNLESS((g_server_manager.RegisterServer<pm::impl::IInformationInterface, pm::InformationService>(InformationServiceName, InformationMaxSessions)));
|
||||
|
||||
/* Loop forever, servicing our services. */
|
||||
g_server_manager.LoopProcess();
|
||||
|
||||
@@ -17,59 +17,63 @@
|
||||
#include "pm_shell_service.hpp"
|
||||
#include "impl/pm_process_manager.hpp"
|
||||
|
||||
namespace ams::pm::shell {
|
||||
namespace ams::pm {
|
||||
|
||||
/* Overrides for libstratosphere pm::shell commands. */
|
||||
Result LaunchProgram(os::ProcessId *out_process_id, const ncm::ProgramLocation &loc, u32 launch_flags) {
|
||||
return impl::LaunchProgram(out_process_id, loc, launch_flags);
|
||||
namespace shell {
|
||||
|
||||
Result LaunchProgram(os::ProcessId *out_process_id, const ncm::ProgramLocation &loc, u32 launch_flags) {
|
||||
return impl::LaunchProgram(out_process_id, loc, launch_flags);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* Service command implementations. */
|
||||
Result ShellServiceBase::LaunchProgram(sf::Out<os::ProcessId> out_process_id, const ncm::ProgramLocation &loc, u32 flags) {
|
||||
Result ShellService::LaunchProgram(sf::Out<os::ProcessId> out_process_id, const ncm::ProgramLocation &loc, u32 flags) {
|
||||
return pm::shell::LaunchProgram(out_process_id.GetPointer(), loc, flags);
|
||||
}
|
||||
|
||||
Result ShellServiceBase::TerminateProcess(os::ProcessId process_id) {
|
||||
Result ShellService::TerminateProcess(os::ProcessId process_id) {
|
||||
return impl::TerminateProcess(process_id);
|
||||
}
|
||||
|
||||
Result ShellServiceBase::TerminateProgram(ncm::ProgramId program_id) {
|
||||
Result ShellService::TerminateProgram(ncm::ProgramId program_id) {
|
||||
return impl::TerminateProgram(program_id);
|
||||
}
|
||||
|
||||
void ShellServiceBase::GetProcessEventHandle(sf::OutCopyHandle out) {
|
||||
void ShellService::GetProcessEventHandle(sf::OutCopyHandle out) {
|
||||
R_ABORT_UNLESS(impl::GetProcessEventHandle(out.GetHandlePointer()));
|
||||
}
|
||||
|
||||
void ShellServiceBase::GetProcessEventInfo(sf::Out<ProcessEventInfo> out) {
|
||||
void ShellService::GetProcessEventInfo(sf::Out<ProcessEventInfo> out) {
|
||||
R_ABORT_UNLESS(impl::GetProcessEventInfo(out.GetPointer()));
|
||||
}
|
||||
|
||||
Result ShellServiceBase::CleanupProcess(os::ProcessId process_id) {
|
||||
Result ShellService::CleanupProcess(os::ProcessId process_id) {
|
||||
return impl::CleanupProcess(process_id);
|
||||
}
|
||||
|
||||
Result ShellServiceBase::ClearExceptionOccurred(os::ProcessId process_id) {
|
||||
Result ShellService::ClearExceptionOccurred(os::ProcessId process_id) {
|
||||
return impl::ClearExceptionOccurred(process_id);
|
||||
}
|
||||
|
||||
void ShellServiceBase::NotifyBootFinished() {
|
||||
void ShellService::NotifyBootFinished() {
|
||||
R_ABORT_UNLESS(impl::NotifyBootFinished());
|
||||
}
|
||||
|
||||
Result ShellServiceBase::GetApplicationProcessIdForShell(sf::Out<os::ProcessId> out) {
|
||||
Result ShellService::GetApplicationProcessIdForShell(sf::Out<os::ProcessId> out) {
|
||||
return impl::GetApplicationProcessId(out.GetPointer());
|
||||
}
|
||||
|
||||
Result ShellServiceBase::BoostSystemMemoryResourceLimit(u64 boost_size) {
|
||||
Result ShellService::BoostSystemMemoryResourceLimit(u64 boost_size) {
|
||||
return impl::BoostSystemMemoryResourceLimit(boost_size);
|
||||
}
|
||||
|
||||
Result ShellServiceBase::BoostApplicationThreadResourceLimit() {
|
||||
Result ShellService::BoostApplicationThreadResourceLimit() {
|
||||
return impl::BoostApplicationThreadResourceLimit();
|
||||
}
|
||||
|
||||
void ShellServiceBase::GetBootFinishedEventHandle(sf::OutCopyHandle out) {
|
||||
void ShellService::GetBootFinishedEventHandle(sf::OutCopyHandle out) {
|
||||
R_ABORT_UNLESS(impl::GetBootFinishedEventHandle(out.GetHandlePointer()));
|
||||
}
|
||||
|
||||
|
||||
@@ -16,91 +16,24 @@
|
||||
#pragma once
|
||||
#include <stratosphere.hpp>
|
||||
|
||||
namespace ams::pm::shell {
|
||||
namespace ams::pm {
|
||||
|
||||
class ShellServiceBase : public sf::IServiceObject {
|
||||
protected:
|
||||
class ShellService final {
|
||||
public:
|
||||
/* Actual command implementations. */
|
||||
virtual Result LaunchProgram(sf::Out<os::ProcessId> out_process_id, const ncm::ProgramLocation &loc, u32 flags);
|
||||
virtual Result TerminateProcess(os::ProcessId process_id);
|
||||
virtual Result TerminateProgram(ncm::ProgramId program_id);
|
||||
virtual void GetProcessEventHandle(sf::OutCopyHandle out);
|
||||
virtual void GetProcessEventInfo(sf::Out<ProcessEventInfo> out);
|
||||
virtual Result CleanupProcess(os::ProcessId process_id);
|
||||
virtual Result ClearExceptionOccurred(os::ProcessId process_id);
|
||||
virtual void NotifyBootFinished();
|
||||
virtual Result GetApplicationProcessIdForShell(sf::Out<os::ProcessId> out);
|
||||
virtual Result BoostSystemMemoryResourceLimit(u64 boost_size);
|
||||
virtual Result BoostApplicationThreadResourceLimit();
|
||||
virtual void GetBootFinishedEventHandle(sf::OutCopyHandle out);
|
||||
};
|
||||
|
||||
/* This represents modern ShellService (5.0.0+). */
|
||||
class ShellService final : public ShellServiceBase {
|
||||
private:
|
||||
enum class CommandId {
|
||||
LaunchProgram = 0,
|
||||
TerminateProcess = 1,
|
||||
TerminateProgram = 2,
|
||||
GetProcessEventHandle = 3,
|
||||
GetProcessEventInfo = 4,
|
||||
NotifyBootFinished = 5,
|
||||
GetApplicationProcessIdForShell = 6,
|
||||
BoostSystemMemoryResourceLimit = 7,
|
||||
BoostApplicationThreadResourceLimit = 8,
|
||||
GetBootFinishedEventHandle = 9,
|
||||
};
|
||||
public:
|
||||
DEFINE_SERVICE_DISPATCH_TABLE {
|
||||
/* 5.0.0-* */
|
||||
MAKE_SERVICE_COMMAND_META(LaunchProgram),
|
||||
MAKE_SERVICE_COMMAND_META(TerminateProcess),
|
||||
MAKE_SERVICE_COMMAND_META(TerminateProgram),
|
||||
MAKE_SERVICE_COMMAND_META(GetProcessEventHandle),
|
||||
MAKE_SERVICE_COMMAND_META(GetProcessEventInfo),
|
||||
MAKE_SERVICE_COMMAND_META(NotifyBootFinished),
|
||||
MAKE_SERVICE_COMMAND_META(GetApplicationProcessIdForShell),
|
||||
MAKE_SERVICE_COMMAND_META(BoostSystemMemoryResourceLimit),
|
||||
|
||||
/* 7.0.0-* */
|
||||
MAKE_SERVICE_COMMAND_META(BoostApplicationThreadResourceLimit, hos::Version_7_0_0),
|
||||
|
||||
/* 8.0.0-* */
|
||||
MAKE_SERVICE_COMMAND_META(GetBootFinishedEventHandle, hos::Version_8_0_0),
|
||||
};
|
||||
};
|
||||
|
||||
/* This represents deprecated ShellService (1.0.0-4.1.0). */
|
||||
class ShellServiceDeprecated final : public ShellServiceBase {
|
||||
private:
|
||||
enum class CommandId {
|
||||
LaunchProgram = 0,
|
||||
TerminateProcess = 1,
|
||||
TerminateProgram = 2,
|
||||
GetProcessEventHandle = 3,
|
||||
GetProcessEventInfo = 4,
|
||||
CleanupProcess = 5,
|
||||
ClearExceptionOccurred = 6,
|
||||
NotifyBootFinished = 7,
|
||||
GetApplicationProcessIdForShell = 8,
|
||||
BoostSystemMemoryResourceLimit = 9,
|
||||
};
|
||||
public:
|
||||
DEFINE_SERVICE_DISPATCH_TABLE {
|
||||
/* 1.0.0-4.1.0 */
|
||||
MAKE_SERVICE_COMMAND_META(LaunchProgram),
|
||||
MAKE_SERVICE_COMMAND_META(TerminateProcess),
|
||||
MAKE_SERVICE_COMMAND_META(TerminateProgram),
|
||||
MAKE_SERVICE_COMMAND_META(GetProcessEventHandle),
|
||||
MAKE_SERVICE_COMMAND_META(GetProcessEventInfo),
|
||||
MAKE_SERVICE_COMMAND_META(CleanupProcess),
|
||||
MAKE_SERVICE_COMMAND_META(ClearExceptionOccurred),
|
||||
MAKE_SERVICE_COMMAND_META(NotifyBootFinished),
|
||||
MAKE_SERVICE_COMMAND_META(GetApplicationProcessIdForShell),
|
||||
|
||||
/* 4.0.0-4.1.0 */
|
||||
MAKE_SERVICE_COMMAND_META(BoostSystemMemoryResourceLimit, hos::Version_4_0_0),
|
||||
};
|
||||
Result LaunchProgram(sf::Out<os::ProcessId> out_process_id, const ncm::ProgramLocation &loc, u32 flags);
|
||||
Result TerminateProcess(os::ProcessId process_id);
|
||||
Result TerminateProgram(ncm::ProgramId program_id);
|
||||
void GetProcessEventHandle(sf::OutCopyHandle out);
|
||||
void GetProcessEventInfo(sf::Out<ProcessEventInfo> out);
|
||||
Result CleanupProcess(os::ProcessId process_id);
|
||||
Result ClearExceptionOccurred(os::ProcessId process_id);
|
||||
void NotifyBootFinished();
|
||||
Result GetApplicationProcessIdForShell(sf::Out<os::ProcessId> out);
|
||||
Result BoostSystemMemoryResourceLimit(u64 boost_size);
|
||||
Result BoostApplicationThreadResourceLimit();
|
||||
void GetBootFinishedEventHandle(sf::OutCopyHandle out);
|
||||
};
|
||||
static_assert(pm::impl::IsIShellInterface<ShellService>);
|
||||
|
||||
}
|
||||
|
||||
@@ -413,7 +413,7 @@ namespace ams::ro::impl {
|
||||
}
|
||||
|
||||
/* Service implementations. */
|
||||
Result LoadNrr(size_t context_id, Handle process_h, u64 nrr_address, u64 nrr_size, ModuleType expected_type, bool enforce_type) {
|
||||
Result RegisterModuleInfo(size_t context_id, Handle process_h, u64 nrr_address, u64 nrr_size, ModuleType expected_type, bool enforce_type) {
|
||||
/* Get context. */
|
||||
ProcessContext *context = GetContextById(context_id);
|
||||
AMS_ABORT_UNLESS(context != nullptr);
|
||||
@@ -454,7 +454,7 @@ namespace ams::ro::impl {
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
Result UnloadNrr(size_t context_id, u64 nrr_address) {
|
||||
Result UnregisterModuleInfo(size_t context_id, u64 nrr_address) {
|
||||
/* Get context. */
|
||||
ProcessContext *context = GetContextById(context_id);
|
||||
AMS_ABORT_UNLESS(context != nullptr);
|
||||
@@ -476,7 +476,7 @@ namespace ams::ro::impl {
|
||||
return UnmapNrr(context->process_handle, nrr_backup.mapped_header, nrr_backup.nrr_heap_address, nrr_backup.nrr_heap_size, nrr_backup.mapped_code_address);
|
||||
}
|
||||
|
||||
Result LoadNro(u64 *out_address, size_t context_id, u64 nro_address, u64 nro_size, u64 bss_address, u64 bss_size) {
|
||||
Result MapManualLoadModuleMemory(u64 *out_address, size_t context_id, u64 nro_address, u64 nro_size, u64 bss_address, u64 bss_size) {
|
||||
/* Get context. */
|
||||
ProcessContext *context = GetContextById(context_id);
|
||||
AMS_ABORT_UNLESS(context != nullptr);
|
||||
@@ -522,7 +522,7 @@ namespace ams::ro::impl {
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
Result UnloadNro(size_t context_id, u64 nro_address) {
|
||||
Result UnmapManualLoadModuleMemory(size_t context_id, u64 nro_address) {
|
||||
/* Get context. */
|
||||
ProcessContext *context = GetContextById(context_id);
|
||||
AMS_ABORT_UNLESS(context != nullptr);
|
||||
|
||||
@@ -35,10 +35,10 @@ namespace ams::ro::impl {
|
||||
void UnregisterProcess(size_t context_id);
|
||||
|
||||
/* Service implementations. */
|
||||
Result LoadNrr(size_t context_id, Handle process_h, u64 nrr_address, u64 nrr_size, ModuleType expected_type, bool enforce_type);
|
||||
Result UnloadNrr(size_t context_id, u64 nrr_address);
|
||||
Result LoadNro(u64 *out_address, size_t context_id, u64 nro_address, u64 nro_size, u64 bss_address, u64 bss_size);
|
||||
Result UnloadNro(size_t context_id, u64 nro_address);
|
||||
Result RegisterModuleInfo(size_t context_id, Handle process_h, u64 nrr_address, u64 nrr_size, ModuleType expected_type, bool enforce_type);
|
||||
Result UnregisterModuleInfo(size_t context_id, u64 nrr_address);
|
||||
Result MapManualLoadModuleMemory(u64 *out_address, size_t context_id, u64 nro_address, u64 nro_size, u64 bss_address, u64 bss_size);
|
||||
Result UnmapManualLoadModuleMemory(size_t context_id, u64 nro_address);
|
||||
|
||||
/* Debug service implementations. */
|
||||
Result GetProcessModuleInfo(u32 *out_count, LoaderModuleInfo *out_infos, size_t max_out_count, os::ProcessId process_id);
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include <stratosphere.hpp>
|
||||
#include "ro_debug_monitor.hpp"
|
||||
#include "ro_debug_monitor_service.hpp"
|
||||
#include "impl/ro_service_impl.hpp"
|
||||
|
||||
namespace ams::ro {
|
||||
@@ -18,18 +18,10 @@
|
||||
|
||||
namespace ams::ro {
|
||||
|
||||
class DebugMonitorService final : public sf::IServiceObject {
|
||||
protected:
|
||||
enum class CommandId {
|
||||
GetProcessModuleInfo = 0,
|
||||
};
|
||||
private:
|
||||
/* Actual commands. */
|
||||
Result GetProcessModuleInfo(sf::Out<u32> out_count, const sf::OutArray<LoaderModuleInfo> &out_infos, os::ProcessId process_id);
|
||||
class DebugMonitorService final {
|
||||
public:
|
||||
DEFINE_SERVICE_DISPATCH_TABLE {
|
||||
MAKE_SERVICE_COMMAND_META(GetProcessModuleInfo),
|
||||
};
|
||||
Result GetProcessModuleInfo(sf::Out<u32> out_count, const sf::OutArray<LoaderModuleInfo> &out_infos, os::ProcessId process_id);
|
||||
};
|
||||
static_assert(ro::impl::IsIDebugMonitorInterface<DebugMonitorService>);
|
||||
|
||||
}
|
||||
@@ -14,8 +14,8 @@
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include <stratosphere.hpp>
|
||||
#include "ro_debug_monitor.hpp"
|
||||
#include "ro_service.hpp"
|
||||
#include "ro_debug_monitor_service.hpp"
|
||||
#include "ro_ro_service.hpp"
|
||||
|
||||
extern "C" {
|
||||
extern u32 __start__;
|
||||
@@ -84,10 +84,6 @@ void __appExit(void) {
|
||||
setsysExit();
|
||||
}
|
||||
|
||||
/* Helpers to create RO objects. */
|
||||
static constexpr auto MakeRoServiceForSelf = []() { return std::make_shared<ro::Service>(ro::ModuleType::ForSelf); };
|
||||
static constexpr auto MakeRoServiceForOthers = []() { return std::make_shared<ro::Service>(ro::ModuleType::ForOthers); };
|
||||
|
||||
namespace {
|
||||
|
||||
/* ldr:ro, ro:dmnt, ro:1. */
|
||||
@@ -122,11 +118,11 @@ int main(int argc, char **argv)
|
||||
}
|
||||
|
||||
/* Create services. */
|
||||
R_ABORT_UNLESS((g_server_manager.RegisterServer<ro::DebugMonitorService>(DebugMonitorServiceName, DebugMonitorMaxSessions)));
|
||||
R_ABORT_UNLESS((g_server_manager.RegisterServer<ro::impl::IDebugMonitorInterface, ro::DebugMonitorService>(DebugMonitorServiceName, DebugMonitorMaxSessions)));
|
||||
|
||||
R_ABORT_UNLESS((g_server_manager.RegisterServer<ro::Service, +MakeRoServiceForSelf>(ForSelfServiceName, ForSelfMaxSessions)));
|
||||
R_ABORT_UNLESS((g_server_manager.RegisterServer<ro::impl::IRoInterface, ro::RoServiceForSelf>(ForSelfServiceName, ForSelfMaxSessions)));
|
||||
if (hos::GetVersion() >= hos::Version_7_0_0) {
|
||||
R_ABORT_UNLESS((g_server_manager.RegisterServer<ro::Service, +MakeRoServiceForOthers>(ForOthersServiceName, ForOthersMaxSessions)));
|
||||
R_ABORT_UNLESS((g_server_manager.RegisterServer<ro::impl::IRoInterface, ro::RoServiceForOthers>(ForOthersServiceName, ForOthersMaxSessions)));
|
||||
}
|
||||
|
||||
/* Loop forever, servicing our services. */
|
||||
|
||||
67
stratosphere/ro/source/ro_ro_service.cpp
Normal file
67
stratosphere/ro/source/ro_ro_service.cpp
Normal file
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2020 Atmosphère-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include <stratosphere.hpp>
|
||||
#include "ro_ro_service.hpp"
|
||||
#include "impl/ro_service_impl.hpp"
|
||||
|
||||
namespace ams::ro {
|
||||
|
||||
void SetDevelopmentHardware(bool is_development_hardware) {
|
||||
impl::SetDevelopmentHardware(is_development_hardware);
|
||||
}
|
||||
|
||||
void SetDevelopmentFunctionEnabled(bool is_development_function_enabled) {
|
||||
impl::SetDevelopmentFunctionEnabled(is_development_function_enabled);
|
||||
}
|
||||
|
||||
RoService::RoService(ModuleType t) : context_id(impl::InvalidContextId), type(t) {
|
||||
/* ... */
|
||||
}
|
||||
|
||||
RoService::~RoService() {
|
||||
impl::UnregisterProcess(this->context_id);
|
||||
}
|
||||
|
||||
Result RoService::MapManualLoadModuleMemory(sf::Out<u64> load_address, const sf::ClientProcessId &client_pid, u64 nro_address, u64 nro_size, u64 bss_address, u64 bss_size) {
|
||||
R_TRY(impl::ValidateProcess(this->context_id, client_pid.GetValue()));
|
||||
return impl::MapManualLoadModuleMemory(load_address.GetPointer(), this->context_id, nro_address, nro_size, bss_address, bss_size);
|
||||
}
|
||||
|
||||
Result RoService::UnmapManualLoadModuleMemory(const sf::ClientProcessId &client_pid, u64 nro_address) {
|
||||
R_TRY(impl::ValidateProcess(this->context_id, client_pid.GetValue()));
|
||||
return impl::UnmapManualLoadModuleMemory(this->context_id, nro_address);
|
||||
}
|
||||
|
||||
Result RoService::RegisterModuleInfo(const sf::ClientProcessId &client_pid, u64 nrr_address, u64 nrr_size) {
|
||||
R_TRY(impl::ValidateProcess(this->context_id, client_pid.GetValue()));
|
||||
return impl::RegisterModuleInfo(this->context_id, svc::InvalidHandle, nrr_address, nrr_size, ModuleType::ForSelf, true);
|
||||
}
|
||||
|
||||
Result RoService::UnregisterModuleInfo(const sf::ClientProcessId &client_pid, u64 nrr_address) {
|
||||
R_TRY(impl::ValidateProcess(this->context_id, client_pid.GetValue()));
|
||||
return impl::UnregisterModuleInfo(this->context_id, nrr_address);
|
||||
}
|
||||
|
||||
Result RoService::RegisterProcessHandle(const sf::ClientProcessId &client_pid, sf::CopyHandle process_h) {
|
||||
return impl::RegisterProcess(std::addressof(this->context_id), process_h.GetValue(), client_pid.GetValue());
|
||||
}
|
||||
|
||||
Result RoService::RegisterModuleInfoEx(const sf::ClientProcessId &client_pid, u64 nrr_address, u64 nrr_size, sf::CopyHandle process_h) {
|
||||
R_TRY(impl::ValidateProcess(this->context_id, client_pid.GetValue()));
|
||||
return impl::RegisterModuleInfo(this->context_id, process_h.GetValue(), nrr_address, nrr_size, this->type, this->type == ModuleType::ForOthers);
|
||||
}
|
||||
|
||||
}
|
||||
56
stratosphere/ro/source/ro_ro_service.hpp
Normal file
56
stratosphere/ro/source/ro_ro_service.hpp
Normal file
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2020 Atmosphère-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include <stratosphere.hpp>
|
||||
|
||||
namespace ams::ro {
|
||||
|
||||
/* Access utilities. */
|
||||
void SetDevelopmentHardware(bool is_development_hardware);
|
||||
void SetDevelopmentFunctionEnabled(bool is_development_function_enabled);
|
||||
|
||||
class RoService {
|
||||
private:
|
||||
size_t context_id;
|
||||
ModuleType type;
|
||||
protected:
|
||||
explicit RoService(ModuleType t);
|
||||
public:
|
||||
virtual ~RoService();
|
||||
public:
|
||||
/* Actual commands. */
|
||||
Result MapManualLoadModuleMemory(sf::Out<u64> out_load_address, const sf::ClientProcessId &client_pid, u64 nro_address, u64 nro_size, u64 bss_address, u64 bss_size);
|
||||
Result UnmapManualLoadModuleMemory(const sf::ClientProcessId &client_pid, u64 nro_address);
|
||||
Result RegisterModuleInfo(const sf::ClientProcessId &client_pid, u64 nrr_address, u64 nrr_size);
|
||||
Result UnregisterModuleInfo(const sf::ClientProcessId &client_pid, u64 nrr_address);
|
||||
Result RegisterProcessHandle(const sf::ClientProcessId &client_pid, sf::CopyHandle process_h);
|
||||
Result RegisterModuleInfoEx(const sf::ClientProcessId &client_pid, u64 nrr_address, u64 nrr_size, sf::CopyHandle process_h);
|
||||
};
|
||||
static_assert(ro::impl::IsIRoInterface<RoService>);
|
||||
|
||||
class RoServiceForSelf final : public RoService {
|
||||
public:
|
||||
RoServiceForSelf() : RoService(ro::ModuleType::ForSelf) { /* ... */ }
|
||||
};
|
||||
|
||||
/* TODO: This is really JitPlugin... */
|
||||
class RoServiceForOthers final : public RoService {
|
||||
public:
|
||||
RoServiceForOthers() : RoService(ro::ModuleType::ForOthers) { /* ... */ }
|
||||
};
|
||||
|
||||
}
|
||||
@@ -1,67 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2020 Atmosphère-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include <stratosphere.hpp>
|
||||
#include "ro_service.hpp"
|
||||
#include "impl/ro_service_impl.hpp"
|
||||
|
||||
namespace ams::ro {
|
||||
|
||||
void SetDevelopmentHardware(bool is_development_hardware) {
|
||||
impl::SetDevelopmentHardware(is_development_hardware);
|
||||
}
|
||||
|
||||
void SetDevelopmentFunctionEnabled(bool is_development_function_enabled) {
|
||||
impl::SetDevelopmentFunctionEnabled(is_development_function_enabled);
|
||||
}
|
||||
|
||||
Service::Service(ModuleType t) : context_id(impl::InvalidContextId), type(t) {
|
||||
/* ... */
|
||||
}
|
||||
|
||||
Service::~Service() {
|
||||
impl::UnregisterProcess(this->context_id);
|
||||
}
|
||||
|
||||
Result Service::LoadNro(sf::Out<u64> load_address, const sf::ClientProcessId &client_pid, u64 nro_address, u64 nro_size, u64 bss_address, u64 bss_size) {
|
||||
R_TRY(impl::ValidateProcess(this->context_id, client_pid.GetValue()));
|
||||
return impl::LoadNro(load_address.GetPointer(), this->context_id, nro_address, nro_size, bss_address, bss_size);
|
||||
}
|
||||
|
||||
Result Service::UnloadNro(const sf::ClientProcessId &client_pid, u64 nro_address) {
|
||||
R_TRY(impl::ValidateProcess(this->context_id, client_pid.GetValue()));
|
||||
return impl::UnloadNro(this->context_id, nro_address);
|
||||
}
|
||||
|
||||
Result Service::LoadNrr(const sf::ClientProcessId &client_pid, u64 nrr_address, u64 nrr_size) {
|
||||
R_TRY(impl::ValidateProcess(this->context_id, client_pid.GetValue()));
|
||||
return impl::LoadNrr(this->context_id, INVALID_HANDLE, nrr_address, nrr_size, ModuleType::ForSelf, true);
|
||||
}
|
||||
|
||||
Result Service::UnloadNrr(const sf::ClientProcessId &client_pid, u64 nrr_address) {
|
||||
R_TRY(impl::ValidateProcess(this->context_id, client_pid.GetValue()));
|
||||
return impl::UnloadNrr(this->context_id, nrr_address);
|
||||
}
|
||||
|
||||
Result Service::Initialize(const sf::ClientProcessId &client_pid, sf::CopyHandle process_h) {
|
||||
return impl::RegisterProcess(&this->context_id, process_h.GetValue(), client_pid.GetValue());
|
||||
}
|
||||
|
||||
Result Service::LoadNrrEx(const sf::ClientProcessId &client_pid, u64 nrr_address, u64 nrr_size, sf::CopyHandle process_h) {
|
||||
R_TRY(impl::ValidateProcess(this->context_id, client_pid.GetValue()));
|
||||
return impl::LoadNrr(this->context_id, process_h.GetValue(), nrr_address, nrr_size, this->type, this->type == ModuleType::ForOthers);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,62 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2020 Atmosphère-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include <stratosphere.hpp>
|
||||
|
||||
namespace ams::ro {
|
||||
|
||||
/* Access utilities. */
|
||||
void SetDevelopmentHardware(bool is_development_hardware);
|
||||
void SetDevelopmentFunctionEnabled(bool is_development_function_enabled);
|
||||
|
||||
class Service final : public sf::IServiceObject {
|
||||
protected:
|
||||
enum class CommandId {
|
||||
LoadNro = 0,
|
||||
UnloadNro = 1,
|
||||
LoadNrr = 2,
|
||||
UnloadNrr = 3,
|
||||
Initialize = 4,
|
||||
LoadNrrEx = 10,
|
||||
};
|
||||
private:
|
||||
size_t context_id;
|
||||
ModuleType type;
|
||||
public:
|
||||
explicit Service(ModuleType t);
|
||||
virtual ~Service();
|
||||
private:
|
||||
/* Actual commands. */
|
||||
Result LoadNro(sf::Out<u64> out_load_address, const sf::ClientProcessId &client_pid, u64 nro_address, u64 nro_size, u64 bss_address, u64 bss_size);
|
||||
Result UnloadNro(const sf::ClientProcessId &client_pid, u64 nro_address);
|
||||
Result LoadNrr(const sf::ClientProcessId &client_pid, u64 nrr_address, u64 nrr_size);
|
||||
Result UnloadNrr(const sf::ClientProcessId &client_pid, u64 nrr_address);
|
||||
Result Initialize(const sf::ClientProcessId &client_pid, sf::CopyHandle process_h);
|
||||
Result LoadNrrEx(const sf::ClientProcessId &client_pid, u64 nrr_address, u64 nrr_size, sf::CopyHandle process_h);
|
||||
public:
|
||||
DEFINE_SERVICE_DISPATCH_TABLE {
|
||||
MAKE_SERVICE_COMMAND_META(LoadNro),
|
||||
MAKE_SERVICE_COMMAND_META(UnloadNro),
|
||||
MAKE_SERVICE_COMMAND_META(LoadNrr),
|
||||
MAKE_SERVICE_COMMAND_META(UnloadNrr),
|
||||
MAKE_SERVICE_COMMAND_META(Initialize),
|
||||
MAKE_SERVICE_COMMAND_META(LoadNrrEx, hos::Version_7_0_0),
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
@@ -14,20 +14,20 @@
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include <stratosphere.hpp>
|
||||
#include "sm_dmnt_service.hpp"
|
||||
#include "sm_debug_monitor_service.hpp"
|
||||
#include "impl/sm_service_manager.hpp"
|
||||
|
||||
namespace ams::sm {
|
||||
|
||||
Result DmntService::AtmosphereGetRecord(sf::Out<ServiceRecord> record, ServiceName service) {
|
||||
Result DebugMonitorService::AtmosphereGetRecord(sf::Out<ServiceRecord> record, ServiceName service) {
|
||||
return impl::GetServiceRecord(record.GetPointer(), service);
|
||||
}
|
||||
|
||||
void DmntService::AtmosphereListRecords(const sf::OutArray<ServiceRecord> &records, sf::Out<u64> out_count, u64 offset) {
|
||||
void DebugMonitorService::AtmosphereListRecords(const sf::OutArray<ServiceRecord> &records, sf::Out<u64> out_count, u64 offset) {
|
||||
R_ABORT_UNLESS(impl::ListServiceRecords(records.GetPointer(), out_count.GetPointer(), offset, records.GetSize()));
|
||||
}
|
||||
|
||||
void DmntService::AtmosphereGetRecordSize(sf::Out<u64> record_size) {
|
||||
void DebugMonitorService::AtmosphereGetRecordSize(sf::Out<u64> record_size) {
|
||||
record_size.SetValue(sizeof(ServiceRecord));
|
||||
}
|
||||
|
||||
31
stratosphere/sm/source/sm_debug_monitor_service.hpp
Normal file
31
stratosphere/sm/source/sm_debug_monitor_service.hpp
Normal file
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2020 Atmosphère-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include <stratosphere.hpp>
|
||||
|
||||
namespace ams::sm {
|
||||
|
||||
/* Service definition. */
|
||||
class DebugMonitorService final {
|
||||
public:
|
||||
Result AtmosphereGetRecord(sf::Out<ServiceRecord> record, ServiceName service);
|
||||
void AtmosphereListRecords(const sf::OutArray<ServiceRecord> &records, sf::Out<u64> out_count, u64 offset);
|
||||
void AtmosphereGetRecordSize(sf::Out<u64> record_size);
|
||||
};
|
||||
static_assert(sm::impl::IsIDebugMonitorInterface<DebugMonitorService>);
|
||||
|
||||
}
|
||||
@@ -1,44 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2020 Atmosphère-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include <stratosphere.hpp>
|
||||
|
||||
namespace ams::sm {
|
||||
|
||||
/* Service definition. */
|
||||
class DmntService final : public sf::IServiceObject {
|
||||
protected:
|
||||
/* Command IDs. */
|
||||
enum class CommandId {
|
||||
AtmosphereGetRecord = 65000,
|
||||
AtmosphereListRecords = 65001,
|
||||
AtmosphereGetRecordSize = 65002,
|
||||
};
|
||||
private:
|
||||
/* Actual commands. */
|
||||
virtual Result AtmosphereGetRecord(sf::Out<ServiceRecord> record, ServiceName service);
|
||||
virtual void AtmosphereListRecords(const sf::OutArray<ServiceRecord> &records, sf::Out<u64> out_count, u64 offset);
|
||||
virtual void AtmosphereGetRecordSize(sf::Out<u64> record_size);
|
||||
public:
|
||||
DEFINE_SERVICE_DISPATCH_TABLE {
|
||||
MAKE_SERVICE_COMMAND_META(AtmosphereGetRecord),
|
||||
MAKE_SERVICE_COMMAND_META(AtmosphereListRecords),
|
||||
MAKE_SERVICE_COMMAND_META(AtmosphereGetRecordSize),
|
||||
};
|
||||
};
|
||||
|
||||
}
|
||||
@@ -16,7 +16,7 @@
|
||||
#include <stratosphere.hpp>
|
||||
#include "sm_user_service.hpp"
|
||||
#include "sm_manager_service.hpp"
|
||||
#include "sm_dmnt_service.hpp"
|
||||
#include "sm_debug_monitor_service.hpp"
|
||||
#include "impl/sm_service_manager.hpp"
|
||||
|
||||
extern "C" {
|
||||
@@ -101,14 +101,14 @@ int main(int argc, char **argv)
|
||||
{
|
||||
Handle sm_h;
|
||||
R_ABORT_UNLESS(svcManageNamedPort(&sm_h, "sm:", 0x40));
|
||||
g_server_manager.RegisterServer<sm::UserService>(sm_h);
|
||||
g_server_manager.RegisterServer<sm::impl::IUserInterface, sm::UserService>(sm_h);
|
||||
}
|
||||
|
||||
/* Create sm:m manually. */
|
||||
{
|
||||
Handle smm_h;
|
||||
R_ABORT_UNLESS(sm::impl::RegisterServiceForSelf(&smm_h, sm::ServiceName::Encode("sm:m"), 1));
|
||||
g_server_manager.RegisterServer<sm::ManagerService>(smm_h);
|
||||
g_server_manager.RegisterServer<sm::impl::IManagerInterface, sm::ManagerService>(smm_h);
|
||||
}
|
||||
|
||||
/*===== ATMOSPHERE EXTENSION =====*/
|
||||
@@ -116,7 +116,7 @@ int main(int argc, char **argv)
|
||||
{
|
||||
Handle smdmnt_h;
|
||||
R_ABORT_UNLESS(sm::impl::RegisterServiceForSelf(&smdmnt_h, sm::ServiceName::Encode("sm:dmnt"), 1));
|
||||
g_server_manager.RegisterServer<sm::DmntService>(smdmnt_h);
|
||||
g_server_manager.RegisterServer<sm::impl::IDebugMonitorInterface, sm::DebugMonitorService>(smdmnt_h);
|
||||
}
|
||||
|
||||
/*================================*/
|
||||
|
||||
@@ -19,33 +19,14 @@
|
||||
namespace ams::sm {
|
||||
|
||||
/* Service definition. */
|
||||
class ManagerService final : public sf::IServiceObject {
|
||||
protected:
|
||||
/* Command IDs. */
|
||||
enum class CommandId {
|
||||
RegisterProcess = 0,
|
||||
UnregisterProcess = 1,
|
||||
|
||||
AtmosphereEndInitDefers = 65000,
|
||||
AtmosphereHasMitm = 65001,
|
||||
AtmosphereRegisterProcess = 65002,
|
||||
};
|
||||
private:
|
||||
/* Actual commands. */
|
||||
virtual Result RegisterProcess(os::ProcessId process_id, const sf::InBuffer &acid_sac, const sf::InBuffer &aci_sac);
|
||||
virtual Result UnregisterProcess(os::ProcessId process_id);
|
||||
virtual void AtmosphereEndInitDefers();
|
||||
virtual void AtmosphereHasMitm(sf::Out<bool> out, ServiceName service);
|
||||
virtual Result AtmosphereRegisterProcess(os::ProcessId process_id, ncm::ProgramId program_id, cfg::OverrideStatus override_status, const sf::InBuffer &acid_sac, const sf::InBuffer &aci_sac);
|
||||
class ManagerService final {
|
||||
public:
|
||||
DEFINE_SERVICE_DISPATCH_TABLE {
|
||||
MAKE_SERVICE_COMMAND_META(RegisterProcess),
|
||||
MAKE_SERVICE_COMMAND_META(UnregisterProcess),
|
||||
|
||||
MAKE_SERVICE_COMMAND_META(AtmosphereEndInitDefers),
|
||||
MAKE_SERVICE_COMMAND_META(AtmosphereHasMitm),
|
||||
MAKE_SERVICE_COMMAND_META(AtmosphereRegisterProcess),
|
||||
};
|
||||
Result RegisterProcess(os::ProcessId process_id, const sf::InBuffer &acid_sac, const sf::InBuffer &aci_sac);
|
||||
Result UnregisterProcess(os::ProcessId process_id);
|
||||
void AtmosphereEndInitDefers();
|
||||
void AtmosphereHasMitm(sf::Out<bool> out, ServiceName service);
|
||||
Result AtmosphereRegisterProcess(os::ProcessId process_id, ncm::ProgramId program_id, cfg::OverrideStatus override_status, const sf::InBuffer &acid_sac, const sf::InBuffer &aci_sac);
|
||||
};
|
||||
static_assert(sm::impl::IsIManagerInterface<ManagerService>);
|
||||
|
||||
}
|
||||
|
||||
@@ -19,20 +19,18 @@
|
||||
|
||||
namespace ams::sm {
|
||||
|
||||
Result UserService::Initialize(const sf::ClientProcessId &client_process_id) {
|
||||
Result UserService::RegisterClient(const sf::ClientProcessId &client_process_id) {
|
||||
this->process_id = client_process_id.GetValue();
|
||||
this->has_initialized = true;
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
Result UserService::EnsureInitialized() {
|
||||
if (!this->has_initialized) {
|
||||
return sm::ResultInvalidClient();
|
||||
}
|
||||
R_UNLESS(this->has_initialized, sm::ResultInvalidClient());
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
Result UserService::GetService(sf::OutMoveHandle out_h, ServiceName service) {
|
||||
Result UserService::GetServiceHandle(sf::OutMoveHandle out_h, ServiceName service) {
|
||||
R_TRY(this->EnsureInitialized());
|
||||
return impl::GetServiceHandle(out_h.GetHandlePointer(), this->process_id, service);
|
||||
}
|
||||
|
||||
@@ -20,26 +20,7 @@
|
||||
namespace ams::sm {
|
||||
|
||||
/* Service definition. */
|
||||
class UserService final : public sf::IServiceObject {
|
||||
protected:
|
||||
/* Command IDs. */
|
||||
enum class CommandId {
|
||||
Initialize = 0,
|
||||
GetService = 1,
|
||||
RegisterService = 2,
|
||||
UnregisterService = 3,
|
||||
|
||||
AtmosphereInstallMitm = 65000,
|
||||
AtmosphereUninstallMitm = 65001,
|
||||
/* Deprecated: AtmosphereAssociatePidTidForMitm = 65002 */
|
||||
AtmosphereAcknowledgeMitmSession = 65003,
|
||||
AtmosphereHasMitm = 65004,
|
||||
AtmosphereWaitMitm = 65005,
|
||||
AtmosphereDeclareFutureMitm = 65006,
|
||||
|
||||
AtmosphereHasService = 65100,
|
||||
AtmosphereWaitService = 65101,
|
||||
};
|
||||
class UserService final {
|
||||
private:
|
||||
os::ProcessId process_id = os::InvalidProcessId;
|
||||
bool has_initialized = false;
|
||||
@@ -47,38 +28,22 @@ namespace ams::sm {
|
||||
Result EnsureInitialized();
|
||||
public:
|
||||
/* Official commands. */
|
||||
virtual Result Initialize(const sf::ClientProcessId &client_process_id);
|
||||
virtual Result GetService(sf::OutMoveHandle out_h, ServiceName service);
|
||||
virtual Result RegisterService(sf::OutMoveHandle out_h, ServiceName service, u32 max_sessions, bool is_light);
|
||||
virtual Result UnregisterService(ServiceName service);
|
||||
Result RegisterClient(const sf::ClientProcessId &client_process_id);
|
||||
Result GetServiceHandle(sf::OutMoveHandle out_h, ServiceName service);
|
||||
Result RegisterService(sf::OutMoveHandle out_h, ServiceName service, u32 max_sessions, bool is_light);
|
||||
Result UnregisterService(ServiceName service);
|
||||
|
||||
/* Atmosphere commands. */
|
||||
virtual Result AtmosphereInstallMitm(sf::OutMoveHandle srv_h, sf::OutMoveHandle qry_h, ServiceName service);
|
||||
virtual Result AtmosphereUninstallMitm(ServiceName service);
|
||||
virtual Result AtmosphereAcknowledgeMitmSession(sf::Out<MitmProcessInfo> client_info, sf::OutMoveHandle fwd_h, ServiceName service);
|
||||
virtual Result AtmosphereHasMitm(sf::Out<bool> out, ServiceName service);
|
||||
virtual Result AtmosphereWaitMitm(ServiceName service);
|
||||
virtual Result AtmosphereDeclareFutureMitm(ServiceName service);
|
||||
Result AtmosphereInstallMitm(sf::OutMoveHandle srv_h, sf::OutMoveHandle qry_h, ServiceName service);
|
||||
Result AtmosphereUninstallMitm(ServiceName service);
|
||||
Result AtmosphereAcknowledgeMitmSession(sf::Out<MitmProcessInfo> client_info, sf::OutMoveHandle fwd_h, ServiceName service);
|
||||
Result AtmosphereHasMitm(sf::Out<bool> out, ServiceName service);
|
||||
Result AtmosphereWaitMitm(ServiceName service);
|
||||
Result AtmosphereDeclareFutureMitm(ServiceName service);
|
||||
|
||||
virtual Result AtmosphereHasService(sf::Out<bool> out, ServiceName service);
|
||||
virtual Result AtmosphereWaitService(ServiceName service);
|
||||
public:
|
||||
DEFINE_SERVICE_DISPATCH_TABLE {
|
||||
MAKE_SERVICE_COMMAND_META(Initialize),
|
||||
MAKE_SERVICE_COMMAND_META(GetService),
|
||||
MAKE_SERVICE_COMMAND_META(RegisterService),
|
||||
MAKE_SERVICE_COMMAND_META(UnregisterService),
|
||||
|
||||
MAKE_SERVICE_COMMAND_META(AtmosphereInstallMitm),
|
||||
MAKE_SERVICE_COMMAND_META(AtmosphereUninstallMitm),
|
||||
MAKE_SERVICE_COMMAND_META(AtmosphereAcknowledgeMitmSession),
|
||||
MAKE_SERVICE_COMMAND_META(AtmosphereHasMitm),
|
||||
MAKE_SERVICE_COMMAND_META(AtmosphereWaitMitm),
|
||||
MAKE_SERVICE_COMMAND_META(AtmosphereDeclareFutureMitm),
|
||||
|
||||
MAKE_SERVICE_COMMAND_META(AtmosphereHasService),
|
||||
MAKE_SERVICE_COMMAND_META(AtmosphereWaitService),
|
||||
};
|
||||
Result AtmosphereHasService(sf::Out<bool> out, ServiceName service);
|
||||
Result AtmosphereWaitService(ServiceName service);
|
||||
};
|
||||
static_assert(sm::impl::IsIUserInterface<UserService>);
|
||||
|
||||
}
|
||||
|
||||
@@ -24,39 +24,39 @@ namespace ams::spl::impl {
|
||||
|
||||
/* Convenient defines. */
|
||||
constexpr size_t DeviceAddressSpaceAlign = 0x400000;
|
||||
constexpr u32 WorkBufferMapBase = 0x80000000u;
|
||||
constexpr u32 CryptAesInMapBase = 0x90000000u;
|
||||
constexpr u32 CryptAesOutMapBase = 0xC0000000u;
|
||||
constexpr size_t CryptAesSizeMax = static_cast<size_t>(CryptAesOutMapBase - CryptAesInMapBase);
|
||||
constexpr u32 WorkBufferMapBase = 0x80000000u;
|
||||
constexpr u32 ComputeAesInMapBase = 0x90000000u;
|
||||
constexpr u32 ComputeAesOutMapBase = 0xC0000000u;
|
||||
constexpr size_t ComputeAesSizeMax = static_cast<size_t>(ComputeAesOutMapBase - ComputeAesInMapBase);
|
||||
|
||||
constexpr size_t RsaPrivateKeySize = 0x100;
|
||||
constexpr size_t RsaPrivateKeyMetaSize = 0x30;
|
||||
constexpr size_t DeviceUniqueDataMetaSize = 0x30;
|
||||
constexpr size_t LabelDigestSizeMax = 0x20;
|
||||
|
||||
constexpr size_t WorkBufferSizeMax = 0x800;
|
||||
|
||||
constexpr s32 MaxPhysicalAesKeyslots = 6;
|
||||
constexpr s32 MaxPhysicalAesKeyslotsDeprecated = 4;
|
||||
constexpr s32 MaxPhysicalAesKeySlots = 6;
|
||||
constexpr s32 MaxPhysicalAesKeySlotsDeprecated = 4;
|
||||
|
||||
constexpr s32 MaxVirtualAesKeyslots = 9;
|
||||
constexpr s32 MaxVirtualAesKeySlots = 9;
|
||||
|
||||
/* Keyslot management. */
|
||||
/* KeySlot management. */
|
||||
KeySlotCache g_keyslot_cache;
|
||||
std::optional<KeySlotCacheEntry> g_keyslot_cache_entry[MaxPhysicalAesKeyslots];
|
||||
std::optional<KeySlotCacheEntry> g_keyslot_cache_entry[MaxPhysicalAesKeySlots];
|
||||
|
||||
inline s32 GetMaxPhysicalKeyslots() {
|
||||
return (hos::GetVersion() >= hos::Version_6_0_0) ? MaxPhysicalAesKeyslots : MaxPhysicalAesKeyslotsDeprecated;
|
||||
inline s32 GetMaxPhysicalKeySlots() {
|
||||
return (hos::GetVersion() >= hos::Version_6_0_0) ? MaxPhysicalAesKeySlots : MaxPhysicalAesKeySlotsDeprecated;
|
||||
}
|
||||
|
||||
constexpr s32 VirtualKeySlotMin = 16;
|
||||
constexpr s32 VirtualKeySlotMax = VirtualKeySlotMin + MaxVirtualAesKeyslots - 1;
|
||||
constexpr s32 VirtualKeySlotMax = VirtualKeySlotMin + MaxVirtualAesKeySlots - 1;
|
||||
|
||||
constexpr inline bool IsVirtualKeySlot(s32 keyslot) {
|
||||
return VirtualKeySlotMin <= keyslot && keyslot <= VirtualKeySlotMax;
|
||||
}
|
||||
|
||||
inline bool IsPhysicalKeySlot(s32 keyslot) {
|
||||
return keyslot < GetMaxPhysicalKeyslots();
|
||||
return keyslot < GetMaxPhysicalKeySlots();
|
||||
}
|
||||
|
||||
constexpr inline s32 GetVirtualKeySlotIndex(s32 keyslot) {
|
||||
@@ -71,16 +71,16 @@ namespace ams::spl::impl {
|
||||
}
|
||||
|
||||
void InitializeKeySlotCache() {
|
||||
for (s32 i = 0; i < MaxPhysicalAesKeyslots; i++) {
|
||||
for (s32 i = 0; i < MaxPhysicalAesKeySlots; i++) {
|
||||
g_keyslot_cache_entry[i].emplace(i);
|
||||
g_keyslot_cache.AddEntry(std::addressof(g_keyslot_cache_entry[i].value()));
|
||||
}
|
||||
}
|
||||
|
||||
enum class KeySlotContentType {
|
||||
None = 0,
|
||||
AesKey = 1,
|
||||
TitleKey = 2,
|
||||
None = 0,
|
||||
AesKey = 1,
|
||||
PreparedKey = 2,
|
||||
};
|
||||
|
||||
struct KeySlotContents {
|
||||
@@ -92,15 +92,15 @@ namespace ams::spl::impl {
|
||||
} aes_key;
|
||||
struct {
|
||||
AccessKey access_key;
|
||||
} title_key;
|
||||
} prepared_key;
|
||||
};
|
||||
};
|
||||
|
||||
const void *g_keyslot_owners[MaxVirtualAesKeyslots];
|
||||
KeySlotContents g_keyslot_contents[MaxVirtualAesKeyslots];
|
||||
KeySlotContents g_physical_keyslot_contents_for_backwards_compatibility[MaxPhysicalAesKeyslots];
|
||||
const void *g_keyslot_owners[MaxVirtualAesKeySlots];
|
||||
KeySlotContents g_keyslot_contents[MaxVirtualAesKeySlots];
|
||||
KeySlotContents g_physical_keyslot_contents_for_backwards_compatibility[MaxPhysicalAesKeySlots];
|
||||
|
||||
void ClearPhysicalKeyslot(s32 keyslot) {
|
||||
void ClearPhysicalKeySlot(s32 keyslot) {
|
||||
AMS_ASSERT(IsPhysicalKeySlot(keyslot));
|
||||
|
||||
AccessKey access_key = {};
|
||||
@@ -139,13 +139,13 @@ namespace ams::spl::impl {
|
||||
if (load) {
|
||||
switch (contents->type) {
|
||||
case KeySlotContentType::None:
|
||||
ClearPhysicalKeyslot(phys_slot);
|
||||
ClearPhysicalKeySlot(phys_slot);
|
||||
break;
|
||||
case KeySlotContentType::AesKey:
|
||||
R_ABORT_UNLESS(smc::ConvertResult(smc::LoadAesKey(phys_slot, contents->aes_key.access_key, contents->aes_key.key_source)));
|
||||
break;
|
||||
case KeySlotContentType::TitleKey:
|
||||
R_ABORT_UNLESS(smc::ConvertResult(smc::LoadTitleKey(phys_slot, contents->title_key.access_key)));
|
||||
case KeySlotContentType::PreparedKey:
|
||||
R_ABORT_UNLESS(smc::ConvertResult(smc::LoadPreparedAesKey(phys_slot, contents->prepared_key.access_key)));
|
||||
break;
|
||||
AMS_UNREACHABLE_DEFAULT_CASE();
|
||||
}
|
||||
@@ -169,32 +169,32 @@ namespace ams::spl::impl {
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
Result LoadVirtualTitleKey(s32 keyslot, const AccessKey &access_key) {
|
||||
Result LoadVirtualPreparedAesKey(s32 keyslot, const AccessKey &access_key) {
|
||||
/* Ensure we can load into the slot. */
|
||||
const s32 phys_slot = GetPhysicalKeySlot(keyslot, false);
|
||||
R_TRY(smc::ConvertResult(smc::LoadTitleKey(phys_slot, access_key)));
|
||||
R_TRY(smc::ConvertResult(smc::LoadPreparedAesKey(phys_slot, access_key)));
|
||||
|
||||
/* Update our contents. */
|
||||
const s32 index = GetVirtualKeySlotIndex(keyslot);
|
||||
|
||||
g_keyslot_contents[index].type = KeySlotContentType::TitleKey;
|
||||
g_keyslot_contents[index].title_key.access_key = access_key;
|
||||
g_keyslot_contents[index].type = KeySlotContentType::PreparedKey;
|
||||
g_keyslot_contents[index].prepared_key.access_key = access_key;
|
||||
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
/* Type definitions. */
|
||||
class ScopedAesKeyslot {
|
||||
class ScopedAesKeySlot {
|
||||
private:
|
||||
s32 slot;
|
||||
bool has_slot;
|
||||
public:
|
||||
ScopedAesKeyslot() : slot(-1), has_slot(false) {
|
||||
ScopedAesKeySlot() : slot(-1), has_slot(false) {
|
||||
/* ... */
|
||||
}
|
||||
~ScopedAesKeyslot() {
|
||||
~ScopedAesKeySlot() {
|
||||
if (this->has_slot) {
|
||||
FreeAesKeyslot(slot, this);
|
||||
DeallocateAesKeySlot(slot, this);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -203,7 +203,7 @@ namespace ams::spl::impl {
|
||||
}
|
||||
|
||||
Result Allocate() {
|
||||
R_TRY(AllocateAesKeyslot(&this->slot, this));
|
||||
R_TRY(AllocateAesKeySlot(&this->slot, this));
|
||||
this->has_slot = true;
|
||||
return ResultSuccess();
|
||||
}
|
||||
@@ -269,7 +269,7 @@ namespace ams::spl::impl {
|
||||
|
||||
void InitializeSeEvents() {
|
||||
u64 irq_num;
|
||||
AMS_ABORT_UNLESS(smc::GetConfig(&irq_num, 1, SplConfigItem_SecurityEngineIrqNumber) == smc::Result::Success);
|
||||
AMS_ABORT_UNLESS(smc::GetConfig(&irq_num, 1, ConfigItem::SecurityEngineInterruptNumber) == smc::Result::Success);
|
||||
os::InitializeInterruptEvent(std::addressof(g_se_event), irq_num, os::EventClearMode_AutoClear);
|
||||
|
||||
R_ABORT_UNLESS(os::CreateSystemEvent(std::addressof(g_se_keyslot_available_event), os::EventClearMode_AutoClear, true));
|
||||
@@ -320,7 +320,7 @@ namespace ams::spl::impl {
|
||||
WaitSeOperationComplete();
|
||||
|
||||
smc::Result op_res;
|
||||
smc::Result res = smc::CheckStatus(&op_res, op_key);
|
||||
smc::Result res = smc::GetResult(&op_res, op_key);
|
||||
if (res != smc::Result::Success) {
|
||||
return res;
|
||||
}
|
||||
@@ -332,7 +332,7 @@ namespace ams::spl::impl {
|
||||
WaitSeOperationComplete();
|
||||
|
||||
smc::Result op_res;
|
||||
smc::Result res = smc::GetResult(&op_res, out_buf, out_buf_size, op_key);
|
||||
smc::Result res = smc::GetResultData(&op_res, out_buf, out_buf_size, op_key);
|
||||
if (res != smc::Result::Success) {
|
||||
return res;
|
||||
}
|
||||
@@ -340,17 +340,17 @@ namespace ams::spl::impl {
|
||||
return op_res;
|
||||
}
|
||||
|
||||
/* Internal Keyslot utility. */
|
||||
Result ValidateAesKeyslot(s32 keyslot, const void *owner) {
|
||||
/* Internal KeySlot utility. */
|
||||
Result ValidateAesKeySlot(s32 keyslot, const void *owner) {
|
||||
/* Allow the use of physical keyslots on 1.0.0. */
|
||||
if (hos::GetVersion() == hos::Version_1_0_0) {
|
||||
R_SUCCEED_IF(IsPhysicalKeySlot(keyslot));
|
||||
}
|
||||
|
||||
R_UNLESS(IsVirtualKeySlot(keyslot), spl::ResultInvalidKeyslot());
|
||||
R_UNLESS(IsVirtualKeySlot(keyslot), spl::ResultInvalidKeySlot());
|
||||
|
||||
const s32 index = GetVirtualKeySlotIndex(keyslot);
|
||||
R_UNLESS(g_keyslot_owners[index] == owner, spl::ResultInvalidKeyslot());
|
||||
R_UNLESS(g_keyslot_owners[index] == owner, spl::ResultInvalidKeySlot());
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
@@ -377,11 +377,11 @@ namespace ams::spl::impl {
|
||||
std::scoped_lock lk(g_async_op_lock);
|
||||
smc::AsyncOperationKey op_key;
|
||||
const IvCtr iv_ctr = {};
|
||||
const u32 mode = smc::GetCryptAesMode(smc::CipherMode::CbcDecrypt, GetPhysicalKeySlot(keyslot, true));
|
||||
const u32 mode = smc::GetComputeAesMode(smc::CipherMode::CbcDecrypt, GetPhysicalKeySlot(keyslot, true));
|
||||
const u32 dst_ll_addr = g_se_mapped_work_buffer_addr + offsetof(DecryptAesBlockLayout, crypt_ctx.out);
|
||||
const u32 src_ll_addr = g_se_mapped_work_buffer_addr + offsetof(DecryptAesBlockLayout, crypt_ctx.in);
|
||||
|
||||
smc::Result res = smc::CryptAes(&op_key, mode, iv_ctr, dst_ll_addr, src_ll_addr, sizeof(layout->in_block));
|
||||
smc::Result res = smc::ComputeAes(&op_key, mode, iv_ctr, dst_ll_addr, src_ll_addr, sizeof(layout->in_block));
|
||||
if (res != smc::Result::Success) {
|
||||
return res;
|
||||
}
|
||||
@@ -397,33 +397,33 @@ namespace ams::spl::impl {
|
||||
}
|
||||
|
||||
/* Implementation wrappers for API commands. */
|
||||
Result ImportSecureExpModKey(const void *src, size_t src_size, const AccessKey &access_key, const KeySource &key_source, u32 option) {
|
||||
struct ImportSecureExpModKeyLayout {
|
||||
u8 data[RsaPrivateKeyMetaSize + 2 * RsaPrivateKeySize + 0x10];
|
||||
Result DecryptAndStoreDeviceUniqueKey(const void *src, size_t src_size, const AccessKey &access_key, const KeySource &key_source, u32 option) {
|
||||
struct DecryptAndStoreDeviceUniqueKeyLayout {
|
||||
u8 data[DeviceUniqueDataMetaSize + 2 * RsaPrivateKeySize + 0x10];
|
||||
};
|
||||
ImportSecureExpModKeyLayout *layout = reinterpret_cast<ImportSecureExpModKeyLayout *>(g_work_buffer);
|
||||
DecryptAndStoreDeviceUniqueKeyLayout *layout = reinterpret_cast<DecryptAndStoreDeviceUniqueKeyLayout *>(g_work_buffer);
|
||||
|
||||
/* Validate size. */
|
||||
R_UNLESS(src_size <= sizeof(ImportSecureExpModKeyLayout), spl::ResultInvalidSize());
|
||||
R_UNLESS(src_size <= sizeof(DecryptAndStoreDeviceUniqueKeyLayout), spl::ResultInvalidSize());
|
||||
std::memcpy(layout, src, src_size);
|
||||
|
||||
armDCacheFlush(layout, sizeof(*layout));
|
||||
smc::Result smc_res;
|
||||
if (hos::GetVersion() >= hos::Version_5_0_0) {
|
||||
smc_res = smc::DecryptOrImportRsaPrivateKey(layout->data, src_size, access_key, key_source, static_cast<smc::DecryptOrImportMode>(option));
|
||||
smc_res = smc::DecryptDeviceUniqueData(layout->data, src_size, access_key, key_source, static_cast<smc::DeviceUniqueDataMode>(option));
|
||||
} else {
|
||||
smc_res = smc::ImportSecureExpModKey(layout->data, src_size, access_key, key_source, option);
|
||||
smc_res = smc::DecryptAndStoreGcKey(layout->data, src_size, access_key, key_source, option);
|
||||
}
|
||||
|
||||
return smc::ConvertResult(smc_res);
|
||||
}
|
||||
|
||||
Result SecureExpMod(void *out, size_t out_size, const void *base, size_t base_size, const void *mod, size_t mod_size, smc::SecureExpModMode mode) {
|
||||
struct SecureExpModLayout {
|
||||
Result ModularExponentiateWithStorageKey(void *out, size_t out_size, const void *base, size_t base_size, const void *mod, size_t mod_size, smc::ModularExponentiateWithStorageKeyMode mode) {
|
||||
struct ModularExponentiateWithStorageKeyLayout {
|
||||
u8 base[0x100];
|
||||
u8 mod[0x100];
|
||||
};
|
||||
SecureExpModLayout *layout = reinterpret_cast<SecureExpModLayout *>(g_work_buffer);
|
||||
ModularExponentiateWithStorageKeyLayout *layout = reinterpret_cast<ModularExponentiateWithStorageKeyLayout *>(g_work_buffer);
|
||||
|
||||
/* Validate sizes. */
|
||||
R_UNLESS(base_size <= sizeof(layout->base), spl::ResultInvalidSize());
|
||||
@@ -443,7 +443,7 @@ namespace ams::spl::impl {
|
||||
std::scoped_lock lk(g_async_op_lock);
|
||||
smc::AsyncOperationKey op_key;
|
||||
|
||||
smc::Result res = smc::SecureExpMod(&op_key, layout->base, layout->mod, mode);
|
||||
smc::Result res = smc::ModularExponentiateWithStorageKey(&op_key, layout->base, layout->mod, mode);
|
||||
if (res != smc::Result::Success) {
|
||||
return smc::ConvertResult(res);
|
||||
}
|
||||
@@ -458,12 +458,12 @@ namespace ams::spl::impl {
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
Result UnwrapEsRsaOaepWrappedKey(AccessKey *out_access_key, const void *base, size_t base_size, const void *mod, size_t mod_size, const void *label_digest, size_t label_digest_size, u32 generation, smc::EsKeyType type) {
|
||||
struct UnwrapEsKeyLayout {
|
||||
Result PrepareEsDeviceUniqueKey(AccessKey *out_access_key, const void *base, size_t base_size, const void *mod, size_t mod_size, const void *label_digest, size_t label_digest_size, u32 generation, smc::EsCommonKeyType type) {
|
||||
struct PrepareEsDeviceUniqueKeyLayout {
|
||||
u8 base[0x100];
|
||||
u8 mod[0x100];
|
||||
};
|
||||
UnwrapEsKeyLayout *layout = reinterpret_cast<UnwrapEsKeyLayout *>(g_work_buffer);
|
||||
PrepareEsDeviceUniqueKeyLayout *layout = reinterpret_cast<PrepareEsDeviceUniqueKeyLayout *>(g_work_buffer);
|
||||
|
||||
/* Validate sizes. */
|
||||
R_UNLESS(base_size <= sizeof(layout->base), spl::ResultInvalidSize());
|
||||
@@ -483,7 +483,7 @@ namespace ams::spl::impl {
|
||||
std::scoped_lock lk(g_async_op_lock);
|
||||
smc::AsyncOperationKey op_key;
|
||||
|
||||
smc::Result res = smc::UnwrapTitleKey(&op_key, layout->base, layout->mod, label_digest, label_digest_size, smc::GetUnwrapEsKeyOption(type, generation));
|
||||
smc::Result res = smc::PrepareEsDeviceUniqueKey(&op_key, layout->base, layout->mod, label_digest, label_digest_size, smc::GetPrepareEsDeviceUniqueKeyOption(type, generation));
|
||||
if (res != smc::Result::Success) {
|
||||
return smc::ConvertResult(res);
|
||||
}
|
||||
@@ -514,39 +514,45 @@ namespace ams::spl::impl {
|
||||
}
|
||||
|
||||
/* General. */
|
||||
Result GetConfig(u64 *out, SplConfigItem which) {
|
||||
Result GetConfig(u64 *out, ConfigItem which) {
|
||||
/* Nintendo explicitly blacklists package2 hash here, amusingly. */
|
||||
/* This is not blacklisted in safemode, but we're never in safe mode... */
|
||||
R_UNLESS(which != SplConfigItem_Package2Hash, spl::ResultInvalidArgument());
|
||||
R_UNLESS(which != ConfigItem::Package2Hash, spl::ResultInvalidArgument());
|
||||
|
||||
smc::Result res = smc::GetConfig(out, 1, which);
|
||||
|
||||
/* Nintendo has some special handling here for hardware type/is_retail. */
|
||||
if (which == SplConfigItem_HardwareType && res == smc::Result::InvalidArgument) {
|
||||
*out = 0;
|
||||
res = smc::Result::Success;
|
||||
}
|
||||
if (which == SplConfigItem_IsRetail && res == smc::Result::InvalidArgument) {
|
||||
*out = 0;
|
||||
res = smc::Result::Success;
|
||||
if (res == smc::Result::InvalidArgument) {
|
||||
switch (which) {
|
||||
case ConfigItem::HardwareType:
|
||||
*out = static_cast<u64>(HardwareType::Icosa);
|
||||
res = smc::Result::Success;
|
||||
break;
|
||||
case ConfigItem::HardwareState:
|
||||
*out = HardwareState_Development;
|
||||
res = smc::Result::Success;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return smc::ConvertResult(res);
|
||||
}
|
||||
|
||||
Result ExpMod(void *out, size_t out_size, const void *base, size_t base_size, const void *exp, size_t exp_size, const void *mod, size_t mod_size) {
|
||||
struct ExpModLayout {
|
||||
Result ModularExponentiate(void *out, size_t out_size, const void *base, size_t base_size, const void *exp, size_t exp_size, const void *mod, size_t mod_size) {
|
||||
struct ModularExponentiateLayout {
|
||||
u8 base[0x100];
|
||||
u8 exp[0x100];
|
||||
u8 mod[0x100];
|
||||
};
|
||||
ExpModLayout *layout = reinterpret_cast<ExpModLayout *>(g_work_buffer);
|
||||
ModularExponentiateLayout *layout = reinterpret_cast<ModularExponentiateLayout *>(g_work_buffer);
|
||||
|
||||
/* Validate sizes. */
|
||||
R_UNLESS(base_size <= sizeof(layout->base), spl::ResultInvalidSize());
|
||||
R_UNLESS(exp_size <= sizeof(layout->exp), spl::ResultInvalidSize());
|
||||
R_UNLESS(mod_size <= sizeof(layout->mod), spl::ResultInvalidSize());
|
||||
R_UNLESS(out_size <= WorkBufferSizeMax, spl::ResultInvalidSize());
|
||||
R_UNLESS(exp_size <= sizeof(layout->exp), spl::ResultInvalidSize());
|
||||
R_UNLESS(mod_size <= sizeof(layout->mod), spl::ResultInvalidSize());
|
||||
R_UNLESS(out_size <= WorkBufferSizeMax, spl::ResultInvalidSize());
|
||||
|
||||
/* Copy data into work buffer. */
|
||||
const size_t base_ofs = sizeof(layout->base) - base_size;
|
||||
@@ -562,7 +568,7 @@ namespace ams::spl::impl {
|
||||
std::scoped_lock lk(g_async_op_lock);
|
||||
smc::AsyncOperationKey op_key;
|
||||
|
||||
smc::Result res = smc::ExpMod(&op_key, layout->base, layout->exp, exp_size, layout->mod);
|
||||
smc::Result res = smc::ModularExponentiate(&op_key, layout->base, layout->exp, exp_size, layout->mod);
|
||||
if (res != smc::Result::Success) {
|
||||
return smc::ConvertResult(res);
|
||||
}
|
||||
@@ -577,7 +583,7 @@ namespace ams::spl::impl {
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
Result SetConfig(SplConfigItem which, u64 value) {
|
||||
Result SetConfig(ConfigItem which, u64 value) {
|
||||
return smc::ConvertResult(smc::SetConfig(which, &value, 1));
|
||||
}
|
||||
|
||||
@@ -595,10 +601,10 @@ namespace ams::spl::impl {
|
||||
}
|
||||
|
||||
Result IsDevelopment(bool *out) {
|
||||
u64 is_retail;
|
||||
R_TRY(GetConfig(&is_retail, SplConfigItem_IsRetail));
|
||||
u64 hardware_state;
|
||||
R_TRY(impl::GetConfig(&hardware_state, ConfigItem::HardwareState));
|
||||
|
||||
*out = (is_retail == 0);
|
||||
*out = (hardware_state == HardwareState_Development);
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
@@ -623,7 +629,7 @@ namespace ams::spl::impl {
|
||||
}
|
||||
|
||||
Result LoadAesKey(s32 keyslot, const void *owner, const AccessKey &access_key, const KeySource &key_source) {
|
||||
R_TRY(ValidateAesKeyslot(keyslot, owner));
|
||||
R_TRY(ValidateAesKeySlot(keyslot, owner));
|
||||
return LoadVirtualAesKey(keyslot, access_key, key_source);
|
||||
}
|
||||
|
||||
@@ -632,7 +638,7 @@ namespace ams::spl::impl {
|
||||
.data = {0x89, 0x61, 0x5E, 0xE0, 0x5C, 0x31, 0xB6, 0x80, 0x5F, 0xE5, 0x8F, 0x3D, 0xA2, 0x4F, 0x7A, 0xA8}
|
||||
};
|
||||
|
||||
ScopedAesKeyslot keyslot_holder;
|
||||
ScopedAesKeySlot keyslot_holder;
|
||||
R_TRY(keyslot_holder.Allocate());
|
||||
|
||||
R_TRY(LoadVirtualAesKey(keyslot_holder.GetKeySlot(), access_key, s_generate_aes_key_source));
|
||||
@@ -651,8 +657,8 @@ namespace ams::spl::impl {
|
||||
return GenerateAesKey(out_key, access_key, key_source);
|
||||
}
|
||||
|
||||
Result CryptAesCtr(void *dst, size_t dst_size, s32 keyslot, const void *owner, const void *src, size_t src_size, const IvCtr &iv_ctr) {
|
||||
R_TRY(ValidateAesKeyslot(keyslot, owner));
|
||||
Result ComputeCtr(void *dst, size_t dst_size, s32 keyslot, const void *owner, const void *src, size_t src_size, const IvCtr &iv_ctr) {
|
||||
R_TRY(ValidateAesKeySlot(keyslot, owner));
|
||||
|
||||
/* Succeed immediately if there's nothing to crypt. */
|
||||
if (src_size == 0) {
|
||||
@@ -670,14 +676,14 @@ namespace ams::spl::impl {
|
||||
const uintptr_t dst_addr_page_aligned = util::AlignDown(dst_addr, os::MemoryPageSize);
|
||||
const size_t src_size_page_aligned = util::AlignUp(src_addr + src_size, os::MemoryPageSize) - src_addr_page_aligned;
|
||||
const size_t dst_size_page_aligned = util::AlignUp(dst_addr + dst_size, os::MemoryPageSize) - dst_addr_page_aligned;
|
||||
const u32 src_se_map_addr = CryptAesInMapBase + (src_addr_page_aligned % DeviceAddressSpaceAlign);
|
||||
const u32 dst_se_map_addr = CryptAesOutMapBase + (dst_addr_page_aligned % DeviceAddressSpaceAlign);
|
||||
const u32 src_se_addr = CryptAesInMapBase + (src_addr % DeviceAddressSpaceAlign);
|
||||
const u32 dst_se_addr = CryptAesOutMapBase + (dst_addr % DeviceAddressSpaceAlign);
|
||||
const u32 src_se_map_addr = ComputeAesInMapBase + (src_addr_page_aligned % DeviceAddressSpaceAlign);
|
||||
const u32 dst_se_map_addr = ComputeAesOutMapBase + (dst_addr_page_aligned % DeviceAddressSpaceAlign);
|
||||
const u32 src_se_addr = ComputeAesInMapBase + (src_addr % DeviceAddressSpaceAlign);
|
||||
const u32 dst_se_addr = ComputeAesOutMapBase + (dst_addr % DeviceAddressSpaceAlign);
|
||||
|
||||
/* Validate aligned sizes. */
|
||||
R_UNLESS(src_size_page_aligned <= CryptAesSizeMax, spl::ResultInvalidSize());
|
||||
R_UNLESS(dst_size_page_aligned <= CryptAesSizeMax, spl::ResultInvalidSize());
|
||||
R_UNLESS(src_size_page_aligned <= ComputeAesSizeMax, spl::ResultInvalidSize());
|
||||
R_UNLESS(dst_size_page_aligned <= ComputeAesSizeMax, spl::ResultInvalidSize());
|
||||
|
||||
/* Helpers for mapping/unmapping. */
|
||||
DeviceAddressSpaceMapHelper in_mapper(g_se_das_hnd, src_se_map_addr, src_addr_page_aligned, src_size_page_aligned, 1);
|
||||
@@ -698,11 +704,11 @@ namespace ams::spl::impl {
|
||||
{
|
||||
std::scoped_lock lk(g_async_op_lock);
|
||||
smc::AsyncOperationKey op_key;
|
||||
const u32 mode = smc::GetCryptAesMode(smc::CipherMode::Ctr, GetPhysicalKeySlot(keyslot, true));
|
||||
const u32 mode = smc::GetComputeAesMode(smc::CipherMode::Ctr, GetPhysicalKeySlot(keyslot, true));
|
||||
const u32 dst_ll_addr = g_se_mapped_work_buffer_addr + offsetof(SeCryptContext, out);
|
||||
const u32 src_ll_addr = g_se_mapped_work_buffer_addr + offsetof(SeCryptContext, in);
|
||||
|
||||
smc::Result res = smc::CryptAes(&op_key, mode, iv_ctr, dst_ll_addr, src_ll_addr, src_size);
|
||||
smc::Result res = smc::ComputeAes(&op_key, mode, iv_ctr, dst_ll_addr, src_ll_addr, src_size);
|
||||
if (res != smc::Result::Success) {
|
||||
return smc::ConvertResult(res);
|
||||
}
|
||||
@@ -717,7 +723,7 @@ namespace ams::spl::impl {
|
||||
}
|
||||
|
||||
Result ComputeCmac(Cmac *out_cmac, s32 keyslot, const void *owner, const void *data, size_t size) {
|
||||
R_TRY(ValidateAesKeyslot(keyslot, owner));
|
||||
R_TRY(ValidateAesKeySlot(keyslot, owner));
|
||||
|
||||
R_UNLESS(size <= WorkBufferSizeMax, spl::ResultInvalidSize());
|
||||
|
||||
@@ -725,9 +731,9 @@ namespace ams::spl::impl {
|
||||
return smc::ConvertResult(smc::ComputeCmac(out_cmac, GetPhysicalKeySlot(keyslot, true), g_work_buffer, size));
|
||||
}
|
||||
|
||||
Result AllocateAesKeyslot(s32 *out_keyslot, const void *owner) {
|
||||
Result AllocateAesKeySlot(s32 *out_keyslot, const void *owner) {
|
||||
/* Find a virtual keyslot. */
|
||||
for (s32 i = 0; i < MaxVirtualAesKeyslots; i++) {
|
||||
for (s32 i = 0; i < MaxVirtualAesKeySlots; i++) {
|
||||
if (g_keyslot_owners[i] == nullptr) {
|
||||
g_keyslot_owners[i] = owner;
|
||||
g_keyslot_contents[i] = { .type = KeySlotContentType::None };
|
||||
@@ -737,20 +743,20 @@ namespace ams::spl::impl {
|
||||
}
|
||||
|
||||
os::ClearSystemEvent(std::addressof(g_se_keyslot_available_event));
|
||||
return spl::ResultOutOfKeyslots();
|
||||
return spl::ResultOutOfKeySlots();
|
||||
}
|
||||
|
||||
Result FreeAesKeyslot(s32 keyslot, const void *owner) {
|
||||
Result DeallocateAesKeySlot(s32 keyslot, const void *owner) {
|
||||
/* Only virtual keyslots can be freed. */
|
||||
R_UNLESS(IsVirtualKeySlot(keyslot), spl::ResultInvalidKeyslot());
|
||||
R_UNLESS(IsVirtualKeySlot(keyslot), spl::ResultInvalidKeySlot());
|
||||
|
||||
/* Ensure the keyslot is owned. */
|
||||
R_TRY(ValidateAesKeyslot(keyslot, owner));
|
||||
R_TRY(ValidateAesKeySlot(keyslot, owner));
|
||||
|
||||
/* Clear the physical keyslot, if we're cached. */
|
||||
s32 phys_slot;
|
||||
if (g_keyslot_cache.Release(std::addressof(phys_slot), keyslot)) {
|
||||
ClearPhysicalKeyslot(phys_slot);
|
||||
ClearPhysicalKeySlot(phys_slot);
|
||||
}
|
||||
|
||||
/* Clear the virtual keyslot. */
|
||||
@@ -763,15 +769,15 @@ namespace ams::spl::impl {
|
||||
}
|
||||
|
||||
/* RSA. */
|
||||
Result DecryptRsaPrivateKey(void *dst, size_t dst_size, const void *src, size_t src_size, const AccessKey &access_key, const KeySource &key_source, u32 option) {
|
||||
struct DecryptRsaPrivateKeyLayout {
|
||||
u8 data[RsaPrivateKeySize + RsaPrivateKeyMetaSize];
|
||||
Result DecryptDeviceUniqueData(void *dst, size_t dst_size, const void *src, size_t src_size, const AccessKey &access_key, const KeySource &key_source, u32 option) {
|
||||
struct DecryptDeviceUniqueDataLayout {
|
||||
u8 data[RsaPrivateKeySize + DeviceUniqueDataMetaSize];
|
||||
};
|
||||
DecryptRsaPrivateKeyLayout *layout = reinterpret_cast<DecryptRsaPrivateKeyLayout *>(g_work_buffer);
|
||||
DecryptDeviceUniqueDataLayout *layout = reinterpret_cast<DecryptDeviceUniqueDataLayout *>(g_work_buffer);
|
||||
|
||||
/* Validate size. */
|
||||
R_UNLESS(src_size >= RsaPrivateKeyMetaSize, spl::ResultInvalidSize());
|
||||
R_UNLESS(src_size <= sizeof(DecryptRsaPrivateKeyLayout), spl::ResultInvalidSize());
|
||||
R_UNLESS(src_size >= DeviceUniqueDataMetaSize, spl::ResultInvalidSize());
|
||||
R_UNLESS(src_size <= sizeof(DecryptDeviceUniqueDataLayout), spl::ResultInvalidSize());
|
||||
|
||||
std::memcpy(layout->data, src, src_size);
|
||||
armDCacheFlush(layout, sizeof(*layout));
|
||||
@@ -779,10 +785,10 @@ namespace ams::spl::impl {
|
||||
smc::Result smc_res;
|
||||
size_t copy_size = 0;
|
||||
if (hos::GetVersion() >= hos::Version_5_0_0) {
|
||||
copy_size = std::min(dst_size, src_size - RsaPrivateKeyMetaSize);
|
||||
smc_res = smc::DecryptOrImportRsaPrivateKey(layout->data, src_size, access_key, key_source, static_cast<smc::DecryptOrImportMode>(option));
|
||||
copy_size = std::min(dst_size, src_size - DeviceUniqueDataMetaSize);
|
||||
smc_res = smc::DecryptDeviceUniqueData(layout->data, src_size, access_key, key_source, static_cast<smc::DeviceUniqueDataMode>(option));
|
||||
} else {
|
||||
smc_res = smc::DecryptRsaPrivateKey(©_size, layout->data, src_size, access_key, key_source, option);
|
||||
smc_res = smc::DecryptDeviceUniqueData(©_size, layout->data, src_size, access_key, key_source, option);
|
||||
copy_size = std::min(dst_size, copy_size);
|
||||
}
|
||||
|
||||
@@ -795,71 +801,66 @@ namespace ams::spl::impl {
|
||||
}
|
||||
|
||||
/* SSL */
|
||||
Result ImportSslKey(const void *src, size_t src_size, const AccessKey &access_key, const KeySource &key_source) {
|
||||
return ImportSecureExpModKey(src, src_size, access_key, key_source, static_cast<u32>(smc::DecryptOrImportMode::ImportSslKey));
|
||||
Result DecryptAndStoreSslClientCertKey(const void *src, size_t src_size, const AccessKey &access_key, const KeySource &key_source) {
|
||||
return DecryptAndStoreDeviceUniqueKey(src, src_size, access_key, key_source, static_cast<u32>(smc::DeviceUniqueDataMode::DecryptAndStoreSslKey));
|
||||
}
|
||||
|
||||
Result SslExpMod(void *out, size_t out_size, const void *base, size_t base_size, const void *mod, size_t mod_size) {
|
||||
return SecureExpMod(out, out_size, base, base_size, mod, mod_size, smc::SecureExpModMode::Ssl);
|
||||
Result ModularExponentiateWithSslClientCertKey(void *out, size_t out_size, const void *base, size_t base_size, const void *mod, size_t mod_size) {
|
||||
return ModularExponentiateWithStorageKey(out, out_size, base, base_size, mod, mod_size, smc::ModularExponentiateWithStorageKeyMode::Ssl);
|
||||
}
|
||||
|
||||
/* ES */
|
||||
Result ImportEsKey(const void *src, size_t src_size, const AccessKey &access_key, const KeySource &key_source, u32 option) {
|
||||
Result LoadEsDeviceKey(const void *src, size_t src_size, const AccessKey &access_key, const KeySource &key_source, u32 option) {
|
||||
if (hos::GetVersion() >= hos::Version_5_0_0) {
|
||||
return ImportSecureExpModKey(src, src_size, access_key, key_source, option);
|
||||
return DecryptAndStoreDeviceUniqueKey(src, src_size, access_key, key_source, option);
|
||||
} else {
|
||||
struct ImportEsKeyLayout {
|
||||
u8 data[RsaPrivateKeyMetaSize + 2 * RsaPrivateKeySize + 0x10];
|
||||
struct LoadEsDeviceKeyLayout {
|
||||
u8 data[DeviceUniqueDataMetaSize + 2 * RsaPrivateKeySize + 0x10];
|
||||
};
|
||||
ImportEsKeyLayout *layout = reinterpret_cast<ImportEsKeyLayout *>(g_work_buffer);
|
||||
LoadEsDeviceKeyLayout *layout = reinterpret_cast<LoadEsDeviceKeyLayout *>(g_work_buffer);
|
||||
|
||||
/* Validate size. */
|
||||
R_UNLESS(src_size <= sizeof(ImportEsKeyLayout), spl::ResultInvalidSize());
|
||||
R_UNLESS(src_size <= sizeof(LoadEsDeviceKeyLayout), spl::ResultInvalidSize());
|
||||
|
||||
std::memcpy(layout, src, src_size);
|
||||
|
||||
armDCacheFlush(layout, sizeof(*layout));
|
||||
return smc::ConvertResult(smc::ImportEsKey(layout->data, src_size, access_key, key_source, option));
|
||||
return smc::ConvertResult(smc::LoadEsDeviceKey(layout->data, src_size, access_key, key_source, option));
|
||||
}
|
||||
}
|
||||
|
||||
Result UnwrapTitleKey(AccessKey *out_access_key, const void *base, size_t base_size, const void *mod, size_t mod_size, const void *label_digest, size_t label_digest_size, u32 generation) {
|
||||
return UnwrapEsRsaOaepWrappedKey(out_access_key, base, base_size, mod, mod_size, label_digest, label_digest_size, generation, smc::EsKeyType::TitleKey);
|
||||
Result PrepareEsTitleKey(AccessKey *out_access_key, const void *base, size_t base_size, const void *mod, size_t mod_size, const void *label_digest, size_t label_digest_size, u32 generation) {
|
||||
return PrepareEsDeviceUniqueKey(out_access_key, base, base_size, mod, mod_size, label_digest, label_digest_size, generation, smc::EsCommonKeyType::TitleKey);
|
||||
}
|
||||
|
||||
Result UnwrapCommonTitleKey(AccessKey *out_access_key, const KeySource &key_source, u32 generation) {
|
||||
return smc::ConvertResult(smc::UnwrapCommonTitleKey(out_access_key, key_source, generation));
|
||||
Result PrepareCommonEsTitleKey(AccessKey *out_access_key, const KeySource &key_source, u32 generation) {
|
||||
return smc::ConvertResult(smc::PrepareCommonEsTitleKey(out_access_key, key_source, generation));
|
||||
}
|
||||
|
||||
Result ImportDrmKey(const void *src, size_t src_size, const AccessKey &access_key, const KeySource &key_source) {
|
||||
return ImportSecureExpModKey(src, src_size, access_key, key_source, static_cast<u32>(smc::DecryptOrImportMode::ImportDrmKey));
|
||||
Result DecryptAndStoreDrmDeviceCertKey(const void *src, size_t src_size, const AccessKey &access_key, const KeySource &key_source) {
|
||||
return DecryptAndStoreDeviceUniqueKey(src, src_size, access_key, key_source, static_cast<u32>(smc::DeviceUniqueDataMode::DecryptAndStoreDrmDeviceCertKey));
|
||||
}
|
||||
|
||||
Result DrmExpMod(void *out, size_t out_size, const void *base, size_t base_size, const void *mod, size_t mod_size) {
|
||||
return SecureExpMod(out, out_size, base, base_size, mod, mod_size, smc::SecureExpModMode::Drm);
|
||||
Result ModularExponentiateWithDrmDeviceCertKey(void *out, size_t out_size, const void *base, size_t base_size, const void *mod, size_t mod_size) {
|
||||
return ModularExponentiateWithStorageKey(out, out_size, base, base_size, mod, mod_size, smc::ModularExponentiateWithStorageKeyMode::DrmDeviceCert);
|
||||
}
|
||||
|
||||
Result UnwrapElicenseKey(AccessKey *out_access_key, const void *base, size_t base_size, const void *mod, size_t mod_size, const void *label_digest, size_t label_digest_size, u32 generation) {
|
||||
return UnwrapEsRsaOaepWrappedKey(out_access_key, base, base_size, mod, mod_size, label_digest, label_digest_size, generation, smc::EsKeyType::ElicenseKey);
|
||||
}
|
||||
|
||||
Result LoadElicenseKey(s32 keyslot, const void *owner, const AccessKey &access_key) {
|
||||
/* Right now, this is just literally the same function as LoadTitleKey in N's impl. */
|
||||
return LoadTitleKey(keyslot, owner, access_key);
|
||||
Result PrepareEsArchiveKey(AccessKey *out_access_key, const void *base, size_t base_size, const void *mod, size_t mod_size, const void *label_digest, size_t label_digest_size, u32 generation) {
|
||||
return PrepareEsDeviceUniqueKey(out_access_key, base, base_size, mod, mod_size, label_digest, label_digest_size, generation, smc::EsCommonKeyType::ArchiveKey);
|
||||
}
|
||||
|
||||
/* FS */
|
||||
Result ImportLotusKey(const void *src, size_t src_size, const AccessKey &access_key, const KeySource &key_source, u32 option) {
|
||||
return ImportSecureExpModKey(src, src_size, access_key, key_source, option);
|
||||
Result DecryptAndStoreGcKey(const void *src, size_t src_size, const AccessKey &access_key, const KeySource &key_source, u32 option) {
|
||||
return DecryptAndStoreDeviceUniqueKey(src, src_size, access_key, key_source, option);
|
||||
}
|
||||
|
||||
Result DecryptLotusMessage(u32 *out_size, void *dst, size_t dst_size, const void *base, size_t base_size, const void *mod, size_t mod_size, const void *label_digest, size_t label_digest_size) {
|
||||
Result DecryptGcMessage(u32 *out_size, void *dst, size_t dst_size, const void *base, size_t base_size, const void *mod, size_t mod_size, const void *label_digest, size_t label_digest_size) {
|
||||
/* Validate sizes. */
|
||||
R_UNLESS(dst_size <= WorkBufferSizeMax, spl::ResultInvalidSize());
|
||||
R_UNLESS(label_digest_size == LabelDigestSizeMax, spl::ResultInvalidSize());
|
||||
|
||||
/* Nintendo doesn't check this result code, but we will. */
|
||||
R_TRY(SecureExpMod(g_work_buffer, 0x100, base, base_size, mod, mod_size, smc::SecureExpModMode::Lotus));
|
||||
R_TRY(ModularExponentiateWithStorageKey(g_work_buffer, 0x100, base, base_size, mod, mod_size, smc::ModularExponentiateWithStorageKeyMode::Gc));
|
||||
|
||||
size_t data_size = crypto::DecodeRsa2048OaepSha256(dst, dst_size, label_digest, label_digest_size, g_work_buffer, 0x100);
|
||||
R_UNLESS(data_size > 0, spl::ResultDecryptionFailed());
|
||||
@@ -872,9 +873,9 @@ namespace ams::spl::impl {
|
||||
return smc::ConvertResult(smc::GenerateSpecificAesKey(out_key, key_source, generation, which));
|
||||
}
|
||||
|
||||
Result LoadTitleKey(s32 keyslot, const void *owner, const AccessKey &access_key) {
|
||||
R_TRY(ValidateAesKeyslot(keyslot, owner));
|
||||
return LoadVirtualTitleKey(keyslot, access_key);
|
||||
Result LoadPreparedAesKey(s32 keyslot, const void *owner, const AccessKey &access_key) {
|
||||
R_TRY(ValidateAesKeySlot(keyslot, owner));
|
||||
return LoadVirtualPreparedAesKey(keyslot, access_key);
|
||||
}
|
||||
|
||||
Result GetPackage2Hash(void *dst, const size_t size) {
|
||||
@@ -882,7 +883,7 @@ namespace ams::spl::impl {
|
||||
R_UNLESS(size >= sizeof(hash), spl::ResultInvalidSize());
|
||||
|
||||
smc::Result smc_res;
|
||||
if ((smc_res = smc::GetConfig(hash, 4, SplConfigItem_Package2Hash)) != smc::Result::Success) {
|
||||
if ((smc_res = smc::GetConfig(hash, 4, ConfigItem::Package2Hash)) != smc::Result::Success) {
|
||||
return smc::ConvertResult(smc_res);
|
||||
}
|
||||
|
||||
@@ -891,19 +892,19 @@ namespace ams::spl::impl {
|
||||
}
|
||||
|
||||
/* Manu. */
|
||||
Result ReEncryptRsaPrivateKey(void *dst, size_t dst_size, const void *src, size_t src_size, const AccessKey &access_key_dec, const KeySource &source_dec, const AccessKey &access_key_enc, const KeySource &source_enc, u32 option) {
|
||||
struct ReEncryptRsaPrivateKeyLayout {
|
||||
u8 data[RsaPrivateKeyMetaSize + 2 * RsaPrivateKeySize + 0x10];
|
||||
Result ReencryptDeviceUniqueData(void *dst, size_t dst_size, const void *src, size_t src_size, const AccessKey &access_key_dec, const KeySource &source_dec, const AccessKey &access_key_enc, const KeySource &source_enc, u32 option) {
|
||||
struct ReencryptDeviceUniqueDataLayout {
|
||||
u8 data[DeviceUniqueDataMetaSize + 2 * RsaPrivateKeySize + 0x10];
|
||||
AccessKey access_key_dec;
|
||||
KeySource source_dec;
|
||||
AccessKey access_key_enc;
|
||||
KeySource source_enc;
|
||||
};
|
||||
ReEncryptRsaPrivateKeyLayout *layout = reinterpret_cast<ReEncryptRsaPrivateKeyLayout *>(g_work_buffer);
|
||||
ReencryptDeviceUniqueDataLayout *layout = reinterpret_cast<ReencryptDeviceUniqueDataLayout *>(g_work_buffer);
|
||||
|
||||
/* Validate size. */
|
||||
R_UNLESS(src_size >= RsaPrivateKeyMetaSize, spl::ResultInvalidSize());
|
||||
R_UNLESS(src_size <= sizeof(ReEncryptRsaPrivateKeyLayout), spl::ResultInvalidSize());
|
||||
R_UNLESS(src_size >= DeviceUniqueDataMetaSize, spl::ResultInvalidSize());
|
||||
R_UNLESS(src_size <= sizeof(ReencryptDeviceUniqueDataLayout), spl::ResultInvalidSize());
|
||||
|
||||
std::memcpy(layout, src, src_size);
|
||||
layout->access_key_dec = access_key_dec;
|
||||
@@ -913,7 +914,7 @@ namespace ams::spl::impl {
|
||||
|
||||
armDCacheFlush(layout, sizeof(*layout));
|
||||
|
||||
smc::Result smc_res = smc::ReEncryptRsaPrivateKey(layout->data, src_size, layout->access_key_dec, layout->source_dec, layout->access_key_enc, layout->source_enc, option);
|
||||
smc::Result smc_res = smc::ReencryptDeviceUniqueData(layout->data, src_size, layout->access_key_dec, layout->source_dec, layout->access_key_enc, layout->source_enc, option);
|
||||
if (smc_res == smc::Result::Success) {
|
||||
size_t copy_size = std::min(dst_size, src_size);
|
||||
armDCacheFlush(layout, copy_size);
|
||||
@@ -924,16 +925,16 @@ namespace ams::spl::impl {
|
||||
}
|
||||
|
||||
/* Helper. */
|
||||
Result FreeAesKeyslots(const void *owner) {
|
||||
Result DeallocateAllAesKeySlots(const void *owner) {
|
||||
for (s32 slot = VirtualKeySlotMin; slot <= VirtualKeySlotMax; ++slot) {
|
||||
if (g_keyslot_owners[GetVirtualKeySlotIndex(slot)] == owner) {
|
||||
FreeAesKeyslot(slot, owner);
|
||||
DeallocateAesKeySlot(slot, owner);
|
||||
}
|
||||
}
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
Handle GetAesKeyslotAvailableEventHandle() {
|
||||
Handle GetAesKeySlotAvailableEventHandle() {
|
||||
return os::GetReadableHandleOfSystemEvent(std::addressof(g_se_keyslot_available_event));
|
||||
}
|
||||
|
||||
|
||||
@@ -22,9 +22,9 @@ namespace ams::spl::impl {
|
||||
void Initialize();
|
||||
|
||||
/* General. */
|
||||
Result GetConfig(u64 *out, SplConfigItem which);
|
||||
Result ExpMod(void *out, size_t out_size, const void *base, size_t base_size, const void *exp, size_t exp_size, const void *mod, size_t mod_size);
|
||||
Result SetConfig(SplConfigItem which, u64 value);
|
||||
Result GetConfig(u64 *out, spl::ConfigItem which);
|
||||
Result ModularExponentiate(void *out, size_t out_size, const void *base, size_t base_size, const void *exp, size_t exp_size, const void *mod, size_t mod_size);
|
||||
Result SetConfig(spl::ConfigItem which, u64 value);
|
||||
Result GenerateRandomBytes(void *out, size_t size);
|
||||
Result IsDevelopment(bool *out);
|
||||
Result SetBootReason(BootReasonValue boot_reason);
|
||||
@@ -35,39 +35,39 @@ namespace ams::spl::impl {
|
||||
Result LoadAesKey(s32 keyslot, const void *owner, const AccessKey &access_key, const KeySource &key_source);
|
||||
Result GenerateAesKey(AesKey *out_key, const AccessKey &access_key, const KeySource &key_source);
|
||||
Result DecryptAesKey(AesKey *out_key, const KeySource &key_source, u32 generation, u32 option);
|
||||
Result CryptAesCtr(void *dst, size_t dst_size, s32 keyslot, const void *owner, const void *src, size_t src_size, const IvCtr &iv_ctr);
|
||||
Result ComputeCtr(void *dst, size_t dst_size, s32 keyslot, const void *owner, const void *src, size_t src_size, const IvCtr &iv_ctr);
|
||||
Result ComputeCmac(Cmac *out_cmac, s32 keyslot, const void *owner, const void *data, size_t size);
|
||||
Result AllocateAesKeyslot(s32 *out_keyslot, const void *owner);
|
||||
Result FreeAesKeyslot(s32 keyslot, const void *owner);
|
||||
Result AllocateAesKeySlot(s32 *out_keyslot, const void *owner);
|
||||
Result DeallocateAesKeySlot(s32 keyslot, const void *owner);
|
||||
|
||||
/* RSA. */
|
||||
Result DecryptRsaPrivateKey(void *dst, size_t dst_size, const void *src, size_t src_size, const AccessKey &access_key, const KeySource &key_source, u32 option);
|
||||
Result DecryptDeviceUniqueData(void *dst, size_t dst_size, const void *src, size_t src_size, const AccessKey &access_key, const KeySource &key_source, u32 option);
|
||||
|
||||
/* SSL */
|
||||
Result ImportSslKey(const void *src, size_t src_size, const AccessKey &access_key, const KeySource &key_source);
|
||||
Result SslExpMod(void *out, size_t out_size, const void *base, size_t base_size, const void *mod, size_t mod_size);
|
||||
Result DecryptAndStoreSslClientCertKey(const void *src, size_t src_size, const AccessKey &access_key, const KeySource &key_source);
|
||||
Result ModularExponentiateWithSslClientCertKey(void *out, size_t out_size, const void *base, size_t base_size, const void *mod, size_t mod_size);
|
||||
|
||||
/* ES */
|
||||
Result ImportEsKey(const void *src, size_t src_size, const AccessKey &access_key, const KeySource &key_source, u32 option);
|
||||
Result UnwrapTitleKey(AccessKey *out_access_key, const void *base, size_t base_size, const void *mod, size_t mod_size, const void *label_digest, size_t label_digest_size, u32 generation);
|
||||
Result UnwrapCommonTitleKey(AccessKey *out_access_key, const KeySource &key_source, u32 generation);
|
||||
Result ImportDrmKey(const void *src, size_t src_size, const AccessKey &access_key, const KeySource &key_source);
|
||||
Result DrmExpMod(void *out, size_t out_size, const void *base, size_t base_size, const void *mod, size_t mod_size);
|
||||
Result UnwrapElicenseKey(AccessKey *out_access_key, const void *base, size_t base_size, const void *mod, size_t mod_size, const void *label_digest, size_t label_digest_size, u32 generation);
|
||||
Result LoadElicenseKey(s32 keyslot, const void *owner, const AccessKey &access_key);
|
||||
Result LoadEsDeviceKey(const void *src, size_t src_size, const AccessKey &access_key, const KeySource &key_source, u32 option);
|
||||
Result PrepareEsTitleKey(AccessKey *out_access_key, const void *base, size_t base_size, const void *mod, size_t mod_size, const void *label_digest, size_t label_digest_size, u32 generation);
|
||||
Result PrepareCommonEsTitleKey(AccessKey *out_access_key, const KeySource &key_source, u32 generation);
|
||||
Result DecryptAndStoreDrmDeviceCertKey(const void *src, size_t src_size, const AccessKey &access_key, const KeySource &key_source);
|
||||
Result ModularExponentiateWithDrmDeviceCertKey(void *out, size_t out_size, const void *base, size_t base_size, const void *mod, size_t mod_size);
|
||||
Result PrepareEsArchiveKey(AccessKey *out_access_key, const void *base, size_t base_size, const void *mod, size_t mod_size, const void *label_digest, size_t label_digest_size, u32 generation);
|
||||
Result LoadPreparedAesKey(s32 keyslot, const void *owner, const AccessKey &access_key);
|
||||
|
||||
/* FS */
|
||||
Result ImportLotusKey(const void *src, size_t src_size, const AccessKey &access_key, const KeySource &key_source, u32 option);
|
||||
Result DecryptLotusMessage(u32 *out_size, void *dst, size_t dst_size, const void *base, size_t base_size, const void *mod, size_t mod_size, const void *label_digest, size_t label_digest_size);
|
||||
Result DecryptAndStoreGcKey(const void *src, size_t src_size, const AccessKey &access_key, const KeySource &key_source, u32 option);
|
||||
Result DecryptGcMessage(u32 *out_size, void *dst, size_t dst_size, const void *base, size_t base_size, const void *mod, size_t mod_size, const void *label_digest, size_t label_digest_size);
|
||||
Result GenerateSpecificAesKey(AesKey *out_key, const KeySource &key_source, u32 generation, u32 which);
|
||||
Result LoadTitleKey(s32 keyslot, const void *owner, const AccessKey &access_key);
|
||||
Result LoadPreparedAesKey(s32 keyslot, const void *owner, const AccessKey &access_key);
|
||||
Result GetPackage2Hash(void *dst, const size_t size);
|
||||
|
||||
/* Manu. */
|
||||
Result ReEncryptRsaPrivateKey(void *dst, size_t dst_size, const void *src, size_t src_size, const AccessKey &access_key_dec, const KeySource &source_dec, const AccessKey &access_key_enc, const KeySource &source_enc, u32 option);
|
||||
Result ReencryptDeviceUniqueData(void *dst, size_t dst_size, const void *src, size_t src_size, const AccessKey &access_key_dec, const KeySource &source_dec, const AccessKey &access_key_enc, const KeySource &source_enc, u32 option);
|
||||
|
||||
/* Helper. */
|
||||
Result FreeAesKeyslots(const void *owner);
|
||||
Handle GetAesKeyslotAvailableEventHandle();
|
||||
Result DeallocateAllAesKeySlots(const void *owner);
|
||||
Handle GetAesKeySlotAvailableEventHandle();
|
||||
|
||||
}
|
||||
|
||||
@@ -21,7 +21,7 @@ namespace ams::spl {
|
||||
|
||||
CryptoService::~CryptoService() {
|
||||
/* Free any keyslots this service is using. */
|
||||
impl::FreeAesKeyslots(this);
|
||||
impl::DeallocateAllAesKeySlots(this);
|
||||
}
|
||||
|
||||
Result CryptoService::GenerateAesKek(sf::Out<AccessKey> out_access_key, KeySource key_source, u32 generation, u32 option) {
|
||||
@@ -40,24 +40,25 @@ namespace ams::spl {
|
||||
return impl::DecryptAesKey(out_key.GetPointer(), key_source, generation, option);
|
||||
}
|
||||
|
||||
Result CryptoService::CryptAesCtr(const sf::OutNonSecureBuffer &out_buf, s32 keyslot, const sf::InNonSecureBuffer &in_buf, IvCtr iv_ctr) {
|
||||
return impl::CryptAesCtr(out_buf.GetPointer(), out_buf.GetSize(), keyslot, this, in_buf.GetPointer(), in_buf.GetSize(), iv_ctr);
|
||||
Result CryptoService::ComputeCtr(const sf::OutNonSecureBuffer &out_buf, s32 keyslot, const sf::InNonSecureBuffer &in_buf, IvCtr iv_ctr) {
|
||||
return impl::ComputeCtr(out_buf.GetPointer(), out_buf.GetSize(), keyslot, this, in_buf.GetPointer(), in_buf.GetSize(), iv_ctr);
|
||||
}
|
||||
|
||||
Result CryptoService::ComputeCmac(sf::Out<Cmac> out_cmac, s32 keyslot, const sf::InPointerBuffer &in_buf) {
|
||||
return impl::ComputeCmac(out_cmac.GetPointer(), keyslot, this, in_buf.GetPointer(), in_buf.GetSize());
|
||||
}
|
||||
|
||||
Result CryptoService::AllocateAesKeyslot(sf::Out<s32> out_keyslot) {
|
||||
return impl::AllocateAesKeyslot(out_keyslot.GetPointer(), this);
|
||||
Result CryptoService::AllocateAesKeySlot(sf::Out<s32> out_keyslot) {
|
||||
return impl::AllocateAesKeySlot(out_keyslot.GetPointer(), this);
|
||||
}
|
||||
|
||||
Result CryptoService::FreeAesKeyslot(s32 keyslot) {
|
||||
return impl::FreeAesKeyslot(keyslot, this);
|
||||
Result CryptoService::DeallocateAesKeySlot(s32 keyslot) {
|
||||
return impl::DeallocateAesKeySlot(keyslot, this);
|
||||
}
|
||||
|
||||
void CryptoService::GetAesKeyslotAvailableEvent(sf::OutCopyHandle out_hnd) {
|
||||
out_hnd.SetValue(impl::GetAesKeyslotAvailableEventHandle());
|
||||
Result CryptoService::GetAesKeySlotAvailableEvent(sf::OutCopyHandle out_hnd) {
|
||||
out_hnd.SetValue(impl::GetAesKeySlotAvailableEventHandle());
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -20,38 +20,19 @@ namespace ams::spl {
|
||||
|
||||
class CryptoService : public GeneralService {
|
||||
public:
|
||||
CryptoService() : GeneralService() { /* ... */ }
|
||||
virtual ~CryptoService();
|
||||
protected:
|
||||
/* Actual commands. */
|
||||
virtual Result GenerateAesKek(sf::Out<AccessKey> out_access_key, KeySource key_source, u32 generation, u32 option);
|
||||
virtual Result LoadAesKey(s32 keyslot, AccessKey access_key, KeySource key_source);
|
||||
virtual Result GenerateAesKey(sf::Out<AesKey> out_key, AccessKey access_key, KeySource key_source);
|
||||
virtual Result DecryptAesKey(sf::Out<AesKey> out_key, KeySource key_source, u32 generation, u32 option);
|
||||
virtual Result CryptAesCtr(const sf::OutNonSecureBuffer &out_buf, s32 keyslot, const sf::InNonSecureBuffer &in_buf, IvCtr iv_ctr);
|
||||
virtual Result ComputeCmac(sf::Out<Cmac> out_cmac, s32 keyslot, const sf::InPointerBuffer &in_buf);
|
||||
virtual Result AllocateAesKeyslot(sf::Out<s32> out_keyslot);
|
||||
virtual Result FreeAesKeyslot(s32 keyslot);
|
||||
virtual void GetAesKeyslotAvailableEvent(sf::OutCopyHandle out_hnd);
|
||||
public:
|
||||
DEFINE_SERVICE_DISPATCH_TABLE {
|
||||
MAKE_SERVICE_COMMAND_META(GetConfig),
|
||||
MAKE_SERVICE_COMMAND_META(ExpMod),
|
||||
MAKE_SERVICE_COMMAND_META(SetConfig),
|
||||
MAKE_SERVICE_COMMAND_META(GenerateRandomBytes),
|
||||
MAKE_SERVICE_COMMAND_META(IsDevelopment),
|
||||
MAKE_SERVICE_COMMAND_META(SetBootReason, hos::Version_3_0_0),
|
||||
MAKE_SERVICE_COMMAND_META(GetBootReason, hos::Version_3_0_0),
|
||||
MAKE_SERVICE_COMMAND_META(GenerateAesKek),
|
||||
MAKE_SERVICE_COMMAND_META(LoadAesKey),
|
||||
MAKE_SERVICE_COMMAND_META(GenerateAesKey),
|
||||
MAKE_SERVICE_COMMAND_META(DecryptAesKey),
|
||||
MAKE_SERVICE_COMMAND_META(CryptAesCtr),
|
||||
MAKE_SERVICE_COMMAND_META(ComputeCmac),
|
||||
MAKE_SERVICE_COMMAND_META(AllocateAesKeyslot /* Atmosphere extension: This was added in hos::Version_2_0_0, but is allowed on older firmware by atmosphere. */),
|
||||
MAKE_SERVICE_COMMAND_META(FreeAesKeyslot /* Atmosphere extension: This was added in hos::Version_2_0_0, but is allowed on older firmware by atmosphere. */),
|
||||
MAKE_SERVICE_COMMAND_META(GetAesKeyslotAvailableEvent /* Atmosphere extension: This was added in hos::Version_2_0_0, but is allowed on older firmware by atmosphere. */),
|
||||
};
|
||||
/* Actual commands. */
|
||||
Result GenerateAesKek(sf::Out<AccessKey> out_access_key, KeySource key_source, u32 generation, u32 option);
|
||||
Result LoadAesKey(s32 keyslot, AccessKey access_key, KeySource key_source);
|
||||
Result GenerateAesKey(sf::Out<AesKey> out_key, AccessKey access_key, KeySource key_source);
|
||||
Result DecryptAesKey(sf::Out<AesKey> out_key, KeySource key_source, u32 generation, u32 option);
|
||||
Result ComputeCtr(const sf::OutNonSecureBuffer &out_buf, s32 keyslot, const sf::InNonSecureBuffer &in_buf, IvCtr iv_ctr);
|
||||
Result ComputeCmac(sf::Out<Cmac> out_cmac, s32 keyslot, const sf::InPointerBuffer &in_buf);
|
||||
Result AllocateAesKeySlot(sf::Out<s32> out_keyslot);
|
||||
Result DeallocateAesKeySlot(s32 keyslot);
|
||||
Result GetAesKeySlotAvailableEvent(sf::OutCopyHandle out_hnd);
|
||||
};
|
||||
static_assert(spl::impl::IsICryptoInterface<CryptoService>);
|
||||
|
||||
}
|
||||
|
||||
@@ -19,12 +19,17 @@
|
||||
|
||||
namespace ams::spl {
|
||||
|
||||
Result DeprecatedService::GetConfig(sf::Out<u64> out, u32 which) {
|
||||
return impl::GetConfig(out.GetPointer(), static_cast<SplConfigItem>(which));
|
||||
DeprecatedService::~DeprecatedService() {
|
||||
/* Free any keyslots this service is using. */
|
||||
impl::DeallocateAllAesKeySlots(this);
|
||||
}
|
||||
|
||||
Result DeprecatedService::ExpMod(const sf::OutPointerBuffer &out, const sf::InPointerBuffer &base, const sf::InPointerBuffer &exp, const sf::InPointerBuffer &mod) {
|
||||
return impl::ExpMod(out.GetPointer(), out.GetSize(), base.GetPointer(), base.GetSize(), exp.GetPointer(), exp.GetSize(), mod.GetPointer(), mod.GetSize());
|
||||
Result DeprecatedService::GetConfig(sf::Out<u64> out, u32 which) {
|
||||
return impl::GetConfig(out.GetPointer(), static_cast<spl::ConfigItem>(which));
|
||||
}
|
||||
|
||||
Result DeprecatedService::ModularExponentiate(const sf::OutPointerBuffer &out, const sf::InPointerBuffer &base, const sf::InPointerBuffer &exp, const sf::InPointerBuffer &mod) {
|
||||
return impl::ModularExponentiate(out.GetPointer(), out.GetSize(), base.GetPointer(), base.GetSize(), exp.GetPointer(), exp.GetSize(), mod.GetPointer(), mod.GetSize());
|
||||
}
|
||||
|
||||
Result DeprecatedService::GenerateAesKek(sf::Out<AccessKey> out_access_key, KeySource key_source, u32 generation, u32 option) {
|
||||
@@ -40,19 +45,19 @@ namespace ams::spl {
|
||||
}
|
||||
|
||||
Result DeprecatedService::SetConfig(u32 which, u64 value) {
|
||||
return impl::SetConfig(static_cast<SplConfigItem>(which), value);
|
||||
return impl::SetConfig(static_cast<spl::ConfigItem>(which), value);
|
||||
}
|
||||
|
||||
Result DeprecatedService::GenerateRandomBytes(const sf::OutPointerBuffer &out) {
|
||||
return impl::GenerateRandomBytes(out.GetPointer(), out.GetSize());
|
||||
}
|
||||
|
||||
Result DeprecatedService::ImportLotusKey(const sf::InPointerBuffer &src, AccessKey access_key, KeySource key_source, u32 option) {
|
||||
return impl::ImportLotusKey(src.GetPointer(), src.GetSize(), access_key, key_source, option);
|
||||
Result DeprecatedService::DecryptAndStoreGcKey(const sf::InPointerBuffer &src, AccessKey access_key, KeySource key_source, u32 option) {
|
||||
return impl::DecryptAndStoreGcKey(src.GetPointer(), src.GetSize(), access_key, key_source, option);
|
||||
}
|
||||
|
||||
Result DeprecatedService::DecryptLotusMessage(sf::Out<u32> out_size, const sf::OutPointerBuffer &out, const sf::InPointerBuffer &base, const sf::InPointerBuffer &mod, const sf::InPointerBuffer &label_digest) {
|
||||
return impl::DecryptLotusMessage(out_size.GetPointer(), out.GetPointer(), out.GetSize(), base.GetPointer(), base.GetSize(), mod.GetPointer(), mod.GetSize(), label_digest.GetPointer(), label_digest.GetSize());
|
||||
Result DeprecatedService::DecryptGcMessage(sf::Out<u32> out_size, const sf::OutPointerBuffer &out, const sf::InPointerBuffer &base, const sf::InPointerBuffer &mod, const sf::InPointerBuffer &label_digest) {
|
||||
return impl::DecryptGcMessage(out_size.GetPointer(), out.GetPointer(), out.GetSize(), base.GetPointer(), base.GetSize(), mod.GetPointer(), mod.GetSize(), label_digest.GetPointer(), label_digest.GetSize());
|
||||
}
|
||||
|
||||
Result DeprecatedService::IsDevelopment(sf::Out<bool> is_dev) {
|
||||
@@ -63,60 +68,61 @@ namespace ams::spl {
|
||||
return impl::GenerateSpecificAesKey(out_key.GetPointer(), key_source, generation, which);
|
||||
}
|
||||
|
||||
Result DeprecatedService::DecryptRsaPrivateKey(const sf::OutPointerBuffer &dst, const sf::InPointerBuffer &src, AccessKey access_key, KeySource key_source, u32 option) {
|
||||
return impl::DecryptRsaPrivateKey(dst.GetPointer(), dst.GetSize(), src.GetPointer(), src.GetSize(), access_key, key_source, option);
|
||||
Result DeprecatedService::DecryptDeviceUniqueData(const sf::OutPointerBuffer &dst, const sf::InPointerBuffer &src, AccessKey access_key, KeySource key_source, u32 option) {
|
||||
return impl::DecryptDeviceUniqueData(dst.GetPointer(), dst.GetSize(), src.GetPointer(), src.GetSize(), access_key, key_source, option);
|
||||
}
|
||||
|
||||
Result DeprecatedService::DecryptAesKey(sf::Out<AesKey> out_key, KeySource key_source, u32 generation, u32 option) {
|
||||
return impl::DecryptAesKey(out_key.GetPointer(), key_source, generation, option);
|
||||
}
|
||||
|
||||
Result DeprecatedService::CryptAesCtrDeprecated(const sf::OutBuffer &out_buf, s32 keyslot, const sf::InBuffer &in_buf, IvCtr iv_ctr) {
|
||||
return impl::CryptAesCtr(out_buf.GetPointer(), out_buf.GetSize(), keyslot, this, in_buf.GetPointer(), in_buf.GetSize(), iv_ctr);
|
||||
Result DeprecatedService::ComputeCtrDeprecated(const sf::OutBuffer &out_buf, s32 keyslot, const sf::InBuffer &in_buf, IvCtr iv_ctr) {
|
||||
return impl::ComputeCtr(out_buf.GetPointer(), out_buf.GetSize(), keyslot, this, in_buf.GetPointer(), in_buf.GetSize(), iv_ctr);
|
||||
}
|
||||
|
||||
Result DeprecatedService::CryptAesCtr(const sf::OutNonSecureBuffer &out_buf, s32 keyslot, const sf::InNonSecureBuffer &in_buf, IvCtr iv_ctr) {
|
||||
return impl::CryptAesCtr(out_buf.GetPointer(), out_buf.GetSize(), keyslot, this, in_buf.GetPointer(), in_buf.GetSize(), iv_ctr);
|
||||
Result DeprecatedService::ComputeCtr(const sf::OutNonSecureBuffer &out_buf, s32 keyslot, const sf::InNonSecureBuffer &in_buf, IvCtr iv_ctr) {
|
||||
return impl::ComputeCtr(out_buf.GetPointer(), out_buf.GetSize(), keyslot, this, in_buf.GetPointer(), in_buf.GetSize(), iv_ctr);
|
||||
}
|
||||
|
||||
Result DeprecatedService::ComputeCmac(sf::Out<Cmac> out_cmac, s32 keyslot, const sf::InPointerBuffer &in_buf) {
|
||||
return impl::ComputeCmac(out_cmac.GetPointer(), keyslot, this, in_buf.GetPointer(), in_buf.GetSize());
|
||||
}
|
||||
|
||||
Result DeprecatedService::ImportEsKey(const sf::InPointerBuffer &src, AccessKey access_key, KeySource key_source, u32 option) {
|
||||
return impl::ImportEsKey(src.GetPointer(), src.GetSize(), access_key, key_source, option);
|
||||
Result DeprecatedService::LoadEsDeviceKey(const sf::InPointerBuffer &src, AccessKey access_key, KeySource key_source, u32 option) {
|
||||
return impl::LoadEsDeviceKey(src.GetPointer(), src.GetSize(), access_key, key_source, option);
|
||||
}
|
||||
|
||||
Result DeprecatedService::UnwrapTitleKeyDeprecated(sf::Out<AccessKey> out_access_key, const sf::InPointerBuffer &base, const sf::InPointerBuffer &mod, const sf::InPointerBuffer &label_digest) {
|
||||
return impl::UnwrapTitleKey(out_access_key.GetPointer(), base.GetPointer(), base.GetSize(), mod.GetPointer(), mod.GetSize(), label_digest.GetPointer(), label_digest.GetSize(), 0);
|
||||
Result DeprecatedService::PrepareEsTitleKeyDeprecated(sf::Out<AccessKey> out_access_key, const sf::InPointerBuffer &base, const sf::InPointerBuffer &mod, const sf::InPointerBuffer &label_digest) {
|
||||
return impl::PrepareEsTitleKey(out_access_key.GetPointer(), base.GetPointer(), base.GetSize(), mod.GetPointer(), mod.GetSize(), label_digest.GetPointer(), label_digest.GetSize(), 0);
|
||||
}
|
||||
|
||||
Result DeprecatedService::UnwrapTitleKey(sf::Out<AccessKey> out_access_key, const sf::InPointerBuffer &base, const sf::InPointerBuffer &mod, const sf::InPointerBuffer &label_digest, u32 generation) {
|
||||
return impl::UnwrapTitleKey(out_access_key.GetPointer(), base.GetPointer(), base.GetSize(), mod.GetPointer(), mod.GetSize(), label_digest.GetPointer(), label_digest.GetSize(), generation);
|
||||
Result DeprecatedService::PrepareEsTitleKey(sf::Out<AccessKey> out_access_key, const sf::InPointerBuffer &base, const sf::InPointerBuffer &mod, const sf::InPointerBuffer &label_digest, u32 generation) {
|
||||
return impl::PrepareEsTitleKey(out_access_key.GetPointer(), base.GetPointer(), base.GetSize(), mod.GetPointer(), mod.GetSize(), label_digest.GetPointer(), label_digest.GetSize(), generation);
|
||||
}
|
||||
|
||||
Result DeprecatedService::LoadTitleKey(s32 keyslot, AccessKey access_key) {
|
||||
return impl::LoadTitleKey(keyslot, this, access_key);
|
||||
Result DeprecatedService::LoadPreparedAesKey(s32 keyslot, AccessKey access_key) {
|
||||
return impl::LoadPreparedAesKey(keyslot, this, access_key);
|
||||
}
|
||||
|
||||
Result DeprecatedService::UnwrapCommonTitleKeyDeprecated(sf::Out<AccessKey> out_access_key, KeySource key_source) {
|
||||
return impl::UnwrapCommonTitleKey(out_access_key.GetPointer(), key_source, 0);
|
||||
Result DeprecatedService::PrepareCommonEsTitleKeyDeprecated(sf::Out<AccessKey> out_access_key, KeySource key_source) {
|
||||
return impl::PrepareCommonEsTitleKey(out_access_key.GetPointer(), key_source, 0);
|
||||
}
|
||||
|
||||
Result DeprecatedService::UnwrapCommonTitleKey(sf::Out<AccessKey> out_access_key, KeySource key_source, u32 generation) {
|
||||
return impl::UnwrapCommonTitleKey(out_access_key.GetPointer(), key_source, generation);
|
||||
Result DeprecatedService::PrepareCommonEsTitleKey(sf::Out<AccessKey> out_access_key, KeySource key_source, u32 generation) {
|
||||
return impl::PrepareCommonEsTitleKey(out_access_key.GetPointer(), key_source, generation);
|
||||
}
|
||||
|
||||
Result DeprecatedService::AllocateAesKeyslot(sf::Out<s32> out_keyslot) {
|
||||
return impl::AllocateAesKeyslot(out_keyslot.GetPointer(), this);
|
||||
Result DeprecatedService::AllocateAesKeySlot(sf::Out<s32> out_keyslot) {
|
||||
return impl::AllocateAesKeySlot(out_keyslot.GetPointer(), this);
|
||||
}
|
||||
|
||||
Result DeprecatedService::FreeAesKeyslot(s32 keyslot) {
|
||||
return impl::FreeAesKeyslot(keyslot, this);
|
||||
Result DeprecatedService::DeallocateAesKeySlot(s32 keyslot) {
|
||||
return impl::DeallocateAesKeySlot(keyslot, this);
|
||||
}
|
||||
|
||||
void DeprecatedService::GetAesKeyslotAvailableEvent(sf::OutCopyHandle out_hnd) {
|
||||
out_hnd.SetValue(impl::GetAesKeyslotAvailableEventHandle());
|
||||
Result DeprecatedService::GetAesKeySlotAvailableEvent(sf::OutCopyHandle out_hnd) {
|
||||
out_hnd.SetValue(impl::GetAesKeySlotAvailableEventHandle());
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
Result DeprecatedService::SetBootReason(BootReasonValue boot_reason) {
|
||||
|
||||
@@ -18,112 +18,39 @@
|
||||
|
||||
namespace ams::spl {
|
||||
|
||||
class DeprecatedService : public sf::IServiceObject {
|
||||
protected:
|
||||
enum class CommandId {
|
||||
/* 1.0.0+ */
|
||||
GetConfig = 0,
|
||||
ExpMod = 1,
|
||||
GenerateAesKek = 2,
|
||||
LoadAesKey = 3,
|
||||
GenerateAesKey = 4,
|
||||
SetConfig = 5,
|
||||
GenerateRandomBytes = 7,
|
||||
ImportLotusKey = 9,
|
||||
DecryptLotusMessage = 10,
|
||||
IsDevelopment = 11,
|
||||
GenerateSpecificAesKey = 12,
|
||||
DecryptRsaPrivateKeyDeprecated = 13,
|
||||
DecryptRsaPrivateKey = 13,
|
||||
DecryptAesKey = 14,
|
||||
CryptAesCtrDeprecated = 15,
|
||||
CryptAesCtr = 15,
|
||||
ComputeCmac = 16,
|
||||
ImportEsKey = 17,
|
||||
UnwrapTitleKeyDeprecated = 18,
|
||||
UnwrapTitleKey = 18,
|
||||
LoadTitleKey = 19,
|
||||
|
||||
/* 2.0.0+ */
|
||||
UnwrapCommonTitleKeyDeprecated = 20,
|
||||
UnwrapCommonTitleKey = 20,
|
||||
AllocateAesKeyslot = 21,
|
||||
FreeAesKeyslot = 22,
|
||||
GetAesKeyslotAvailableEvent = 23,
|
||||
|
||||
/* 3.0.0+ */
|
||||
SetBootReason = 24,
|
||||
GetBootReason = 25,
|
||||
};
|
||||
class DeprecatedService final {
|
||||
public:
|
||||
virtual ~DeprecatedService();
|
||||
public:
|
||||
DeprecatedService() { /* ... */ }
|
||||
virtual ~DeprecatedService() { /* ... */ }
|
||||
protected:
|
||||
/* Actual commands. */
|
||||
virtual Result GetConfig(sf::Out<u64> out, u32 which);
|
||||
virtual Result ExpMod(const sf::OutPointerBuffer &out, const sf::InPointerBuffer &base, const sf::InPointerBuffer &exp, const sf::InPointerBuffer &mod);
|
||||
virtual Result GenerateAesKek(sf::Out<AccessKey> out_access_key, KeySource key_source, u32 generation, u32 option);
|
||||
virtual Result LoadAesKey(s32 keyslot, AccessKey access_key, KeySource key_source);
|
||||
virtual Result GenerateAesKey(sf::Out<AesKey> out_key, AccessKey access_key, KeySource key_source);
|
||||
virtual Result SetConfig(u32 which, u64 value);
|
||||
virtual Result GenerateRandomBytes(const sf::OutPointerBuffer &out);
|
||||
virtual Result ImportLotusKey(const sf::InPointerBuffer &src, AccessKey access_key, KeySource key_source, u32 option);
|
||||
virtual Result DecryptLotusMessage(sf::Out<u32> out_size, const sf::OutPointerBuffer &out, const sf::InPointerBuffer &base, const sf::InPointerBuffer &mod, const sf::InPointerBuffer &label_digest);
|
||||
virtual Result IsDevelopment(sf::Out<bool> is_dev);
|
||||
virtual Result GenerateSpecificAesKey(sf::Out<AesKey> out_key, KeySource key_source, u32 generation, u32 which);
|
||||
virtual Result DecryptRsaPrivateKey(const sf::OutPointerBuffer &dst, const sf::InPointerBuffer &src, AccessKey access_key, KeySource key_source, u32 option);
|
||||
virtual Result DecryptAesKey(sf::Out<AesKey> out_key, KeySource key_source, u32 generation, u32 option);
|
||||
virtual Result CryptAesCtrDeprecated(const sf::OutBuffer &out_buf, s32 keyslot, const sf::InBuffer &in_buf, IvCtr iv_ctr);
|
||||
virtual Result CryptAesCtr(const sf::OutNonSecureBuffer &out_buf, s32 keyslot, const sf::InNonSecureBuffer &in_buf, IvCtr iv_ctr);
|
||||
virtual Result ComputeCmac(sf::Out<Cmac> out_cmac, s32 keyslot, const sf::InPointerBuffer &in_buf);
|
||||
virtual Result ImportEsKey(const sf::InPointerBuffer &src, AccessKey access_key, KeySource key_source, u32 option);
|
||||
virtual Result UnwrapTitleKeyDeprecated(sf::Out<AccessKey> out_access_key, const sf::InPointerBuffer &base, const sf::InPointerBuffer &mod, const sf::InPointerBuffer &label_digest);
|
||||
virtual Result UnwrapTitleKey(sf::Out<AccessKey> out_access_key, const sf::InPointerBuffer &base, const sf::InPointerBuffer &mod, const sf::InPointerBuffer &label_digest, u32 generation);
|
||||
virtual Result LoadTitleKey(s32 keyslot, AccessKey access_key);
|
||||
virtual Result UnwrapCommonTitleKeyDeprecated(sf::Out<AccessKey> out_access_key, KeySource key_source);
|
||||
virtual Result UnwrapCommonTitleKey(sf::Out<AccessKey> out_access_key, KeySource key_source, u32 generation);
|
||||
virtual Result AllocateAesKeyslot(sf::Out<s32> out_keyslot);
|
||||
virtual Result FreeAesKeyslot(s32 keyslot);
|
||||
virtual void GetAesKeyslotAvailableEvent(sf::OutCopyHandle out_hnd);
|
||||
virtual Result SetBootReason(BootReasonValue boot_reason);
|
||||
virtual Result GetBootReason(sf::Out<BootReasonValue> out);
|
||||
public:
|
||||
DEFINE_SERVICE_DISPATCH_TABLE {
|
||||
MAKE_SERVICE_COMMAND_META(GetConfig),
|
||||
MAKE_SERVICE_COMMAND_META(ExpMod),
|
||||
MAKE_SERVICE_COMMAND_META(GenerateAesKek),
|
||||
MAKE_SERVICE_COMMAND_META(LoadAesKey),
|
||||
MAKE_SERVICE_COMMAND_META(GenerateAesKey),
|
||||
MAKE_SERVICE_COMMAND_META(SetConfig),
|
||||
MAKE_SERVICE_COMMAND_META(GenerateRandomBytes),
|
||||
MAKE_SERVICE_COMMAND_META(ImportLotusKey),
|
||||
MAKE_SERVICE_COMMAND_META(DecryptLotusMessage),
|
||||
MAKE_SERVICE_COMMAND_META(IsDevelopment),
|
||||
MAKE_SERVICE_COMMAND_META(GenerateSpecificAesKey),
|
||||
MAKE_SERVICE_COMMAND_META(DecryptRsaPrivateKey),
|
||||
MAKE_SERVICE_COMMAND_META(DecryptAesKey),
|
||||
|
||||
MAKE_SERVICE_COMMAND_META(CryptAesCtrDeprecated, hos::Version_1_0_0, hos::Version_1_0_0),
|
||||
MAKE_SERVICE_COMMAND_META(CryptAesCtr, hos::Version_2_0_0),
|
||||
|
||||
MAKE_SERVICE_COMMAND_META(ComputeCmac),
|
||||
MAKE_SERVICE_COMMAND_META(ImportEsKey),
|
||||
|
||||
MAKE_SERVICE_COMMAND_META(UnwrapTitleKeyDeprecated, hos::Version_1_0_0, hos::Version_2_0_0),
|
||||
MAKE_SERVICE_COMMAND_META(UnwrapTitleKey, hos::Version_3_0_0),
|
||||
|
||||
MAKE_SERVICE_COMMAND_META(LoadTitleKey),
|
||||
|
||||
MAKE_SERVICE_COMMAND_META(UnwrapCommonTitleKeyDeprecated, hos::Version_2_0_0, hos::Version_2_3_0),
|
||||
MAKE_SERVICE_COMMAND_META(UnwrapCommonTitleKey, hos::Version_3_0_0),
|
||||
|
||||
MAKE_SERVICE_COMMAND_META(AllocateAesKeyslot /* Atmosphere extension: This was added in hos::Version_2_0_0, but is allowed on older firmware by atmosphere. */),
|
||||
MAKE_SERVICE_COMMAND_META(FreeAesKeyslot /* Atmosphere extension: This was added in hos::Version_2_0_0, but is allowed on older firmware by atmosphere. */),
|
||||
MAKE_SERVICE_COMMAND_META(GetAesKeyslotAvailableEvent /* Atmosphere extension: This was added in hos::Version_2_0_0, but is allowed on older firmware by atmosphere. */),
|
||||
|
||||
MAKE_SERVICE_COMMAND_META(SetBootReason, hos::Version_3_0_0),
|
||||
MAKE_SERVICE_COMMAND_META(GetBootReason, hos::Version_3_0_0),
|
||||
};
|
||||
Result GetConfig(sf::Out<u64> out, u32 which);
|
||||
Result ModularExponentiate(const sf::OutPointerBuffer &out, const sf::InPointerBuffer &base, const sf::InPointerBuffer &exp, const sf::InPointerBuffer &mod);
|
||||
Result GenerateAesKek(sf::Out<AccessKey> out_access_key, KeySource key_source, u32 generation, u32 option);
|
||||
Result LoadAesKey(s32 keyslot, AccessKey access_key, KeySource key_source);
|
||||
Result GenerateAesKey(sf::Out<AesKey> out_key, AccessKey access_key, KeySource key_source);
|
||||
Result SetConfig(u32 which, u64 value);
|
||||
Result GenerateRandomBytes(const sf::OutPointerBuffer &out);
|
||||
Result DecryptAndStoreGcKey(const sf::InPointerBuffer &src, AccessKey access_key, KeySource key_source, u32 option);
|
||||
Result DecryptGcMessage(sf::Out<u32> out_size, const sf::OutPointerBuffer &out, const sf::InPointerBuffer &base, const sf::InPointerBuffer &mod, const sf::InPointerBuffer &label_digest);
|
||||
Result IsDevelopment(sf::Out<bool> is_dev);
|
||||
Result GenerateSpecificAesKey(sf::Out<AesKey> out_key, KeySource key_source, u32 generation, u32 which);
|
||||
Result DecryptDeviceUniqueData(const sf::OutPointerBuffer &dst, const sf::InPointerBuffer &src, AccessKey access_key, KeySource key_source, u32 option);
|
||||
Result DecryptAesKey(sf::Out<AesKey> out_key, KeySource key_source, u32 generation, u32 option);
|
||||
Result ComputeCtrDeprecated(const sf::OutBuffer &out_buf, s32 keyslot, const sf::InBuffer &in_buf, IvCtr iv_ctr);
|
||||
Result ComputeCtr(const sf::OutNonSecureBuffer &out_buf, s32 keyslot, const sf::InNonSecureBuffer &in_buf, IvCtr iv_ctr);
|
||||
Result ComputeCmac(sf::Out<Cmac> out_cmac, s32 keyslot, const sf::InPointerBuffer &in_buf);
|
||||
Result LoadEsDeviceKey(const sf::InPointerBuffer &src, AccessKey access_key, KeySource key_source, u32 option);
|
||||
Result PrepareEsTitleKeyDeprecated(sf::Out<AccessKey> out_access_key, const sf::InPointerBuffer &base, const sf::InPointerBuffer &mod, const sf::InPointerBuffer &label_digest);
|
||||
Result PrepareEsTitleKey(sf::Out<AccessKey> out_access_key, const sf::InPointerBuffer &base, const sf::InPointerBuffer &mod, const sf::InPointerBuffer &label_digest, u32 generation);
|
||||
Result LoadPreparedAesKey(s32 keyslot, AccessKey access_key);
|
||||
Result PrepareCommonEsTitleKeyDeprecated(sf::Out<AccessKey> out_access_key, KeySource key_source);
|
||||
Result PrepareCommonEsTitleKey(sf::Out<AccessKey> out_access_key, KeySource key_source, u32 generation);
|
||||
Result AllocateAesKeySlot(sf::Out<s32> out_keyslot);
|
||||
Result DeallocateAesKeySlot(s32 keyslot);
|
||||
Result GetAesKeySlotAvailableEvent(sf::OutCopyHandle out_hnd);
|
||||
Result SetBootReason(BootReasonValue boot_reason);
|
||||
Result GetBootReason(sf::Out<BootReasonValue> out);
|
||||
};
|
||||
static_assert(spl::impl::IsIDeprecatedGeneralInterface<DeprecatedService>);
|
||||
|
||||
}
|
||||
|
||||
30
stratosphere/spl/source/spl_device_unique_data_service.cpp
Normal file
30
stratosphere/spl/source/spl_device_unique_data_service.cpp
Normal file
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2020 Atmosphère-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include <stratosphere.hpp>
|
||||
#include "spl_api_impl.hpp"
|
||||
#include "spl_device_unique_data_service.hpp"
|
||||
|
||||
namespace ams::spl {
|
||||
|
||||
Result DeviceUniqueDataService::DecryptDeviceUniqueDataDeprecated(const sf::OutPointerBuffer &dst, const sf::InPointerBuffer &src, AccessKey access_key, KeySource key_source, u32 option) {
|
||||
return impl::DecryptDeviceUniqueData(dst.GetPointer(), dst.GetSize(), src.GetPointer(), src.GetSize(), access_key, key_source, option);
|
||||
}
|
||||
|
||||
Result DeviceUniqueDataService::DecryptDeviceUniqueData(const sf::OutPointerBuffer &dst, const sf::InPointerBuffer &src, AccessKey access_key, KeySource key_source) {
|
||||
return impl::DecryptDeviceUniqueData(dst.GetPointer(), dst.GetSize(), src.GetPointer(), src.GetSize(), access_key, key_source, static_cast<u32>(smc::DeviceUniqueDataMode::DecryptDeviceUniqueData));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -18,14 +18,12 @@
|
||||
|
||||
namespace ams::spl {
|
||||
|
||||
class RsaService : public CryptoService {
|
||||
class DeviceUniqueDataService : public CryptoService {
|
||||
public:
|
||||
RsaService() : CryptoService() { /* ... */ }
|
||||
virtual ~RsaService() { /* ... */ }
|
||||
protected:
|
||||
/* Actual commands. */
|
||||
virtual Result DecryptRsaPrivateKeyDeprecated(const sf::OutPointerBuffer &dst, const sf::InPointerBuffer &src, AccessKey access_key, KeySource key_source, u32 option);
|
||||
virtual Result DecryptRsaPrivateKey(const sf::OutPointerBuffer &dst, const sf::InPointerBuffer &src, AccessKey access_key, KeySource key_source);
|
||||
Result DecryptDeviceUniqueDataDeprecated(const sf::OutPointerBuffer &dst, const sf::InPointerBuffer &src, AccessKey access_key, KeySource key_source, u32 option);
|
||||
Result DecryptDeviceUniqueData(const sf::OutPointerBuffer &dst, const sf::InPointerBuffer &src, AccessKey access_key, KeySource key_source);
|
||||
};
|
||||
static_assert(spl::impl::IsIDeviceUniqueDataInterface<DeviceUniqueDataService>);
|
||||
|
||||
}
|
||||
@@ -19,36 +19,36 @@
|
||||
|
||||
namespace ams::spl {
|
||||
|
||||
Result EsService::ImportEsKeyDeprecated(const sf::InPointerBuffer &src, AccessKey access_key, KeySource key_source, u32 option) {
|
||||
return impl::ImportEsKey(src.GetPointer(), src.GetSize(), access_key, key_source, option);
|
||||
Result EsService::LoadEsDeviceKeyDeprecated(const sf::InPointerBuffer &src, AccessKey access_key, KeySource key_source, u32 option) {
|
||||
return impl::LoadEsDeviceKey(src.GetPointer(), src.GetSize(), access_key, key_source, option);
|
||||
}
|
||||
|
||||
Result EsService::ImportEsKey(const sf::InPointerBuffer &src, AccessKey access_key, KeySource key_source) {
|
||||
return impl::ImportEsKey(src.GetPointer(), src.GetSize(), access_key, key_source, static_cast<u32>(smc::DecryptOrImportMode::ImportEsKey));
|
||||
Result EsService::LoadEsDeviceKey(const sf::InPointerBuffer &src, AccessKey access_key, KeySource key_source) {
|
||||
return impl::LoadEsDeviceKey(src.GetPointer(), src.GetSize(), access_key, key_source, static_cast<u32>(smc::DeviceUniqueDataMode::DecryptAndStoreEsDeviceKey));
|
||||
}
|
||||
|
||||
Result EsService::UnwrapTitleKey(sf::Out<AccessKey> out_access_key, const sf::InPointerBuffer &base, const sf::InPointerBuffer &mod, const sf::InPointerBuffer &label_digest, u32 generation) {
|
||||
return impl::UnwrapTitleKey(out_access_key.GetPointer(), base.GetPointer(), base.GetSize(), mod.GetPointer(), mod.GetSize(), label_digest.GetPointer(), label_digest.GetSize(), generation);
|
||||
Result EsService::PrepareEsTitleKey(sf::Out<AccessKey> out_access_key, const sf::InPointerBuffer &base, const sf::InPointerBuffer &mod, const sf::InPointerBuffer &label_digest, u32 generation) {
|
||||
return impl::PrepareEsTitleKey(out_access_key.GetPointer(), base.GetPointer(), base.GetSize(), mod.GetPointer(), mod.GetSize(), label_digest.GetPointer(), label_digest.GetSize(), generation);
|
||||
}
|
||||
|
||||
Result EsService::UnwrapCommonTitleKey(sf::Out<AccessKey> out_access_key, KeySource key_source, u32 generation) {
|
||||
return impl::UnwrapCommonTitleKey(out_access_key.GetPointer(), key_source, generation);
|
||||
Result EsService::PrepareCommonEsTitleKey(sf::Out<AccessKey> out_access_key, KeySource key_source, u32 generation) {
|
||||
return impl::PrepareCommonEsTitleKey(out_access_key.GetPointer(), key_source, generation);
|
||||
}
|
||||
|
||||
Result EsService::ImportDrmKey(const sf::InPointerBuffer &src, AccessKey access_key, KeySource key_source) {
|
||||
return impl::ImportDrmKey(src.GetPointer(), src.GetSize(), access_key, key_source);
|
||||
Result EsService::DecryptAndStoreDrmDeviceCertKey(const sf::InPointerBuffer &src, AccessKey access_key, KeySource key_source) {
|
||||
return impl::DecryptAndStoreDrmDeviceCertKey(src.GetPointer(), src.GetSize(), access_key, key_source);
|
||||
}
|
||||
|
||||
Result EsService::DrmExpMod(const sf::OutPointerBuffer &out, const sf::InPointerBuffer &base, const sf::InPointerBuffer &mod) {
|
||||
return impl::DrmExpMod(out.GetPointer(), out.GetSize(), base.GetPointer(), base.GetSize(), mod.GetPointer(), mod.GetSize());
|
||||
Result EsService::ModularExponentiateWithDrmDeviceCertKey(const sf::OutPointerBuffer &out, const sf::InPointerBuffer &base, const sf::InPointerBuffer &mod) {
|
||||
return impl::ModularExponentiateWithDrmDeviceCertKey(out.GetPointer(), out.GetSize(), base.GetPointer(), base.GetSize(), mod.GetPointer(), mod.GetSize());
|
||||
}
|
||||
|
||||
Result EsService::UnwrapElicenseKey(sf::Out<AccessKey> out_access_key, const sf::InPointerBuffer &base, const sf::InPointerBuffer &mod, const sf::InPointerBuffer &label_digest, u32 generation) {
|
||||
return impl::UnwrapElicenseKey(out_access_key.GetPointer(), base.GetPointer(), base.GetSize(), mod.GetPointer(), mod.GetSize(), label_digest.GetPointer(), label_digest.GetSize(), generation);
|
||||
Result EsService::PrepareEsArchiveKey(sf::Out<AccessKey> out_access_key, const sf::InPointerBuffer &base, const sf::InPointerBuffer &mod, const sf::InPointerBuffer &label_digest, u32 generation) {
|
||||
return impl::PrepareEsArchiveKey(out_access_key.GetPointer(), base.GetPointer(), base.GetSize(), mod.GetPointer(), mod.GetSize(), label_digest.GetPointer(), label_digest.GetSize(), generation);
|
||||
}
|
||||
|
||||
Result EsService::LoadElicenseKey(s32 keyslot, AccessKey access_key) {
|
||||
return impl::LoadElicenseKey(keyslot, this, access_key);
|
||||
Result EsService::LoadPreparedAesKey(s32 keyslot, AccessKey access_key) {
|
||||
return impl::LoadPreparedAesKey(keyslot, this, access_key);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -14,53 +14,22 @@
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#pragma once
|
||||
#include "spl_rsa_service.hpp"
|
||||
#include "spl_device_unique_data_service.hpp"
|
||||
|
||||
namespace ams::spl {
|
||||
|
||||
class EsService : public RsaService {
|
||||
class EsService : public DeviceUniqueDataService {
|
||||
public:
|
||||
EsService() : RsaService() { /* ... */ }
|
||||
virtual ~EsService() { /* ... */}
|
||||
protected:
|
||||
/* Actual commands. */
|
||||
virtual Result ImportEsKeyDeprecated(const sf::InPointerBuffer &src, AccessKey access_key, KeySource key_source, u32 option);
|
||||
virtual Result ImportEsKey(const sf::InPointerBuffer &src, AccessKey access_key, KeySource key_source);
|
||||
virtual Result UnwrapTitleKey(sf::Out<AccessKey> out_access_key, const sf::InPointerBuffer &base, const sf::InPointerBuffer &mod, const sf::InPointerBuffer &label_digest, u32 generation);
|
||||
virtual Result UnwrapCommonTitleKey(sf::Out<AccessKey> out_access_key, KeySource key_source, u32 generation);
|
||||
virtual Result ImportDrmKey(const sf::InPointerBuffer &src, AccessKey access_key, KeySource key_source);
|
||||
virtual Result DrmExpMod(const sf::OutPointerBuffer &out, const sf::InPointerBuffer &base, const sf::InPointerBuffer &mod);
|
||||
virtual Result UnwrapElicenseKey(sf::Out<AccessKey> out_access_key, const sf::InPointerBuffer &base, const sf::InPointerBuffer &mod, const sf::InPointerBuffer &label_digest, u32 generation);
|
||||
virtual Result LoadElicenseKey(s32 keyslot, AccessKey access_key);
|
||||
public:
|
||||
DEFINE_SERVICE_DISPATCH_TABLE {
|
||||
MAKE_SERVICE_COMMAND_META(GetConfig),
|
||||
MAKE_SERVICE_COMMAND_META(ExpMod),
|
||||
MAKE_SERVICE_COMMAND_META(SetConfig),
|
||||
MAKE_SERVICE_COMMAND_META(GenerateRandomBytes),
|
||||
MAKE_SERVICE_COMMAND_META(IsDevelopment),
|
||||
MAKE_SERVICE_COMMAND_META(SetBootReason, hos::Version_3_0_0),
|
||||
MAKE_SERVICE_COMMAND_META(GetBootReason, hos::Version_3_0_0),
|
||||
MAKE_SERVICE_COMMAND_META(GenerateAesKek),
|
||||
MAKE_SERVICE_COMMAND_META(LoadAesKey),
|
||||
MAKE_SERVICE_COMMAND_META(GenerateAesKey),
|
||||
MAKE_SERVICE_COMMAND_META(DecryptAesKey),
|
||||
MAKE_SERVICE_COMMAND_META(CryptAesCtr),
|
||||
MAKE_SERVICE_COMMAND_META(ComputeCmac),
|
||||
MAKE_SERVICE_COMMAND_META(AllocateAesKeyslot, hos::Version_2_0_0),
|
||||
MAKE_SERVICE_COMMAND_META(FreeAesKeyslot, hos::Version_2_0_0),
|
||||
MAKE_SERVICE_COMMAND_META(GetAesKeyslotAvailableEvent, hos::Version_2_0_0),
|
||||
MAKE_SERVICE_COMMAND_META(DecryptRsaPrivateKeyDeprecated, hos::Version_4_0_0, hos::Version_4_1_0),
|
||||
MAKE_SERVICE_COMMAND_META(DecryptRsaPrivateKey, hos::Version_5_0_0),
|
||||
MAKE_SERVICE_COMMAND_META(ImportEsKeyDeprecated, hos::Version_4_0_0, hos::Version_4_1_0),
|
||||
MAKE_SERVICE_COMMAND_META(ImportEsKey, hos::Version_5_0_0),
|
||||
MAKE_SERVICE_COMMAND_META(UnwrapTitleKey),
|
||||
MAKE_SERVICE_COMMAND_META(UnwrapCommonTitleKey, hos::Version_2_0_0),
|
||||
MAKE_SERVICE_COMMAND_META(ImportDrmKey, hos::Version_5_0_0),
|
||||
MAKE_SERVICE_COMMAND_META(DrmExpMod, hos::Version_5_0_0),
|
||||
MAKE_SERVICE_COMMAND_META(UnwrapElicenseKey, hos::Version_6_0_0),
|
||||
MAKE_SERVICE_COMMAND_META(LoadElicenseKey, hos::Version_6_0_0),
|
||||
};
|
||||
Result LoadEsDeviceKeyDeprecated(const sf::InPointerBuffer &src, AccessKey access_key, KeySource key_source, u32 option);
|
||||
Result LoadEsDeviceKey(const sf::InPointerBuffer &src, AccessKey access_key, KeySource key_source);
|
||||
Result PrepareEsTitleKey(sf::Out<AccessKey> out_access_key, const sf::InPointerBuffer &base, const sf::InPointerBuffer &mod, const sf::InPointerBuffer &label_digest, u32 generation);
|
||||
Result PrepareCommonEsTitleKey(sf::Out<AccessKey> out_access_key, KeySource key_source, u32 generation);
|
||||
Result DecryptAndStoreDrmDeviceCertKey(const sf::InPointerBuffer &src, AccessKey access_key, KeySource key_source);
|
||||
Result ModularExponentiateWithDrmDeviceCertKey(const sf::OutPointerBuffer &out, const sf::InPointerBuffer &base, const sf::InPointerBuffer &mod);
|
||||
Result PrepareEsArchiveKey(sf::Out<AccessKey> out_access_key, const sf::InPointerBuffer &base, const sf::InPointerBuffer &mod, const sf::InPointerBuffer &label_digest, u32 generation);
|
||||
Result LoadPreparedAesKey(s32 keyslot, AccessKey access_key);
|
||||
};
|
||||
static_assert(spl::impl::IsIEsInterface<EsService>);
|
||||
|
||||
}
|
||||
|
||||
@@ -19,24 +19,24 @@
|
||||
|
||||
namespace ams::spl {
|
||||
|
||||
Result FsService::ImportLotusKeyDeprecated(const sf::InPointerBuffer &src, AccessKey access_key, KeySource key_source, u32 option) {
|
||||
return impl::ImportLotusKey(src.GetPointer(), src.GetSize(), access_key, key_source, option);
|
||||
Result FsService::DecryptAndStoreGcKeyDeprecated(const sf::InPointerBuffer &src, AccessKey access_key, KeySource key_source, u32 option) {
|
||||
return impl::DecryptAndStoreGcKey(src.GetPointer(), src.GetSize(), access_key, key_source, option);
|
||||
}
|
||||
|
||||
Result FsService::ImportLotusKey(const sf::InPointerBuffer &src, AccessKey access_key, KeySource key_source) {
|
||||
return impl::ImportLotusKey(src.GetPointer(), src.GetSize(), access_key, key_source, static_cast<u32>(smc::DecryptOrImportMode::ImportLotusKey));
|
||||
Result FsService::DecryptAndStoreGcKey(const sf::InPointerBuffer &src, AccessKey access_key, KeySource key_source) {
|
||||
return impl::DecryptAndStoreGcKey(src.GetPointer(), src.GetSize(), access_key, key_source, static_cast<u32>(smc::DeviceUniqueDataMode::DecryptAndStoreGcKey));
|
||||
}
|
||||
|
||||
Result FsService::DecryptLotusMessage(sf::Out<u32> out_size, const sf::OutPointerBuffer &out, const sf::InPointerBuffer &base, const sf::InPointerBuffer &mod, const sf::InPointerBuffer &label_digest) {
|
||||
return impl::DecryptLotusMessage(out_size.GetPointer(), out.GetPointer(), out.GetSize(), base.GetPointer(), base.GetSize(), mod.GetPointer(), mod.GetSize(), label_digest.GetPointer(), label_digest.GetSize());
|
||||
Result FsService::DecryptGcMessage(sf::Out<u32> out_size, const sf::OutPointerBuffer &out, const sf::InPointerBuffer &base, const sf::InPointerBuffer &mod, const sf::InPointerBuffer &label_digest) {
|
||||
return impl::DecryptGcMessage(out_size.GetPointer(), out.GetPointer(), out.GetSize(), base.GetPointer(), base.GetSize(), mod.GetPointer(), mod.GetSize(), label_digest.GetPointer(), label_digest.GetSize());
|
||||
}
|
||||
|
||||
Result FsService::GenerateSpecificAesKey(sf::Out<AesKey> out_key, KeySource key_source, u32 generation, u32 which) {
|
||||
return impl::GenerateSpecificAesKey(out_key.GetPointer(), key_source, generation, which);
|
||||
}
|
||||
|
||||
Result FsService::LoadTitleKey(s32 keyslot, AccessKey access_key) {
|
||||
return impl::LoadTitleKey(keyslot, this, access_key);
|
||||
Result FsService::LoadPreparedAesKey(s32 keyslot, AccessKey access_key) {
|
||||
return impl::LoadPreparedAesKey(keyslot, this, access_key);
|
||||
}
|
||||
|
||||
Result FsService::GetPackage2Hash(const sf::OutPointerBuffer &dst) {
|
||||
|
||||
@@ -20,41 +20,14 @@ namespace ams::spl {
|
||||
|
||||
class FsService : public CryptoService {
|
||||
public:
|
||||
FsService() : CryptoService() { /* ... */ }
|
||||
virtual ~FsService() { /* ... */ }
|
||||
protected:
|
||||
/* Actual commands. */
|
||||
virtual Result ImportLotusKeyDeprecated(const sf::InPointerBuffer &src, AccessKey access_key, KeySource key_source, u32 option);
|
||||
virtual Result ImportLotusKey(const sf::InPointerBuffer &src, AccessKey access_key, KeySource key_source);
|
||||
virtual Result DecryptLotusMessage(sf::Out<u32> out_size, const sf::OutPointerBuffer &out, const sf::InPointerBuffer &base, const sf::InPointerBuffer &mod, const sf::InPointerBuffer &label_digest);
|
||||
virtual Result GenerateSpecificAesKey(sf::Out<AesKey> out_key, KeySource key_source, u32 generation, u32 which);
|
||||
virtual Result LoadTitleKey(s32 keyslot, AccessKey access_key);
|
||||
virtual Result GetPackage2Hash(const sf::OutPointerBuffer &dst);
|
||||
public:
|
||||
DEFINE_SERVICE_DISPATCH_TABLE {
|
||||
MAKE_SERVICE_COMMAND_META(GetConfig),
|
||||
MAKE_SERVICE_COMMAND_META(ExpMod),
|
||||
MAKE_SERVICE_COMMAND_META(SetConfig),
|
||||
MAKE_SERVICE_COMMAND_META(GenerateRandomBytes),
|
||||
MAKE_SERVICE_COMMAND_META(IsDevelopment),
|
||||
MAKE_SERVICE_COMMAND_META(SetBootReason, hos::Version_3_0_0),
|
||||
MAKE_SERVICE_COMMAND_META(GetBootReason, hos::Version_3_0_0),
|
||||
MAKE_SERVICE_COMMAND_META(GenerateAesKek),
|
||||
MAKE_SERVICE_COMMAND_META(LoadAesKey),
|
||||
MAKE_SERVICE_COMMAND_META(GenerateAesKey),
|
||||
MAKE_SERVICE_COMMAND_META(DecryptAesKey),
|
||||
MAKE_SERVICE_COMMAND_META(CryptAesCtr),
|
||||
MAKE_SERVICE_COMMAND_META(ComputeCmac),
|
||||
MAKE_SERVICE_COMMAND_META(AllocateAesKeyslot, hos::Version_2_0_0),
|
||||
MAKE_SERVICE_COMMAND_META(FreeAesKeyslot, hos::Version_2_0_0),
|
||||
MAKE_SERVICE_COMMAND_META(GetAesKeyslotAvailableEvent, hos::Version_2_0_0),
|
||||
MAKE_SERVICE_COMMAND_META(ImportLotusKeyDeprecated, hos::Version_4_0_0, hos::Version_4_1_0),
|
||||
MAKE_SERVICE_COMMAND_META(ImportLotusKey, hos::Version_5_0_0),
|
||||
MAKE_SERVICE_COMMAND_META(DecryptLotusMessage),
|
||||
MAKE_SERVICE_COMMAND_META(GenerateSpecificAesKey),
|
||||
MAKE_SERVICE_COMMAND_META(LoadTitleKey),
|
||||
MAKE_SERVICE_COMMAND_META(GetPackage2Hash, hos::Version_5_0_0),
|
||||
};
|
||||
Result DecryptAndStoreGcKeyDeprecated(const sf::InPointerBuffer &src, AccessKey access_key, KeySource key_source, u32 option);
|
||||
Result DecryptAndStoreGcKey(const sf::InPointerBuffer &src, AccessKey access_key, KeySource key_source);
|
||||
Result DecryptGcMessage(sf::Out<u32> out_size, const sf::OutPointerBuffer &out, const sf::InPointerBuffer &base, const sf::InPointerBuffer &mod, const sf::InPointerBuffer &label_digest);
|
||||
Result GenerateSpecificAesKey(sf::Out<AesKey> out_key, KeySource key_source, u32 generation, u32 which);
|
||||
Result LoadPreparedAesKey(s32 keyslot, AccessKey access_key);
|
||||
Result GetPackage2Hash(const sf::OutPointerBuffer &dst);
|
||||
};
|
||||
static_assert(spl::impl::IsIFsInterface<FsService>);
|
||||
|
||||
}
|
||||
|
||||
@@ -20,15 +20,15 @@
|
||||
namespace ams::spl {
|
||||
|
||||
Result GeneralService::GetConfig(sf::Out<u64> out, u32 which) {
|
||||
return impl::GetConfig(out.GetPointer(), static_cast<SplConfigItem>(which));
|
||||
return impl::GetConfig(out.GetPointer(), static_cast<spl::ConfigItem>(which));
|
||||
}
|
||||
|
||||
Result GeneralService::ExpMod(const sf::OutPointerBuffer &out, const sf::InPointerBuffer &base, const sf::InPointerBuffer &exp, const sf::InPointerBuffer &mod) {
|
||||
return impl::ExpMod(out.GetPointer(), out.GetSize(), base.GetPointer(), base.GetSize(), exp.GetPointer(), exp.GetSize(), mod.GetPointer(), mod.GetSize());
|
||||
Result GeneralService::ModularExponentiate(const sf::OutPointerBuffer &out, const sf::InPointerBuffer &base, const sf::InPointerBuffer &exp, const sf::InPointerBuffer &mod) {
|
||||
return impl::ModularExponentiate(out.GetPointer(), out.GetSize(), base.GetPointer(), base.GetSize(), exp.GetPointer(), exp.GetSize(), mod.GetPointer(), mod.GetSize());
|
||||
}
|
||||
|
||||
Result GeneralService::SetConfig(u32 which, u64 value) {
|
||||
return impl::SetConfig(static_cast<SplConfigItem>(which), value);
|
||||
return impl::SetConfig(static_cast<spl::ConfigItem>(which), value);
|
||||
}
|
||||
|
||||
Result GeneralService::GenerateRandomBytes(const sf::OutPointerBuffer &out) {
|
||||
|
||||
@@ -18,76 +18,17 @@
|
||||
|
||||
namespace ams::spl {
|
||||
|
||||
class GeneralService : public sf::IServiceObject {
|
||||
protected:
|
||||
enum class CommandId {
|
||||
/* 1.0.0+ */
|
||||
GetConfig = 0,
|
||||
ExpMod = 1,
|
||||
GenerateAesKek = 2,
|
||||
LoadAesKey = 3,
|
||||
GenerateAesKey = 4,
|
||||
SetConfig = 5,
|
||||
GenerateRandomBytes = 7,
|
||||
ImportLotusKeyDeprecated = 9,
|
||||
ImportLotusKey = 9,
|
||||
DecryptLotusMessage = 10,
|
||||
IsDevelopment = 11,
|
||||
GenerateSpecificAesKey = 12,
|
||||
DecryptRsaPrivateKeyDeprecated = 13,
|
||||
DecryptRsaPrivateKey = 13,
|
||||
DecryptAesKey = 14,
|
||||
CryptAesCtr = 15,
|
||||
ComputeCmac = 16,
|
||||
ImportEsKeyDeprecated = 17,
|
||||
ImportEsKey = 17,
|
||||
UnwrapTitleKey = 18,
|
||||
LoadTitleKey = 19,
|
||||
|
||||
/* 2.0.0+ */
|
||||
UnwrapCommonTitleKey = 20,
|
||||
AllocateAesKeyslot = 21,
|
||||
FreeAesKeyslot = 22,
|
||||
GetAesKeyslotAvailableEvent = 23,
|
||||
|
||||
/* 3.0.0+ */
|
||||
SetBootReason = 24,
|
||||
GetBootReason = 25,
|
||||
|
||||
/* 5.0.0+ */
|
||||
ImportSslKey = 26,
|
||||
SslExpMod = 27,
|
||||
ImportDrmKey = 28,
|
||||
DrmExpMod = 29,
|
||||
ReEncryptRsaPrivateKey = 30,
|
||||
GetPackage2Hash = 31,
|
||||
|
||||
/* 6.0.0+ */
|
||||
UnwrapElicenseKey = 31, /* re-used command id :( */
|
||||
LoadElicenseKey = 32,
|
||||
};
|
||||
class GeneralService {
|
||||
public:
|
||||
GeneralService() { /* ... */ }
|
||||
virtual ~GeneralService() { /* ... */ }
|
||||
protected:
|
||||
/* Actual commands. */
|
||||
virtual Result GetConfig(sf::Out<u64> out, u32 which);
|
||||
virtual Result ExpMod(const sf::OutPointerBuffer &out, const sf::InPointerBuffer &base, const sf::InPointerBuffer &exp, const sf::InPointerBuffer &mod);
|
||||
virtual Result SetConfig(u32 which, u64 value);
|
||||
virtual Result GenerateRandomBytes(const sf::OutPointerBuffer &out);
|
||||
virtual Result IsDevelopment(sf::Out<bool> is_dev);
|
||||
virtual Result SetBootReason(BootReasonValue boot_reason);
|
||||
virtual Result GetBootReason(sf::Out<BootReasonValue> out);
|
||||
public:
|
||||
DEFINE_SERVICE_DISPATCH_TABLE {
|
||||
MAKE_SERVICE_COMMAND_META(GetConfig),
|
||||
MAKE_SERVICE_COMMAND_META(ExpMod),
|
||||
MAKE_SERVICE_COMMAND_META(SetConfig),
|
||||
MAKE_SERVICE_COMMAND_META(GenerateRandomBytes),
|
||||
MAKE_SERVICE_COMMAND_META(IsDevelopment),
|
||||
MAKE_SERVICE_COMMAND_META(SetBootReason, hos::Version_3_0_0),
|
||||
MAKE_SERVICE_COMMAND_META(GetBootReason, hos::Version_3_0_0),
|
||||
};
|
||||
Result GetConfig(sf::Out<u64> out, u32 which);
|
||||
Result ModularExponentiate(const sf::OutPointerBuffer &out, const sf::InPointerBuffer &base, const sf::InPointerBuffer &exp, const sf::InPointerBuffer &mod);
|
||||
Result SetConfig(u32 which, u64 value);
|
||||
Result GenerateRandomBytes(const sf::OutPointerBuffer &out);
|
||||
Result IsDevelopment(sf::Out<bool> is_dev);
|
||||
Result SetBootReason(BootReasonValue boot_reason);
|
||||
Result GetBootReason(sf::Out<BootReasonValue> out);
|
||||
};
|
||||
static_assert(spl::impl::IsIGeneralInterface<GeneralService>);
|
||||
|
||||
}
|
||||
|
||||
@@ -138,18 +138,18 @@ int main(int argc, char **argv)
|
||||
spl::impl::Initialize();
|
||||
|
||||
/* Create services. */
|
||||
R_ABORT_UNLESS(g_server_manager.RegisterServer<spl::RandomService>(RandomServiceName, RandomMaxSessions));
|
||||
R_ABORT_UNLESS((g_server_manager.RegisterServer<spl::impl::IRandomInterface, spl::RandomService>(RandomServiceName, RandomMaxSessions)));
|
||||
if (hos::GetVersion() >= hos::Version_4_0_0) {
|
||||
R_ABORT_UNLESS(g_server_manager.RegisterServer<spl::GeneralService>(GeneralServiceName, GeneralMaxSessions));
|
||||
R_ABORT_UNLESS(g_server_manager.RegisterServer<spl::CryptoService>(CryptoServiceName, CryptoMaxSessions));
|
||||
R_ABORT_UNLESS(g_server_manager.RegisterServer<spl::SslService>(SslServiceName, SslMaxSessions));
|
||||
R_ABORT_UNLESS(g_server_manager.RegisterServer<spl::EsService>(EsServiceName, EsMaxSessions));
|
||||
R_ABORT_UNLESS(g_server_manager.RegisterServer<spl::FsService>(FsServiceName, FsMaxSessions));
|
||||
R_ABORT_UNLESS((g_server_manager.RegisterServer<spl::impl::IGeneralInterface, spl::GeneralService>(GeneralServiceName, GeneralMaxSessions)));
|
||||
R_ABORT_UNLESS((g_server_manager.RegisterServer<spl::impl::ICryptoInterface, spl::CryptoService>(CryptoServiceName, CryptoMaxSessions)));
|
||||
R_ABORT_UNLESS((g_server_manager.RegisterServer<spl::impl::ISslInterface, spl::SslService>(SslServiceName, SslMaxSessions)));
|
||||
R_ABORT_UNLESS((g_server_manager.RegisterServer<spl::impl::IEsInterface, spl::EsService>(EsServiceName, EsMaxSessions)));
|
||||
R_ABORT_UNLESS((g_server_manager.RegisterServer<spl::impl::IFsInterface, spl::FsService>(FsServiceName, FsMaxSessions)));
|
||||
if (hos::GetVersion() >= hos::Version_5_0_0) {
|
||||
R_ABORT_UNLESS(g_server_manager.RegisterServer<spl::ManuService>(ManuServiceName, ManuMaxSessions));
|
||||
R_ABORT_UNLESS((g_server_manager.RegisterServer<spl::impl::IManuInterface, spl::ManuService>(ManuServiceName, ManuMaxSessions)));
|
||||
}
|
||||
} else {
|
||||
R_ABORT_UNLESS(g_server_manager.RegisterServer<spl::DeprecatedService>(DeprecatedServiceName, DeprecatedMaxSessions));
|
||||
R_ABORT_UNLESS((g_server_manager.RegisterServer<spl::impl::IDeprecatedGeneralInterface, spl::DeprecatedService>(DeprecatedServiceName, DeprecatedMaxSessions)));
|
||||
}
|
||||
|
||||
/* Loop forever, servicing our services. */
|
||||
|
||||
@@ -19,8 +19,8 @@
|
||||
|
||||
namespace ams::spl {
|
||||
|
||||
Result ManuService::ReEncryptRsaPrivateKey(const sf::OutPointerBuffer &out, const sf::InPointerBuffer &src, AccessKey access_key_dec, KeySource source_dec, AccessKey access_key_enc, KeySource source_enc, u32 option) {
|
||||
return impl::ReEncryptRsaPrivateKey(out.GetPointer(), out.GetSize(), src.GetPointer(), src.GetSize(), access_key_dec, source_dec, access_key_enc, source_enc, option);
|
||||
Result ManuService::ReencryptDeviceUniqueData(const sf::OutPointerBuffer &out, const sf::InPointerBuffer &src, AccessKey access_key_dec, KeySource source_dec, AccessKey access_key_enc, KeySource source_enc, u32 option) {
|
||||
return impl::ReencryptDeviceUniqueData(out.GetPointer(), out.GetSize(), src.GetPointer(), src.GetSize(), access_key_dec, source_dec, access_key_enc, source_enc, option);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -14,40 +14,15 @@
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#pragma once
|
||||
#include "spl_rsa_service.hpp"
|
||||
#include "spl_device_unique_data_service.hpp"
|
||||
|
||||
namespace ams::spl {
|
||||
|
||||
class ManuService : public RsaService {
|
||||
class ManuService : public DeviceUniqueDataService {
|
||||
public:
|
||||
ManuService() : RsaService() { /* ... */ }
|
||||
|
||||
virtual ~ManuService() { /* ... */ }
|
||||
protected:
|
||||
/* Actual commands. */
|
||||
virtual Result ReEncryptRsaPrivateKey(const sf::OutPointerBuffer &out, const sf::InPointerBuffer &src, AccessKey access_key_dec, KeySource source_dec, AccessKey access_key_enc, KeySource source_enc, u32 option);
|
||||
public:
|
||||
DEFINE_SERVICE_DISPATCH_TABLE {
|
||||
MAKE_SERVICE_COMMAND_META(GetConfig),
|
||||
MAKE_SERVICE_COMMAND_META(ExpMod),
|
||||
MAKE_SERVICE_COMMAND_META(SetConfig),
|
||||
MAKE_SERVICE_COMMAND_META(GenerateRandomBytes),
|
||||
MAKE_SERVICE_COMMAND_META(IsDevelopment),
|
||||
MAKE_SERVICE_COMMAND_META(SetBootReason, hos::Version_3_0_0),
|
||||
MAKE_SERVICE_COMMAND_META(GetBootReason, hos::Version_3_0_0),
|
||||
MAKE_SERVICE_COMMAND_META(GenerateAesKek),
|
||||
MAKE_SERVICE_COMMAND_META(LoadAesKey),
|
||||
MAKE_SERVICE_COMMAND_META(GenerateAesKey),
|
||||
MAKE_SERVICE_COMMAND_META(DecryptAesKey),
|
||||
MAKE_SERVICE_COMMAND_META(CryptAesCtr),
|
||||
MAKE_SERVICE_COMMAND_META(ComputeCmac),
|
||||
MAKE_SERVICE_COMMAND_META(AllocateAesKeyslot, hos::Version_2_0_0),
|
||||
MAKE_SERVICE_COMMAND_META(FreeAesKeyslot, hos::Version_2_0_0),
|
||||
MAKE_SERVICE_COMMAND_META(GetAesKeyslotAvailableEvent, hos::Version_2_0_0),
|
||||
MAKE_SERVICE_COMMAND_META(DecryptRsaPrivateKeyDeprecated, hos::Version_4_0_0, hos::Version_4_1_0),
|
||||
MAKE_SERVICE_COMMAND_META(DecryptRsaPrivateKey, hos::Version_5_0_0),
|
||||
MAKE_SERVICE_COMMAND_META(ReEncryptRsaPrivateKey, hos::Version_5_0_0),
|
||||
};
|
||||
Result ReencryptDeviceUniqueData(const sf::OutPointerBuffer &out, const sf::InPointerBuffer &src, AccessKey access_key_dec, KeySource source_dec, AccessKey access_key_enc, KeySource source_enc, u32 option);
|
||||
};
|
||||
static_assert(spl::impl::IsIManuInterface<ManuService>);
|
||||
|
||||
}
|
||||
|
||||
@@ -18,21 +18,11 @@
|
||||
|
||||
namespace ams::spl {
|
||||
|
||||
class RandomService final : public sf::IServiceObject {
|
||||
protected:
|
||||
enum class CommandId {
|
||||
GenerateRandomBytes = 0,
|
||||
};
|
||||
class RandomService final {
|
||||
public:
|
||||
RandomService() { /* ... */ }
|
||||
virtual ~RandomService() { /* ... */ }
|
||||
private:
|
||||
/* Actual commands. */
|
||||
virtual Result GenerateRandomBytes(const sf::OutBuffer &out);
|
||||
public:
|
||||
DEFINE_SERVICE_DISPATCH_TABLE {
|
||||
MAKE_SERVICE_COMMAND_META(GenerateRandomBytes),
|
||||
};
|
||||
Result GenerateRandomBytes(const sf::OutBuffer &out);
|
||||
};
|
||||
static_assert(spl::impl::IsIRandomInterface<RandomService>);
|
||||
|
||||
}
|
||||
|
||||
@@ -1,30 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2018-2020 Atmosphère-NX
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include <stratosphere.hpp>
|
||||
#include "spl_api_impl.hpp"
|
||||
#include "spl_rsa_service.hpp"
|
||||
|
||||
namespace ams::spl {
|
||||
|
||||
Result RsaService::DecryptRsaPrivateKeyDeprecated(const sf::OutPointerBuffer &dst, const sf::InPointerBuffer &src, AccessKey access_key, KeySource key_source, u32 option) {
|
||||
return impl::DecryptRsaPrivateKey(dst.GetPointer(), dst.GetSize(), src.GetPointer(), src.GetSize(), access_key, key_source, option);
|
||||
}
|
||||
|
||||
Result RsaService::DecryptRsaPrivateKey(const sf::OutPointerBuffer &dst, const sf::InPointerBuffer &src, AccessKey access_key, KeySource key_source) {
|
||||
return impl::DecryptRsaPrivateKey(dst.GetPointer(), dst.GetSize(), src.GetPointer(), src.GetSize(), access_key, key_source, static_cast<u32>(smc::DecryptOrImportMode::DecryptRsaPrivateKey));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -19,12 +19,12 @@
|
||||
|
||||
namespace ams::spl {
|
||||
|
||||
Result SslService::ImportSslKey(const sf::InPointerBuffer &src, AccessKey access_key, KeySource key_source) {
|
||||
return impl::ImportSslKey(src.GetPointer(), src.GetSize(), access_key, key_source);
|
||||
Result SslService::DecryptAndStoreSslClientCertKey(const sf::InPointerBuffer &src, AccessKey access_key, KeySource key_source) {
|
||||
return impl::DecryptAndStoreSslClientCertKey(src.GetPointer(), src.GetSize(), access_key, key_source);
|
||||
}
|
||||
|
||||
Result SslService::SslExpMod(const sf::OutPointerBuffer &out, const sf::InPointerBuffer &base, const sf::InPointerBuffer &mod) {
|
||||
return impl::SslExpMod(out.GetPointer(), out.GetSize(), base.GetPointer(), base.GetSize(), mod.GetPointer(), mod.GetSize());
|
||||
Result SslService::ModularExponentiateWithSslClientCertKey(const sf::OutPointerBuffer &out, const sf::InPointerBuffer &base, const sf::InPointerBuffer &mod) {
|
||||
return impl::ModularExponentiateWithSslClientCertKey(out.GetPointer(), out.GetSize(), base.GetPointer(), base.GetSize(), mod.GetPointer(), mod.GetSize());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -14,42 +14,16 @@
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#pragma once
|
||||
#include "spl_rsa_service.hpp"
|
||||
#include "spl_device_unique_data_service.hpp"
|
||||
|
||||
namespace ams::spl {
|
||||
|
||||
class SslService : public RsaService {
|
||||
class SslService : public DeviceUniqueDataService {
|
||||
public:
|
||||
SslService() : RsaService() { /* ... */ }
|
||||
virtual ~SslService() { /* ... */ }
|
||||
protected:
|
||||
/* Actual commands. */
|
||||
virtual Result ImportSslKey(const sf::InPointerBuffer &src, AccessKey access_key, KeySource key_source);
|
||||
virtual Result SslExpMod(const sf::OutPointerBuffer &out, const sf::InPointerBuffer &base, const sf::InPointerBuffer &mod);
|
||||
public:
|
||||
DEFINE_SERVICE_DISPATCH_TABLE {
|
||||
MAKE_SERVICE_COMMAND_META(GetConfig),
|
||||
MAKE_SERVICE_COMMAND_META(ExpMod),
|
||||
MAKE_SERVICE_COMMAND_META(SetConfig),
|
||||
MAKE_SERVICE_COMMAND_META(GenerateRandomBytes),
|
||||
MAKE_SERVICE_COMMAND_META(IsDevelopment),
|
||||
MAKE_SERVICE_COMMAND_META(SetBootReason, hos::Version_3_0_0),
|
||||
MAKE_SERVICE_COMMAND_META(GetBootReason, hos::Version_3_0_0),
|
||||
MAKE_SERVICE_COMMAND_META(GenerateAesKek),
|
||||
MAKE_SERVICE_COMMAND_META(LoadAesKey),
|
||||
MAKE_SERVICE_COMMAND_META(GenerateAesKey),
|
||||
MAKE_SERVICE_COMMAND_META(DecryptAesKey),
|
||||
MAKE_SERVICE_COMMAND_META(CryptAesCtr),
|
||||
MAKE_SERVICE_COMMAND_META(ComputeCmac),
|
||||
MAKE_SERVICE_COMMAND_META(AllocateAesKeyslot, hos::Version_2_0_0),
|
||||
MAKE_SERVICE_COMMAND_META(FreeAesKeyslot, hos::Version_2_0_0),
|
||||
MAKE_SERVICE_COMMAND_META(GetAesKeyslotAvailableEvent, hos::Version_2_0_0),
|
||||
MAKE_SERVICE_COMMAND_META(DecryptRsaPrivateKeyDeprecated, hos::Version_4_0_0, hos::Version_4_1_0),
|
||||
MAKE_SERVICE_COMMAND_META(DecryptRsaPrivateKey, hos::Version_5_0_0),
|
||||
MAKE_SERVICE_COMMAND_META(ImportSslKey, hos::Version_5_0_0),
|
||||
MAKE_SERVICE_COMMAND_META(SslExpMod, hos::Version_5_0_0),
|
||||
|
||||
};
|
||||
Result DecryptAndStoreSslClientCertKey(const sf::InPointerBuffer &src, AccessKey access_key, KeySource key_source);
|
||||
Result ModularExponentiateWithSslClientCertKey(const sf::OutPointerBuffer &out, const sf::InPointerBuffer &base, const sf::InPointerBuffer &mod);
|
||||
};
|
||||
static_assert(spl::impl::IsISslInterface<SslService>);
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user