From 15773e4755fd1c4d2c1aaf627bb4cade542276bb Mon Sep 17 00:00:00 2001 From: Michael Scire Date: Wed, 23 Oct 2019 00:07:20 -0700 Subject: [PATCH] libstrat: fix domain issues. in/out objects now work. --- .../dmnt/source/dmnt_service_target_io.cpp | 2 +- stratosphere/libstratosphere/Makefile | 14 +--- .../stratosphere/results/sf_results.hpp | 1 + .../sf/cmif/sf_cmif_service_object_holder.hpp | 20 ++++-- .../sf/hipc/sf_hipc_server_manager.hpp | 9 +-- .../hipc/sf_hipc_server_session_manager.hpp | 9 +++ .../sf/impl/sf_impl_command_serialization.hpp | 65 +++++++++++++------ .../stratosphere/sf/sf_service_object.hpp | 12 ++++ .../libstratosphere/source/cfg/cfg_flags.cpp | 2 +- .../source/cfg/cfg_override.cpp | 2 +- .../source/cfg/cfg_sd_card.cpp | 4 +- .../libstratosphere/source/dmnt/dmntcht.c | 15 +++-- .../source/sf/cmif/sf_cmif_domain_manager.cpp | 3 + .../sf/cmif/sf_cmif_domain_service_object.cpp | 4 +- .../sf_hipc_server_domain_session_manager.cpp | 12 +--- .../libstratosphere/source/sm/sm_ams.c | 42 ++++++------ .../libstratosphere/source/sm/sm_ams.h | 16 ++--- .../libstratosphere/source/sm/sm_api.cpp | 10 +-- .../source/sm/sm_manager_api.cpp | 3 +- .../libstratosphere/source/sm/sm_mitm_api.cpp | 12 ++-- .../libstratosphere/source/sm/sm_utils.hpp | 7 ++ .../libstratosphere/source/sm/smm_ams.c | 8 +-- .../libstratosphere/source/sm/smm_ams.h | 2 +- 23 files changed, 161 insertions(+), 113 deletions(-) diff --git a/stratosphere/dmnt/source/dmnt_service_target_io.cpp b/stratosphere/dmnt/source/dmnt_service_target_io.cpp index 76f5d4f70..4cac9cf10 100644 --- a/stratosphere/dmnt/source/dmnt_service_target_io.cpp +++ b/stratosphere/dmnt/source/dmnt_service_target_io.cpp @@ -55,7 +55,7 @@ namespace sts::dmnt { return ResultSuccess; } - R_TRY(fsMountSdcard(&g_sd_fs)); + R_TRY(fsOpenSdCardFileSystem(&g_sd_fs)); g_sd_initialized = true; return ResultSuccess; } diff --git a/stratosphere/libstratosphere/Makefile b/stratosphere/libstratosphere/Makefile index 581691221..57b967733 100644 --- a/stratosphere/libstratosphere/Makefile +++ b/stratosphere/libstratosphere/Makefile @@ -87,7 +87,7 @@ export INCLUDE := $(foreach dir,$(INCLUDES),-I$(CURDIR)/$(dir)) \ .PHONY: clean all #--------------------------------------------------------------------------------- -all: lib/$(TARGET).a lib/$(TARGET)d.a +all: lib/$(TARGET).a lib: @[ -d $@ ] || mkdir -p $@ @@ -95,9 +95,6 @@ lib: release: @[ -d $@ ] || mkdir -p $@ -debug: - @[ -d $@ ] || mkdir -p $@ - lib/$(TARGET).a : lib release $(SOURCES) $(INCLUDES) @$(MAKE) BUILD=release OUTPUT=$(CURDIR)/$@ \ BUILD_CFLAGS="-DNDEBUG=1 -O2" \ @@ -105,13 +102,6 @@ lib/$(TARGET).a : lib release $(SOURCES) $(INCLUDES) --no-print-directory -C release \ -f $(CURDIR)/Makefile -lib/$(TARGET)d.a : lib debug $(SOURCES) $(INCLUDES) - @$(MAKE) BUILD=debug OUTPUT=$(CURDIR)/$@ \ - BUILD_CFLAGS="-DDEBUG=1 -Og" \ - DEPSDIR=$(CURDIR)/debug \ - --no-print-directory -C debug \ - -f $(CURDIR)/Makefile - dist-bin: all @tar --exclude=*~ -cjf $(TARGET).tar.bz2 include lib @@ -123,7 +113,7 @@ dist: dist-src dist-bin #--------------------------------------------------------------------------------- clean: @echo clean ... - @rm -fr release debug lib *.bz2 + @rm -fr release lib *.bz2 #--------------------------------------------------------------------------------- else diff --git a/stratosphere/libstratosphere/include/stratosphere/results/sf_results.hpp b/stratosphere/libstratosphere/include/stratosphere/results/sf_results.hpp index 9cf251cfe..fc0810c43 100644 --- a/stratosphere/libstratosphere/include/stratosphere/results/sf_results.hpp +++ b/stratosphere/libstratosphere/include/stratosphere/results/sf_results.hpp @@ -28,6 +28,7 @@ static constexpr Result ResultServiceFrameworkUnknownCmifCommandId = MAKERE static constexpr Result ResultServiceFrameworkInvalidCmifOutRawSize = MAKERESULT(Module_ServiceFramework, 232); static constexpr Result ResultServiceFrameworkInvalidCmifNumInObjects = MAKERESULT(Module_ServiceFramework, 235); static constexpr Result ResultServiceFrameworkInvalidCmifNumOutObjects = MAKERESULT(Module_ServiceFramework, 236); +static constexpr Result ResultServiceFrameworkInvalidCmifInObject = MAKERESULT(Module_ServiceFramework, 239); static constexpr Result ResultServiceFrameworkTargetNotFound = MAKERESULT(Module_ServiceFramework, 261); diff --git a/stratosphere/libstratosphere/include/stratosphere/sf/cmif/sf_cmif_service_object_holder.hpp b/stratosphere/libstratosphere/include/stratosphere/sf/cmif/sf_cmif_service_object_holder.hpp index e585f6ce0..2d8baff6d 100644 --- a/stratosphere/libstratosphere/include/stratosphere/sf/cmif/sf_cmif_service_object_holder.hpp +++ b/stratosphere/libstratosphere/include/stratosphere/sf/cmif/sf_cmif_service_object_holder.hpp @@ -32,6 +32,10 @@ namespace sts::sf::cmif { /* Default constructor, null all members. */ ServiceObjectHolder() : srv(nullptr), dispatch_meta(nullptr) { /* ... */ } + ~ServiceObjectHolder() { + this->dispatch_meta = nullptr; + } + /* Ensure correct type id at runtime through template constructor. */ template constexpr explicit ServiceObjectHolder(std::shared_ptr &&s) { @@ -40,7 +44,10 @@ namespace sts::sf::cmif { } /* Move constructor, assignment operator. */ - ServiceObjectHolder(ServiceObjectHolder &&o) : srv(std::move(o.srv)), dispatch_meta(std::move(o.dispatch_meta)) { /* ... */ } + ServiceObjectHolder(ServiceObjectHolder &&o) : srv(std::move(o.srv)), dispatch_meta(std::move(o.dispatch_meta)) { + o.dispatch_meta = nullptr; + } + ServiceObjectHolder &operator=(ServiceObjectHolder &&o) { ServiceObjectHolder tmp(std::move(o)); tmp.Swap(*this); @@ -80,14 +87,19 @@ namespace sts::sf::cmif { } template - ServiceImpl *GetServiceObject() const { + constexpr inline bool IsServiceObjectValid() const { + return this->GetServiceId() == GetServiceDispatchMeta()->GetServiceId(); + } + + template + inline std::shared_ptr GetServiceObject() const { if (this->GetServiceId() == GetServiceDispatchMeta()->GetServiceId()) { - return static_cast(this->srv.get()); + return std::static_pointer_cast(this->srv); } return nullptr; } - sf::IServiceObject *GetServiceObjectUnsafe() const { + inline sf::IServiceObject *GetServiceObjectUnsafe() const { return this->srv.get(); } diff --git a/stratosphere/libstratosphere/include/stratosphere/sf/hipc/sf_hipc_server_manager.hpp b/stratosphere/libstratosphere/include/stratosphere/sf/hipc/sf_hipc_server_manager.hpp index c0b818a40..c1b938453 100644 --- a/stratosphere/libstratosphere/include/stratosphere/sf/hipc/sf_hipc_server_manager.hpp +++ b/stratosphere/libstratosphere/include/stratosphere/sf/hipc/sf_hipc_server_manager.hpp @@ -100,10 +100,7 @@ namespace sts::sf::hipc { if constexpr (IsMitmServer) { /* Custom deleter ensures that nothing goes awry. */ /* TODO: Should this just be a custom wrapper object? */ - std::shared_ptr<::Service> forward_service(new ::Service(), [](::Service *srv) { - serviceClose(srv); - delete srv; - }); + std::shared_ptr<::Service> forward_service = std::move(ServerSession::CreateForwardService()); /* Get mitm forward session. */ os::ProcessId client_pid; @@ -348,12 +345,8 @@ namespace sts::sf::hipc { std::memset(this->pointer_buffer_storage, 0, sizeof(this->pointer_buffer_storage)); std::memset(this->saved_message_storage, 0, sizeof(this->saved_message_storage)); if constexpr (ManagerOptions::MaxDomains > 0) { - std::memset(this->domain_storages, 0, sizeof(this->domain_storages)); std::memset(this->domain_allocated, 0, sizeof(this->domain_allocated)); } - if constexpr (ManagerOptions::MaxDomainObjects > 0) { - std::memset(this->domain_entry_storages, 0, sizeof(this->domain_entry_storages)); - } /* Set resource starts. */ this->pointer_buffers_start = util::AlignUp(reinterpret_cast(this->pointer_buffer_storage), 0x10); diff --git a/stratosphere/libstratosphere/include/stratosphere/sf/hipc/sf_hipc_server_session_manager.hpp b/stratosphere/libstratosphere/include/stratosphere/sf/hipc/sf_hipc_server_session_manager.hpp index 05b3f581f..77e2c4f35 100644 --- a/stratosphere/libstratosphere/include/stratosphere/sf/hipc/sf_hipc_server_session_manager.hpp +++ b/stratosphere/libstratosphere/include/stratosphere/sf/hipc/sf_hipc_server_session_manager.hpp @@ -73,6 +73,15 @@ namespace sts::sf::hipc { } Result ForwardRequest(const cmif::ServiceDispatchContext &ctx) const; + + static inline void ForwardServiceDeleter(Service *srv) { + serviceClose(srv); + delete srv; + } + + static inline std::shared_ptr<::Service> CreateForwardService() { + return std::shared_ptr<::Service>(new ::Service(), ForwardServiceDeleter); + } }; class ServerSessionManager { diff --git a/stratosphere/libstratosphere/include/stratosphere/sf/impl/sf_impl_command_serialization.hpp b/stratosphere/libstratosphere/include/stratosphere/sf/impl/sf_impl_command_serialization.hpp index 37fcc91c3..bba5d3545 100644 --- a/stratosphere/libstratosphere/include/stratosphere/sf/impl/sf_impl_command_serialization.hpp +++ b/stratosphere/libstratosphere/include/stratosphere/sf/impl/sf_impl_command_serialization.hpp @@ -70,6 +70,9 @@ namespace sts::sf { } + template + class IsOutForceEnabled> : public std::true_type{}; + template class Out> : public impl::OutObjectTag { static_assert(std::is_base_of::value, "Out> requires ServiceObject base."); @@ -86,7 +89,7 @@ namespace sts::sf { Out(cmif::ServiceObjectHolder *s, cmif::DomainObjectId *o) : srv(s), object_id(o) { /* ... */ } void SetValue(std::shared_ptr &&s, cmif::DomainObjectId new_object_id = cmif::InvalidDomainObjectId) { - *this->srv = ServiceObjectHolder(std::move(s)); + *this->srv = cmif::ServiceObjectHolder(std::move(s)); if (new_object_id != cmif::InvalidDomainObjectId) { *this->object_id = new_object_id; } @@ -655,7 +658,18 @@ namespace sts::sf::impl { std::array out_object_holders; std::array out_object_ids; public: - constexpr InOutObjectHolder() : in_object_holders(), out_object_holders() { /* ... */ } + constexpr InOutObjectHolder() : in_object_holders(), out_object_holders() { + #define _SF_IN_OUT_HOLDER_INITIALIZE_OBJECT_ID(n) if constexpr (NumOutObjects > n) { this->out_object_ids[n] = cmif::InvalidDomainObjectId; } + _SF_IN_OUT_HOLDER_INITIALIZE_OBJECT_ID(0) + _SF_IN_OUT_HOLDER_INITIALIZE_OBJECT_ID(1) + _SF_IN_OUT_HOLDER_INITIALIZE_OBJECT_ID(2) + _SF_IN_OUT_HOLDER_INITIALIZE_OBJECT_ID(3) + _SF_IN_OUT_HOLDER_INITIALIZE_OBJECT_ID(4) + _SF_IN_OUT_HOLDER_INITIALIZE_OBJECT_ID(5) + _SF_IN_OUT_HOLDER_INITIALIZE_OBJECT_ID(6) + _SF_IN_OUT_HOLDER_INITIALIZE_OBJECT_ID(7) + #undef _SF_IN_OUT_HOLDER_INITIALIZE_OBJECT_ID + } Result GetInObjects(const sf::cmif::ServerMessageProcessor *processor) { if constexpr (NumInObjects > 0) { @@ -664,25 +678,36 @@ namespace sts::sf::impl { return ResultSuccess; } - Result ValidateInObjects() { - /* TODO: Actually validate. */ - if constexpr (NumInObjects > 0) { - /* Need to call holder.template GetServiceObject<>() for each object */ - } + template + constexpr inline Result ValidateInObjects() const { + static_assert(std::tuple_size::value == NumInObjects); + #define _SF_IN_OUT_HOLDER_VALIDATE_IN_OBJECT(n) do { \ + if constexpr (NumInObjects > n) { \ + using SharedPtrToServiceImplType = typename std::tuple_element::type; \ + using ServiceImplType = typename SharedPtrToServiceImplType::element_type; \ + R_UNLESS((this->in_object_holders[n].template IsServiceObjectValid()), ResultServiceFrameworkInvalidCmifInObject); \ + } \ + } while (0) + _SF_IN_OUT_HOLDER_VALIDATE_IN_OBJECT(0); + _SF_IN_OUT_HOLDER_VALIDATE_IN_OBJECT(1); + _SF_IN_OUT_HOLDER_VALIDATE_IN_OBJECT(2); + _SF_IN_OUT_HOLDER_VALIDATE_IN_OBJECT(3); + _SF_IN_OUT_HOLDER_VALIDATE_IN_OBJECT(4); + _SF_IN_OUT_HOLDER_VALIDATE_IN_OBJECT(5); + _SF_IN_OUT_HOLDER_VALIDATE_IN_OBJECT(6); + _SF_IN_OUT_HOLDER_VALIDATE_IN_OBJECT(7); return ResultSuccess; } template - std::shared_ptr &&GetInObject() const { - auto &&holder = this->in_object_holders[Index]; - auto obj = holder.template GetServiceObject(); - STS_ASSERT(obj); - return std::move(obj); + std::shared_ptr GetInObject() const { + /* We know from ValidateInObjects() that this will succeed always. */ + return this->in_object_holders[Index].template GetServiceObject(); } template - Out GetOutObject() const { - return Out(&this->out_object_holders[Index], &this->out_object_ids[Index]); + Out> GetOutObject() { + return Out>(&this->out_object_holders[Index], &this->out_object_ids[Index]); } constexpr void SetOutObjects(const cmif::ServiceDispatchContext &ctx, const HipcRequest &response) { @@ -947,7 +972,7 @@ namespace sts::sf::impl { /* Argument deserialization. */ private: template::type> - NX_CONSTEXPR T DeserializeArgumentImpl(const cmif::ServiceDispatchContext &ctx, const cmif::PointerAndSize &in_raw_data, const OutRawHolderType &out_raw_holder, const BufferArrayType &buffers, OutHandleHolderType &out_handles_holder, const InOutObjectHolderType &in_out_objects_holder) { + NX_CONSTEXPR T DeserializeArgumentImpl(const cmif::ServiceDispatchContext &ctx, const cmif::PointerAndSize &in_raw_data, const OutRawHolderType &out_raw_holder, const BufferArrayType &buffers, OutHandleHolderType &out_handles_holder, InOutObjectHolderType &in_out_objects_holder) { constexpr auto Info = CommandMeta::ArgumentSerializationInfos[Index]; if constexpr (Info.arg_type == ArgumentType::InData) { /* New in rawdata. */ @@ -982,10 +1007,10 @@ namespace sts::sf::impl { } } else if constexpr (Info.arg_type == ArgumentType::InObject) { /* New InObject. */ - return std::move(in_out_objects_holder.template GetInObject::type>()); + return in_out_objects_holder.template GetInObject(); } else if constexpr (Info.arg_type == ArgumentType::OutObject) { /* New OutObject. */ - return in_out_objects_holder.template GetOutObject(); + return in_out_objects_holder.template GetOutObject(); } else if constexpr (Info.arg_type == ArgumentType::Buffer) { /* Buffers were already processed earlier. */ if constexpr (sf::IsLargeData) { @@ -1009,11 +1034,11 @@ namespace sts::sf::impl { } template - NX_CONSTEXPR ArgsType DeserializeArgumentsImpl(const cmif::ServiceDispatchContext &ctx, const cmif::PointerAndSize &in_raw_data, const OutRawHolderType &out_raw_holder, const BufferArrayType &buffers, OutHandleHolderType &out_handles_holder, const InOutObjectHolderType &in_out_objects_holder, std::index_sequence) { + NX_CONSTEXPR ArgsType DeserializeArgumentsImpl(const cmif::ServiceDispatchContext &ctx, const cmif::PointerAndSize &in_raw_data, const OutRawHolderType &out_raw_holder, const BufferArrayType &buffers, OutHandleHolderType &out_handles_holder, InOutObjectHolderType &in_out_objects_holder, std::index_sequence) { return ArgsType { DeserializeArgumentImpl(ctx, in_raw_data, out_raw_holder, buffers, out_handles_holder, in_out_objects_holder)..., }; } public: - NX_CONSTEXPR ArgsType DeserializeArguments(const cmif::ServiceDispatchContext &ctx, const cmif::PointerAndSize &in_raw_data, const OutRawHolderType &out_raw_holder, const BufferArrayType &buffers, OutHandleHolderType &out_handles_holder, const InOutObjectHolderType &in_out_objects_holder) { + NX_CONSTEXPR ArgsType DeserializeArguments(const cmif::ServiceDispatchContext &ctx, const cmif::PointerAndSize &in_raw_data, const OutRawHolderType &out_raw_holder, const BufferArrayType &buffers, OutHandleHolderType &out_handles_holder, InOutObjectHolderType &in_out_objects_holder) { return DeserializeArgumentsImpl(ctx, in_raw_data, out_raw_holder, buffers, out_handles_holder, in_out_objects_holder, std::make_index_sequence::value>{}); } }; @@ -1063,7 +1088,7 @@ namespace sts::sf::impl { /* Process input/output objects. */ R_TRY(in_out_objects_holder.GetInObjects(ctx.processor)); - R_TRY(in_out_objects_holder.ValidateInObjects()); + R_TRY((in_out_objects_holder.template ValidateInObjects())); /* Decoding/Invocation. */ { diff --git a/stratosphere/libstratosphere/include/stratosphere/sf/sf_service_object.hpp b/stratosphere/libstratosphere/include/stratosphere/sf/sf_service_object.hpp index fe3c6d7f4..15e86cd7d 100644 --- a/stratosphere/libstratosphere/include/stratosphere/sf/sf_service_object.hpp +++ b/stratosphere/libstratosphere/include/stratosphere/sf/sf_service_object.hpp @@ -38,6 +38,18 @@ namespace sts::sf { static_assert(std::is_base_of::value, "ServiceObjectTraits requires ServiceObject"); static constexpr bool IsMitmServiceObject = std::is_base_of::value; + + struct SharedPointerHelper { + + static constexpr void EmptyDelete(T *) { /* Empty deleter, for fake shared pointer. */ } + + static constexpr std::shared_ptr GetEmptyDeleteSharedPointer(T *srv_obj) { + return std::shared_ptr(srv_obj, EmptyDelete); + } + + }; }; + + } \ No newline at end of file diff --git a/stratosphere/libstratosphere/source/cfg/cfg_flags.cpp b/stratosphere/libstratosphere/source/cfg/cfg_flags.cpp index ab9d17a3b..1d4647844 100644 --- a/stratosphere/libstratosphere/source/cfg/cfg_flags.cpp +++ b/stratosphere/libstratosphere/source/cfg/cfg_flags.cpp @@ -31,7 +31,7 @@ namespace sts::cfg { /* Mount the SD card. */ FsFileSystem sd_fs = {}; - if (R_FAILED(fsMountSdcard(&sd_fs))) { + if (R_FAILED(fsOpenSdCardFileSystem(&sd_fs))) { return false; } ON_SCOPE_EXIT { serviceClose(&sd_fs.s); }; diff --git a/stratosphere/libstratosphere/source/cfg/cfg_override.cpp b/stratosphere/libstratosphere/source/cfg/cfg_override.cpp index 332b517f2..218f3055c 100644 --- a/stratosphere/libstratosphere/source/cfg/cfg_override.cpp +++ b/stratosphere/libstratosphere/source/cfg/cfg_override.cpp @@ -178,7 +178,7 @@ namespace sts::cfg { void ParseIniFile(util::ini::Handler handler, const char *path, void *user_ctx) { /* Mount the SD card. */ FsFileSystem sd_fs = {}; - if (R_FAILED(fsMountSdcard(&sd_fs))) { + if (R_FAILED(fsOpenSdCardFileSystem(&sd_fs))) { return; } ON_SCOPE_EXIT { serviceClose(&sd_fs.s); }; diff --git a/stratosphere/libstratosphere/source/cfg/cfg_sd_card.cpp b/stratosphere/libstratosphere/source/cfg/cfg_sd_card.cpp index fb094b6b8..feada310f 100644 --- a/stratosphere/libstratosphere/source/cfg/cfg_sd_card.cpp +++ b/stratosphere/libstratosphere/source/cfg/cfg_sd_card.cpp @@ -58,14 +58,14 @@ namespace sts::cfg { Result TryInitializeSdCard() { R_TRY(CheckSdCardServicesReady()); - R_ASSERT(fsMountSdcard(&g_sd_card_filesystem)); + R_ASSERT(fsOpenSdCardFileSystem(&g_sd_card_filesystem)); g_sd_card_initialized = true; return ResultSuccess; } void InitializeSdCard() { WaitSdCardServicesReadyImpl(); - R_ASSERT(fsMountSdcard(&g_sd_card_filesystem)); + R_ASSERT(fsOpenSdCardFileSystem(&g_sd_card_filesystem)); g_sd_card_initialized = true; } diff --git a/stratosphere/libstratosphere/source/dmnt/dmntcht.c b/stratosphere/libstratosphere/source/dmnt/dmntcht.c index 86ed9be2f..05bb1b996 100644 --- a/stratosphere/libstratosphere/source/dmnt/dmntcht.c +++ b/stratosphere/libstratosphere/source/dmnt/dmntcht.c @@ -37,6 +37,7 @@ Result dmntchtHasCheatProcess(bool *out) { u8 tmp; Result rc = serviceDispatchOut(&g_dmntchtSrv, 65000, tmp); if (R_SUCCEEDED(rc) && out) *out = tmp & 1; + return rc; } Result dmntchtGetCheatProcessEvent(Event *event) { @@ -47,7 +48,7 @@ Result dmntchtGetCheatProcessEvent(Event *event) { ); if (R_SUCCEEDED(rc)) { - eventLoadRemote(&g_dmntchtSrv, evt_handle, true); + eventLoadRemote(event, evt_handle, true); } return rc; @@ -77,11 +78,11 @@ static Result _dmntchtCmdInU32NoOut(u32 in, u32 cmd_id) { } Result dmntchtGetCheatProcessMappingCount(u64 *out_count) { - return _dmntchtGetCount(65100, out_count); + return _dmntchtGetCount(out_count, 65100); } Result dmntchtGetCheatProcessMappings(MemoryInfo *buffer, u64 max_count, u64 offset, u64 *out_count) { - return _dmntchtGetEntries(65101, buffer, sizeof(*buffer) * max_count, offset, out_count); + return _dmntchtGetEntries(buffer, sizeof(*buffer) * max_count, offset, out_count, 65101); } Result dmntchtReadCheatProcessMemory(u64 address, void *buffer, size_t size) { @@ -111,11 +112,11 @@ Result dmntchtQueryCheatProcessMemory(MemoryInfo *mem_info, u64 address){ } Result dmntchtGetCheatCount(u64 *out_count) { - return _dmntchtGetCount(65200, out_count); + return _dmntchtGetCount(out_count, 65200); } Result dmntchtGetCheats(DmntCheatEntry *buffer, u64 max_count, u64 offset, u64 *out_count) { - return _dmntchtGetEntries(65201, buffer, sizeof(*buffer) * max_count, offset, out_count); + return _dmntchtGetEntries(buffer, sizeof(*buffer) * max_count, offset, out_count, 65201); } Result dmntchtGetCheatById(DmntCheatEntry *out, u32 cheat_id) { @@ -142,11 +143,11 @@ Result dmntchtRemoveCheat(u32 cheat_id) { } Result dmntchtGetFrozenAddressCount(u64 *out_count) { - return _dmntchtGetCount(65300, out_count); + return _dmntchtGetCount(out_count, 65300); } Result dmntchtGetFrozenAddresses(DmntFrozenAddressEntry *buffer, u64 max_count, u64 offset, u64 *out_count) { - return _dmntchtGetEntries(65301, buffer, sizeof(*buffer) * max_count, offset, out_count); + return _dmntchtGetEntries(buffer, sizeof(*buffer) * max_count, offset, out_count, 65301); } Result dmntchtGetFrozenAddress(DmntFrozenAddressEntry *out, u64 address) { diff --git a/stratosphere/libstratosphere/source/sf/cmif/sf_cmif_domain_manager.cpp b/stratosphere/libstratosphere/source/sf/cmif/sf_cmif_domain_manager.cpp index 4ccc5ac93..10ebbb5bf 100644 --- a/stratosphere/libstratosphere/source/sf/cmif/sf_cmif_domain_manager.cpp +++ b/stratosphere/libstratosphere/source/sf/cmif/sf_cmif_domain_manager.cpp @@ -90,6 +90,7 @@ namespace sts::sf::cmif { if (entry == nullptr) { return ServiceObjectHolder(); } + { std::scoped_lock lk(this->manager->entry_owner_lock); if (entry->owner != this) { @@ -116,9 +117,11 @@ namespace sts::sf::cmif { ServerDomainManager::Entry *ServerDomainManager::EntryManager::AllocateEntry() { std::scoped_lock lk(this->lock); + if (this->free_list.empty()) { return nullptr; } + Entry *e = &this->free_list.front(); this->free_list.pop_front(); return e; diff --git a/stratosphere/libstratosphere/source/sf/cmif/sf_cmif_domain_service_object.cpp b/stratosphere/libstratosphere/source/sf/cmif/sf_cmif_domain_service_object.cpp index 3655b5d0e..c17bf9a76 100644 --- a/stratosphere/libstratosphere/source/sf/cmif/sf_cmif_domain_service_object.cpp +++ b/stratosphere/libstratosphere/source/sf/cmif/sf_cmif_domain_service_object.cpp @@ -48,6 +48,7 @@ namespace sts::sf::cmif { } else { ctx.processor->SetImplementationProcessor(&domain_processor); } + ctx.srv_obj = target_object.GetServiceObjectUnsafe(); return target_object.ProcessMessage(ctx, in_message_raw_data); } case CmifDomainRequestType_Close: @@ -86,6 +87,7 @@ namespace sts::sf::cmif { } else { ctx.processor->SetImplementationProcessor(&domain_processor); } + ctx.srv_obj = target_object.GetServiceObjectUnsafe(); return target_object.ProcessMessage(ctx, in_message_raw_data); } case CmifDomainRequestType_Close: @@ -136,7 +138,7 @@ namespace sts::sf::cmif { /* Set output raw data. */ out_raw_data = cmif::PointerAndSize(raw_data.GetAddress() + out_header_size, raw_data.GetSize() - out_header_size); - this->out_object_ids = reinterpret_cast(out_raw_data.GetAddress() + out_raw_data.GetSize()); + this->out_object_ids = reinterpret_cast(out_raw_data.GetAddress() + impl_out_data_total_size); return request; } diff --git a/stratosphere/libstratosphere/source/sf/hipc/sf_hipc_server_domain_session_manager.cpp b/stratosphere/libstratosphere/source/sf/hipc/sf_hipc_server_domain_session_manager.cpp index 10eb7b80b..09fb22878 100644 --- a/stratosphere/libstratosphere/source/sf/hipc/sf_hipc_server_domain_session_manager.cpp +++ b/stratosphere/libstratosphere/source/sf/hipc/sf_hipc_server_domain_session_manager.cpp @@ -47,10 +47,7 @@ namespace sts::sf::hipc { R_ASSERT(tagged_manager->RegisterSession(server_handle, std::move(clone))); } else { /* Clone the forward service. */ - std::shared_ptr<::Service> new_forward_service(new ::Service(), [](::Service *srv) { - serviceClose(srv); - delete srv; - }); + std::shared_ptr<::Service> new_forward_service = std::move(ServerSession::CreateForwardService()); R_ASSERT(serviceClone(this->session->forward_service.get(), new_forward_service.get())); R_ASSERT(tagged_manager->RegisterMitmSession(server_handle, std::move(clone), std::move(new_forward_service))); } @@ -138,10 +135,7 @@ namespace sts::sf::hipc { R_ASSERT(hipc::CreateSession(&server_handle, out.GetHandlePointer())); /* Register. */ - std::shared_ptr<::Service> new_forward_service(new ::Service(), [](::Service *srv) { - serviceClose(srv); - delete srv; - }); + std::shared_ptr<::Service> new_forward_service = std::move(ServerSession::CreateForwardService()); serviceCreate(new_forward_service.get(), new_forward_target); R_ASSERT(this->manager->RegisterMitmSession(server_handle, std::move(object), std::move(new_forward_service))); } @@ -178,7 +172,7 @@ namespace sts::sf::hipc { /* Note: This is safe, as no additional references to the hipc manager can ever be stored. */ /* The shared pointer to stack object is definitely gross, though. */ impl::HipcManager hipc_manager(this, session); - return this->DispatchRequest(cmif::ServiceObjectHolder(std::shared_ptr(&hipc_manager, [](impl::HipcManager *) { /* Empty deleter. */ })), session, in_message, out_message); + return this->DispatchRequest(cmif::ServiceObjectHolder(std::move(ServiceObjectTraits::SharedPointerHelper::GetEmptyDeleteSharedPointer(&hipc_manager))), session, in_message, out_message); } } diff --git a/stratosphere/libstratosphere/source/sm/sm_ams.c b/stratosphere/libstratosphere/source/sm/sm_ams.c index b345e42a6..5f3268d8f 100644 --- a/stratosphere/libstratosphere/source/sm/sm_ams.c +++ b/stratosphere/libstratosphere/source/sm/sm_ams.c @@ -17,31 +17,31 @@ #include "../service_guard.h" #include "sm_ams.h" -static Result _smAtmosphereCmdHas(bool *out, u64 service_name, u32 cmd_id) { +static Result _smAtmosphereCmdHas(bool *out, SmServiceName name, u32 cmd_id) { u8 tmp; - Result rc = serviceDispatchInOut(smGetServiceSession(), cmd_id, service_name, tmp); + Result rc = serviceDispatchInOut(smGetServiceSession(), cmd_id, name, tmp); if (R_SUCCEEDED(rc) && out) *out = tmp & 1; return rc; } -static Result _smAtmosphereCmdInServiceNameNoOut(u64 service_name, Service *srv, u32 cmd_id) { - return serviceDispatchIn(srv, cmd_id, service_name); +static Result _smAtmosphereCmdInServiceNameNoOut(SmServiceName name, Service *srv, u32 cmd_id) { + return serviceDispatchIn(srv, cmd_id, name); } -Result smAtmosphereHasService(bool *out, const char *name) { - return _smAtmosphereCmdHas(out, smEncodeName(name), 65100); +Result smAtmosphereHasService(bool *out, SmServiceName name) { + return _smAtmosphereCmdHas(out, name, 65100); } -Result smAtmosphereWaitService(const char *name) { - return _smAtmosphereCmdInServiceNameNoOut(smEncodeName(name), smGetServiceSession(), 65101); +Result smAtmosphereWaitService(SmServiceName name) { + return _smAtmosphereCmdInServiceNameNoOut(name, smGetServiceSession(), 65101); } -Result smAtmosphereHasMitm(bool *out, const char *name) { - return _smAtmosphereCmdHas(out, smEncodeName(name), 65004); +Result smAtmosphereHasMitm(bool *out, SmServiceName name) { + return _smAtmosphereCmdHas(out, name, 65004); } -Result smAtmosphereWaitMitm(const char *name) { - return _smAtmosphereCmdInServiceNameNoOut(smEncodeName(name), smGetServiceSession(), 65005); +Result smAtmosphereWaitMitm(SmServiceName name) { + return _smAtmosphereCmdInServiceNameNoOut(name, smGetServiceSession(), 65005); } static Service g_smAtmosphereMitmSrv; @@ -76,10 +76,9 @@ Service* smAtmosphereMitmGetServiceSession(void) { return &g_smAtmosphereMitmSrv; } -Result smAtmosphereMitmInstall(Handle *handle_out, Handle *query_out, const char *name) { - const u64 in = smEncodeName(name); +Result smAtmosphereMitmInstall(Handle *handle_out, Handle *query_out, SmServiceName name) { Handle tmp_handles[2]; - Result rc = serviceDispatchIn(&g_smAtmosphereMitmSrv, 65000, in, + Result rc = serviceDispatchIn(&g_smAtmosphereMitmSrv, 65000, name, .out_handle_attrs = { SfOutHandleAttr_HipcMove, SfOutHandleAttr_HipcMove }, .out_handles = tmp_handles, ); @@ -92,22 +91,21 @@ Result smAtmosphereMitmInstall(Handle *handle_out, Handle *query_out, const char return rc; } -Result smAtmosphereMitmUninstall(const char *name) { - return _smAtmosphereCmdInServiceNameNoOut(smEncodeName(name), &g_smAtmosphereMitmSrv, 65001); +Result smAtmosphereMitmUninstall(SmServiceName name) { + return _smAtmosphereCmdInServiceNameNoOut(name, &g_smAtmosphereMitmSrv, 65001); } -Result smAtmosphereMitmDeclareFuture(const char *name) { - return _smAtmosphereCmdInServiceNameNoOut(smEncodeName(name), &g_smAtmosphereMitmSrv, 65006); +Result smAtmosphereMitmDeclareFuture(SmServiceName name) { + return _smAtmosphereCmdInServiceNameNoOut(name, &g_smAtmosphereMitmSrv, 65006); } -Result smAtmosphereMitmAcknowledgeSession(Service *srv_out, u64 *pid_out, u64 *tid_out, const char *name) { - const u64 in = smEncodeName(name); +Result smAtmosphereMitmAcknowledgeSession(Service *srv_out, u64 *pid_out, u64 *tid_out, SmServiceName name) { struct { u64 pid; u64 tid; } out; - Result rc = serviceDispatchInOut(&g_smAtmosphereMitmSrv, 65003, in, out, + Result rc = serviceDispatchInOut(&g_smAtmosphereMitmSrv, 65003, name, out, .out_num_objects = 1, .out_objects = srv_out, ); diff --git a/stratosphere/libstratosphere/source/sm/sm_ams.h b/stratosphere/libstratosphere/source/sm/sm_ams.h index 7ab27f64a..a18f3be2d 100644 --- a/stratosphere/libstratosphere/source/sm/sm_ams.h +++ b/stratosphere/libstratosphere/source/sm/sm_ams.h @@ -13,19 +13,19 @@ extern "C" { #endif -Result smAtmosphereHasService(bool *out, const char *name); -Result smAtmosphereWaitService(const char *name); -Result smAtmosphereHasMitm(bool *out, const char *name); -Result smAtmosphereWaitMitm(const char *name); +Result smAtmosphereHasService(bool *out, SmServiceName name); +Result smAtmosphereWaitService(SmServiceName name); +Result smAtmosphereHasMitm(bool *out, SmServiceName name); +Result smAtmosphereWaitMitm(SmServiceName name); Result smAtmosphereMitmInitialize(void); void smAtmosphereMitmExit(void); Service *smAtmosphereMitmGetServiceSession(); -Result smAtmosphereMitmInstall(Handle *handle_out, Handle *query_out, const char *name); -Result smAtmosphereMitmUninstall(const char *name); -Result smAtmosphereMitmDeclareFuture(const char *name); -Result smAtmosphereMitmAcknowledgeSession(Service *srv_out, u64 *pid_out, u64 *tid_out, const char *name); +Result smAtmosphereMitmInstall(Handle *handle_out, Handle *query_out, SmServiceName name); +Result smAtmosphereMitmUninstall(SmServiceName name); +Result smAtmosphereMitmDeclareFuture(SmServiceName name); +Result smAtmosphereMitmAcknowledgeSession(Service *srv_out, u64 *pid_out, u64 *tid_out, SmServiceName name); #ifdef __cplusplus } diff --git a/stratosphere/libstratosphere/source/sm/sm_api.cpp b/stratosphere/libstratosphere/source/sm/sm_api.cpp index c12806e36..c3fb39208 100644 --- a/stratosphere/libstratosphere/source/sm/sm_api.cpp +++ b/stratosphere/libstratosphere/source/sm/sm_api.cpp @@ -26,32 +26,32 @@ namespace sts::sm { /* Ordinary SM API. */ Result GetService(Service *out, ServiceName name) { return impl::DoWithUserSession([&]() { - return smGetService(out, name.name); + return smGetServiceWrapper(out, impl::ConvertName(name)); }); } Result RegisterService(Handle *out, ServiceName name, size_t max_sessions, bool is_light) { return impl::DoWithUserSession([&]() { - return smRegisterService(out, name.name, is_light, static_cast(max_sessions)); + return smRegisterService(out, impl::ConvertName(name), is_light, static_cast(max_sessions)); }); } Result UnregisterService(ServiceName name) { return impl::DoWithUserSession([&]() { - return smUnregisterService(name.name); + return smUnregisterService(impl::ConvertName(name)); }); } /* Atmosphere extensions. */ Result HasService(bool *out, ServiceName name) { return impl::DoWithUserSession([&]() { - return smAtmosphereHasService(out, name.name); + return smAtmosphereHasService(out, impl::ConvertName(name)); }); } Result WaitService(ServiceName name) { return impl::DoWithUserSession([&]() { - return smAtmosphereWaitService(name.name); + return smAtmosphereWaitService(impl::ConvertName(name)); }); } diff --git a/stratosphere/libstratosphere/source/sm/sm_manager_api.cpp b/stratosphere/libstratosphere/source/sm/sm_manager_api.cpp index f83d041d4..8318d794c 100644 --- a/stratosphere/libstratosphere/source/sm/sm_manager_api.cpp +++ b/stratosphere/libstratosphere/source/sm/sm_manager_api.cpp @@ -20,6 +20,7 @@ #include #include "smm_ams.h" +#include "sm_utils.hpp" namespace sts::sm::manager { @@ -38,7 +39,7 @@ namespace sts::sm::manager { } Result HasMitm(bool *out, ServiceName name) { - return smManagerAtmosphereHasMitm(out, name.name); + return smManagerAtmosphereHasMitm(out, impl::ConvertName(name)); } } diff --git a/stratosphere/libstratosphere/source/sm/sm_mitm_api.cpp b/stratosphere/libstratosphere/source/sm/sm_mitm_api.cpp index 7ecfda466..09b97ae2d 100644 --- a/stratosphere/libstratosphere/source/sm/sm_mitm_api.cpp +++ b/stratosphere/libstratosphere/source/sm/sm_mitm_api.cpp @@ -26,37 +26,37 @@ namespace sts::sm::mitm { /* Mitm API. */ Result InstallMitm(Handle *out_port, Handle *out_query, ServiceName name) { return impl::DoWithMitmSession([&]() { - return smAtmosphereMitmInstall(out_port, out_query, name.name); + return smAtmosphereMitmInstall(out_port, out_query, impl::ConvertName(name)); }); } Result UninstallMitm(ServiceName name) { return impl::DoWithMitmSession([&]() { - return smAtmosphereMitmUninstall(name.name); + return smAtmosphereMitmUninstall(impl::ConvertName(name)); }); } Result DeclareFutureMitm(ServiceName name) { return impl::DoWithMitmSession([&]() { - return smAtmosphereMitmDeclareFuture(name.name); + return smAtmosphereMitmDeclareFuture(impl::ConvertName(name)); }); } Result AcknowledgeSession(Service *out_service, os::ProcessId *out_pid, ncm::TitleId *out_tid, ServiceName name) { return impl::DoWithMitmSession([&]() { - return smAtmosphereMitmAcknowledgeSession(out_service, &out_pid->value, &out_tid->value, name.name); + return smAtmosphereMitmAcknowledgeSession(out_service, &out_pid->value, &out_tid->value, impl::ConvertName(name)); }); } Result HasMitm(bool *out, ServiceName name) { return impl::DoWithUserSession([&]() { - return smAtmosphereHasMitm(out, name.name); + return smAtmosphereHasMitm(out, impl::ConvertName(name)); }); } Result WaitMitm(ServiceName name) { return impl::DoWithUserSession([&]() { - return smAtmosphereWaitMitm(name.name); + return smAtmosphereWaitMitm(impl::ConvertName(name)); }); } diff --git a/stratosphere/libstratosphere/source/sm/sm_utils.hpp b/stratosphere/libstratosphere/source/sm/sm_utils.hpp index 11bb99408..c1cd9ed78 100644 --- a/stratosphere/libstratosphere/source/sm/sm_utils.hpp +++ b/stratosphere/libstratosphere/source/sm/sm_utils.hpp @@ -50,4 +50,11 @@ namespace sts::sm::impl { } } + NX_CONSTEXPR SmServiceName ConvertName(sm::ServiceName name) { + static_assert(sizeof(SmServiceName) == sizeof(sm::ServiceName)); + SmServiceName ret = {}; + __builtin_memcpy(&ret, &name, sizeof(sm::ServiceName)); + return ret; + } + } diff --git a/stratosphere/libstratosphere/source/sm/smm_ams.c b/stratosphere/libstratosphere/source/sm/smm_ams.c index e9a1995eb..ada3d7ed3 100644 --- a/stratosphere/libstratosphere/source/sm/smm_ams.c +++ b/stratosphere/libstratosphere/source/sm/smm_ams.c @@ -36,13 +36,13 @@ Result smManagerAtmosphereRegisterProcess(u64 pid, u64 tid, const void *acid_sac ); } -static Result _smManagerAtmosphereCmdHas(bool *out, u64 service_name, u32 cmd_id) { +static Result _smManagerAtmosphereCmdHas(bool *out, SmServiceName name, u32 cmd_id) { u8 tmp; - Result rc = serviceDispatchInOut(smManagerGetServiceSession(), cmd_id, service_name, tmp); + Result rc = serviceDispatchInOut(smManagerGetServiceSession(), cmd_id, name, tmp); if (R_SUCCEEDED(rc) && out) *out = tmp & 1; return rc; } -Result smManagerAtmosphereHasMitm(bool *out, const char* name) { - return _smManagerAtmosphereCmdHas(out, smEncodeName(name), 65001); +Result smManagerAtmosphereHasMitm(bool *out, SmServiceName name) { + return _smManagerAtmosphereCmdHas(out, name, 65001); } diff --git a/stratosphere/libstratosphere/source/sm/smm_ams.h b/stratosphere/libstratosphere/source/sm/smm_ams.h index 62a47536e..0af187f5d 100644 --- a/stratosphere/libstratosphere/source/sm/smm_ams.h +++ b/stratosphere/libstratosphere/source/sm/smm_ams.h @@ -13,7 +13,7 @@ extern "C" { Result smManagerAtmosphereEndInitialDefers(void); Result smManagerAtmosphereRegisterProcess(u64 pid, u64 tid, const void *acid_sac, size_t acid_sac_size, const void *aci_sac, size_t aci_sac_size); -Result smManagerAtmosphereHasMitm(bool *out, const char* name); +Result smManagerAtmosphereHasMitm(bool *out, SmServiceName name); #ifdef __cplusplus }