From 5f8d2a2044842a0d0674d178e7bb98be2ee65be2 Mon Sep 17 00:00:00 2001 From: Zach Hilman Date: Mon, 24 Jun 2019 19:17:13 -0400 Subject: glue: Add manager to keep track of application registry Manages mapping between title IDs and application launch and control properties. --- src/core/hle/service/glue/manager.cpp | 73 +++++++++++++++++++++++++++++++++++ src/core/hle/service/glue/manager.h | 46 ++++++++++++++++++++++ 2 files changed, 119 insertions(+) create mode 100644 src/core/hle/service/glue/manager.cpp create mode 100644 src/core/hle/service/glue/manager.h (limited to 'src/core/hle/service') diff --git a/src/core/hle/service/glue/manager.cpp b/src/core/hle/service/glue/manager.cpp new file mode 100644 index 000000000..0d5bb4d50 --- /dev/null +++ b/src/core/hle/service/glue/manager.cpp @@ -0,0 +1,73 @@ +// Copyright 2019 yuzu emulator team +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#include "core/hle/service/glue/errors.h" +#include "core/hle/service/glue/manager.h" + +namespace Service::Glue { + +ARPManager::ARPManager() = default; + +ARPManager::~ARPManager() = default; + +ResultVal ARPManager::GetLaunchProperty(u64 title_id) const { + if (title_id == 0) { + return ERR_TITLE_ID_ZERO; + } + + const auto iter = entries.find(title_id); + if (iter == entries.end()) { + return ERR_NONEXISTENT; + } + + return MakeResult(iter->second.launch); +} + +ResultVal> ARPManager::GetControlProperty(u64 title_id) const { + if (title_id == 0) { + return ERR_TITLE_ID_ZERO; + } + + const auto iter = entries.find(title_id); + if (iter == entries.end()) { + return ERR_NONEXISTENT; + } + + return MakeResult>(iter->second.control); +} + +ResultCode ARPManager::Register(u64 title_id, ApplicationLaunchProperty launch, + std::vector control) { + if (title_id == 0) { + return ERR_TITLE_ID_ZERO; + } + + const auto iter = entries.find(title_id); + if (iter != entries.end()) { + return ERR_ALREADY_ISSUED; + } + + entries.insert_or_assign(title_id, MapEntry{launch, std::move(control)}); + return RESULT_SUCCESS; +} + +ResultCode ARPManager::Unregister(u64 title_id) { + if (title_id == 0) { + return ERR_TITLE_ID_ZERO; + } + + const auto iter = entries.find(title_id); + if (iter == entries.end()) { + return ERR_NONEXISTENT; + } + + entries.erase(iter); + return RESULT_SUCCESS; +} + +void ARPManager::ResetAll() { + entries.clear(); +} + +} // namespace Service::Glue diff --git a/src/core/hle/service/glue/manager.h b/src/core/hle/service/glue/manager.h new file mode 100644 index 000000000..561ebf4e0 --- /dev/null +++ b/src/core/hle/service/glue/manager.h @@ -0,0 +1,46 @@ +// Copyright 2019 yuzu emulator team +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#pragma once + +#include "core/file_sys/control_metadata.h" +#include "core/file_sys/romfs_factory.h" +#include "core/hle/result.h" + +namespace Service::Glue { + +struct ApplicationLaunchProperty { + u64 title_id; + u32 version; + FileSys::StorageId base_game_storage_id; + FileSys::StorageId update_storage_id; + INSERT_PADDING_BYTES(0x2); +}; +static_assert(sizeof(ApplicationLaunchProperty) == 0x10, + "ApplicationLaunchProperty has incorrect size."); + +class ARPManager { +public: + ARPManager(); + ~ARPManager(); + + ResultVal GetLaunchProperty(u64 title_id) const; + ResultVal> GetControlProperty(u64 title_id) const; + + ResultCode Register(u64 title_id, ApplicationLaunchProperty launch, std::vector control); + + ResultCode Unregister(u64 title_id); + + void ResetAll(); + +private: + struct MapEntry { + ApplicationLaunchProperty launch; + std::vector control; + }; + + std::map entries; +}; + +} // namespace Service::Glue -- cgit v1.2.3 From 9003e19797eaec40f90e127a02b47d3effb2d005 Mon Sep 17 00:00:00 2001 From: Zach Hilman Date: Mon, 24 Jun 2019 19:17:48 -0400 Subject: arp: Move to glue services Glue is the name of the sysmodule that contains both arp and bgtc. --- src/core/hle/service/arp/arp.cpp | 75 ---------------------------------------- src/core/hle/service/arp/arp.h | 16 --------- 2 files changed, 91 deletions(-) delete mode 100644 src/core/hle/service/arp/arp.cpp delete mode 100644 src/core/hle/service/arp/arp.h (limited to 'src/core/hle/service') diff --git a/src/core/hle/service/arp/arp.cpp b/src/core/hle/service/arp/arp.cpp deleted file mode 100644 index e675b0188..000000000 --- a/src/core/hle/service/arp/arp.cpp +++ /dev/null @@ -1,75 +0,0 @@ -// Copyright 2018 yuzu emulator team -// Licensed under GPLv2 or any later version -// Refer to the license.txt file included. - -#include - -#include "common/logging/log.h" -#include "core/hle/ipc_helpers.h" -#include "core/hle/kernel/hle_ipc.h" -#include "core/hle/service/arp/arp.h" -#include "core/hle/service/service.h" -#include "core/hle/service/sm/sm.h" - -namespace Service::ARP { - -class ARP_R final : public ServiceFramework { -public: - explicit ARP_R() : ServiceFramework{"arp:r"} { - // clang-format off - static const FunctionInfo functions[] = { - {0, nullptr, "GetApplicationLaunchProperty"}, - {1, nullptr, "GetApplicationLaunchPropertyWithApplicationId"}, - {2, nullptr, "GetApplicationControlProperty"}, - {3, nullptr, "GetApplicationControlPropertyWithApplicationId"}, - }; - // clang-format on - - RegisterHandlers(functions); - } -}; - -class IRegistrar final : public ServiceFramework { -public: - explicit IRegistrar() : ServiceFramework{"IRegistrar"} { - // clang-format off - static const FunctionInfo functions[] = { - {0, nullptr, "Issue"}, - {1, nullptr, "SetApplicationLaunchProperty"}, - {2, nullptr, "SetApplicationControlProperty"}, - }; - // clang-format on - - RegisterHandlers(functions); - } -}; - -class ARP_W final : public ServiceFramework { -public: - explicit ARP_W() : ServiceFramework{"arp:w"} { - // clang-format off - static const FunctionInfo functions[] = { - {0, &ARP_W::AcquireRegistrar, "AcquireRegistrar"}, - {1, nullptr, "DeleteProperties"}, - }; - // clang-format on - - RegisterHandlers(functions); - } - -private: - void AcquireRegistrar(Kernel::HLERequestContext& ctx) { - LOG_DEBUG(Service_ARP, "called"); - - IPC::ResponseBuilder rb{ctx, 2, 0, 1}; - rb.Push(RESULT_SUCCESS); - rb.PushIpcInterface(); - } -}; - -void InstallInterfaces(SM::ServiceManager& sm) { - std::make_shared()->InstallAsService(sm); - std::make_shared()->InstallAsService(sm); -} - -} // namespace Service::ARP diff --git a/src/core/hle/service/arp/arp.h b/src/core/hle/service/arp/arp.h deleted file mode 100644 index 9d100187c..000000000 --- a/src/core/hle/service/arp/arp.h +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright 2018 yuzu emulator team -// Licensed under GPLv2 or any later version -// Refer to the license.txt file included. - -#pragma once - -namespace Service::SM { -class ServiceManager; -} - -namespace Service::ARP { - -/// Registers all ARP services with the specified service manager. -void InstallInterfaces(SM::ServiceManager& sm); - -} // namespace Service::ARP -- cgit v1.2.3 From 4fab0d392b9bde614ac140920074290976c322aa Mon Sep 17 00:00:00 2001 From: Zach Hilman Date: Mon, 24 Jun 2019 19:20:06 -0400 Subject: glue: Add scaffolding for bgtc:t and bgtc:sc services --- src/core/hle/service/glue/bgtc.cpp | 50 ++++++++++++++++++++++++++++++++++++++ src/core/hle/service/glue/bgtc.h | 23 ++++++++++++++++++ 2 files changed, 73 insertions(+) create mode 100644 src/core/hle/service/glue/bgtc.cpp create mode 100644 src/core/hle/service/glue/bgtc.h (limited to 'src/core/hle/service') diff --git a/src/core/hle/service/glue/bgtc.cpp b/src/core/hle/service/glue/bgtc.cpp new file mode 100644 index 000000000..cd89d088f --- /dev/null +++ b/src/core/hle/service/glue/bgtc.cpp @@ -0,0 +1,50 @@ +// Copyright 2019 yuzu emulator team +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#include "core/hle/service/glue/bgtc.h" + +namespace Service::Glue { + +BGTC_T::BGTC_T() : ServiceFramework{"bgtc:t"} { + // clang-format off + static const FunctionInfo functions[] = { + {1, nullptr, "NotifyTaskStarting"}, + {2, nullptr, "NotifyTaskFinished"}, + {3, nullptr, "GetTriggerEvent"}, + {4, nullptr, "IsInHalfAwake"}, + {5, nullptr, "NotifyClientName"}, + {6, nullptr, "IsInFullAwake"}, + {11, nullptr, "ScheduleTask"}, + {12, nullptr, "GetScheduledTaskInterval"}, + {13, nullptr, "UnscheduleTask"}, + {14, nullptr, "GetScheduleEvent"}, + {15, nullptr, "SchedulePeriodicTask"}, + {101, nullptr, "GetOperationMode"}, + {102, nullptr, "WillDisconnectNetworkWhenEnteringSleep"}, + {103, nullptr, "WillStayHalfAwakeInsteadSleep"}, + }; + // clang-format on + + RegisterHandlers(functions); +} + +BGTC_T::~BGTC_T() = default; + +BGTC_SC::BGTC_SC() : ServiceFramework{"bgtc:sc"} { + // clang-format off + static const FunctionInfo functions[] = { + {1, nullptr, "GetState"}, + {2, nullptr, "GetStateChangedEvent"}, + {3, nullptr, "NotifyEnteringHalfAwake"}, + {4, nullptr, "NotifyLeavingHalfAwake"}, + {5, nullptr, "SetIsUsingSleepUnsupportedDevices"}, + }; + // clang-format on + + RegisterHandlers(functions); +} + +BGTC_SC::~BGTC_SC() = default; + +} // namespace Service::Glue diff --git a/src/core/hle/service/glue/bgtc.h b/src/core/hle/service/glue/bgtc.h new file mode 100644 index 000000000..81844f03e --- /dev/null +++ b/src/core/hle/service/glue/bgtc.h @@ -0,0 +1,23 @@ +// Copyright 2019 yuzu emulator team +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#pragma once + +#include "core/hle/service/service.h" + +namespace Service::Glue { + +class BGTC_T final : public ServiceFramework { +public: + BGTC_T(); + ~BGTC_T() override; +}; + +class BGTC_SC final : public ServiceFramework { +public: + BGTC_SC(); + ~BGTC_SC() override; +}; + +} // namespace Service::Glue -- cgit v1.2.3 From df3ee4f44431ad6b026d404a234680f51fe702b6 Mon Sep 17 00:00:00 2001 From: Zach Hilman Date: Mon, 24 Jun 2019 19:20:28 -0400 Subject: glue: Add errors for glue/arp services --- src/core/hle/service/glue/errors.h | 17 +++++++++++++++++ src/core/hle/service/glue/glue.cpp | 25 +++++++++++++++++++++++++ src/core/hle/service/glue/glue.h | 16 ++++++++++++++++ 3 files changed, 58 insertions(+) create mode 100644 src/core/hle/service/glue/errors.h create mode 100644 src/core/hle/service/glue/glue.cpp create mode 100644 src/core/hle/service/glue/glue.h (limited to 'src/core/hle/service') diff --git a/src/core/hle/service/glue/errors.h b/src/core/hle/service/glue/errors.h new file mode 100644 index 000000000..594e20a01 --- /dev/null +++ b/src/core/hle/service/glue/errors.h @@ -0,0 +1,17 @@ +// Copyright 2019 yuzu emulator team +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#pragma once + +#include "core/hle/result.h" + +namespace Service::Glue { + +constexpr ResultCode ERR_OUTPUT_TOO_SMALL{0x3C9D}; +constexpr ResultCode ERR_PROCESS_ID_ZERO{0x3E9D}; +constexpr ResultCode ERR_TITLE_ID_ZERO{0x3E9D}; +constexpr ResultCode ERR_ALREADY_ISSUED{0x549D}; +constexpr ResultCode ERR_NONEXISTENT{0xCC9D}; + +} // namespace Service::Glue diff --git a/src/core/hle/service/glue/glue.cpp b/src/core/hle/service/glue/glue.cpp new file mode 100644 index 000000000..c728e815c --- /dev/null +++ b/src/core/hle/service/glue/glue.cpp @@ -0,0 +1,25 @@ +// Copyright 2019 yuzu emulator team +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#include +#include "core/core.h" +#include "core/hle/service/glue/arp.h" +#include "core/hle/service/glue/bgtc.h" +#include "core/hle/service/glue/glue.h" + +namespace Service::Glue { + +void InstallInterfaces(Core::System& system) { + // ARP + std::make_shared(system, system.GetARPManager()) + ->InstallAsService(system.ServiceManager()); + std::make_shared(system, system.GetARPManager()) + ->InstallAsService(system.ServiceManager()); + + // BackGround Task Controller + std::make_shared()->InstallAsService(system.ServiceManager()); + std::make_shared()->InstallAsService(system.ServiceManager()); +} + +} // namespace Service::Glue diff --git a/src/core/hle/service/glue/glue.h b/src/core/hle/service/glue/glue.h new file mode 100644 index 000000000..112cd238b --- /dev/null +++ b/src/core/hle/service/glue/glue.h @@ -0,0 +1,16 @@ +// Copyright 2019 yuzu emulator team +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#pragma once + +namespace Core { +class System; +} // namespace Core + +namespace Service::Glue { + +/// Registers all Glue services with the specified service manager. +void InstallInterfaces(Core::System& system); + +} // namespace Service::Glue -- cgit v1.2.3 From ce2197302236c0990d2d5234ab52f1579c126090 Mon Sep 17 00:00:00 2001 From: Zach Hilman Date: Mon, 24 Jun 2019 19:26:16 -0400 Subject: glue: Implement arp:w and arp:r services These keep track of running process' launch properties and control properties and allows for issuing and reading them by process and title ID. --- src/core/hle/service/glue/arp.cpp | 285 ++++++++++++++++++++++++++++++++++++++ src/core/hle/service/glue/arp.h | 43 ++++++ src/core/hle/service/service.cpp | 4 +- 3 files changed, 330 insertions(+), 2 deletions(-) create mode 100644 src/core/hle/service/glue/arp.cpp create mode 100644 src/core/hle/service/glue/arp.h (limited to 'src/core/hle/service') diff --git a/src/core/hle/service/glue/arp.cpp b/src/core/hle/service/glue/arp.cpp new file mode 100644 index 000000000..19c75ff2f --- /dev/null +++ b/src/core/hle/service/glue/arp.cpp @@ -0,0 +1,285 @@ +// Copyright 2018 yuzu emulator team +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#include + +#include "common/logging/log.h" +#include "core/file_sys/control_metadata.h" +#include "core/hle/ipc_helpers.h" +#include "core/hle/kernel/hle_ipc.h" +#include "core/hle/kernel/kernel.h" +#include "core/hle/kernel/process.h" +#include "core/hle/service/glue/arp.h" +#include "core/hle/service/glue/errors.h" +#include "core/hle/service/glue/manager.h" +#include "core/hle/service/service.h" + +namespace Service::Glue { + +namespace { +std::optional GetTitleIDForProcessID(const Core::System& system, u64 process_id) { + const auto& list = system.Kernel().GetProcessList(); + const auto iter = std::find_if(list.begin(), list.end(), [&process_id](const auto& process) { + return process->GetProcessID() == process_id; + }); + + if (iter == list.end()) { + return std::nullopt; + } + + return (*iter)->GetTitleID(); +} +} // Anonymous namespace + +ARP_R::ARP_R(const Core::System& system, const ARPManager& manager) + : ServiceFramework{"arp:r"}, system(system), manager(manager) { + // clang-format off + static const FunctionInfo functions[] = { + {0, &ARP_R::GetApplicationLaunchProperty, "GetApplicationLaunchProperty"}, + {1, &ARP_R::GetApplicationLaunchPropertyWithApplicationId, "GetApplicationLaunchPropertyWithApplicationId"}, + {2, &ARP_R::GetApplicationControlProperty, "GetApplicationControlProperty"}, + {3, &ARP_R::GetApplicationControlPropertyWithApplicationId, "GetApplicationControlPropertyWithApplicationId"}, + }; + // clang-format on + + RegisterHandlers(functions); +} + +ARP_R::~ARP_R() = default; + +void ARP_R::GetApplicationLaunchProperty(Kernel::HLERequestContext& ctx) { + IPC::RequestParser rp{ctx}; + const auto process_id = rp.PopRaw(); + + LOG_DEBUG(Service_ARP, "called, process_id={:016X}", process_id); + + const auto title_id = GetTitleIDForProcessID(system, process_id); + if (!title_id.has_value()) { + LOG_ERROR(Service_ARP, "Failed to get title ID for process ID!"); + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(ERR_NONEXISTENT); + } + + const auto res = manager.GetLaunchProperty(*title_id); + + if (res.Failed()) { + LOG_ERROR(Service_ARP, "Failed to get launch property!"); + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(res.Code()); + } + + IPC::ResponseBuilder rb{ctx, 6}; + rb.Push(RESULT_SUCCESS); + rb.PushRaw(*res); +} + +void ARP_R::GetApplicationLaunchPropertyWithApplicationId(Kernel::HLERequestContext& ctx) { + IPC::RequestParser rp{ctx}; + const auto title_id = rp.PopRaw(); + + LOG_DEBUG(Service_ARP, "called, title_id={:016X}", title_id); + + const auto res = manager.GetLaunchProperty(title_id); + + if (res.Failed()) { + LOG_ERROR(Service_ARP, "Failed to get launch property!"); + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(res.Code()); + } + + IPC::ResponseBuilder rb{ctx, 6}; + rb.Push(RESULT_SUCCESS); + rb.PushRaw(*res); +} + +void ARP_R::GetApplicationControlProperty(Kernel::HLERequestContext& ctx) { + IPC::RequestParser rp{ctx}; + const auto process_id = rp.PopRaw(); + + LOG_DEBUG(Service_ARP, "called, process_id={:016X}", process_id); + + const auto title_id = GetTitleIDForProcessID(system, process_id); + if (!title_id.has_value()) { + LOG_ERROR(Service_ARP, "Failed to get title ID for process ID!"); + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(ERR_NONEXISTENT); + } + + const auto res = manager.GetControlProperty(*title_id); + + if (res.Failed()) { + LOG_ERROR(Service_ARP, "Failed to get control property!"); + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(res.Code()); + } + + ctx.WriteBuffer(*res); + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(RESULT_SUCCESS); +} + +void ARP_R::GetApplicationControlPropertyWithApplicationId(Kernel::HLERequestContext& ctx) { + IPC::RequestParser rp{ctx}; + const auto title_id = rp.PopRaw(); + + LOG_DEBUG(Service_ARP, "called, title_id={:016X}", title_id); + + const auto res = manager.GetControlProperty(title_id); + + if (res.Failed()) { + LOG_ERROR(Service_ARP, "Failed to get control property!"); + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(res.Code()); + } + + ctx.WriteBuffer(*res); + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(RESULT_SUCCESS); +} + +class IRegistrar final : public ServiceFramework { + friend class ARP_W; + +public: + explicit IRegistrar( + std::function)> issuer) + : ServiceFramework{"IRegistrar"}, issue_process_id(std::move(issuer)) { + // clang-format off + static const FunctionInfo functions[] = { + {0, &IRegistrar::Issue, "Issue"}, + {1, &IRegistrar::SetApplicationLaunchProperty, "SetApplicationLaunchProperty"}, + {2, &IRegistrar::SetApplicationControlProperty, "SetApplicationControlProperty"}, + }; + // clang-format on + + RegisterHandlers(functions); + } + +private: + void Issue(Kernel::HLERequestContext& ctx) { + IPC::RequestParser rp{ctx}; + const auto process_id = rp.PopRaw(); + + LOG_DEBUG(Service_ARP, "called, process_id={:016X}", process_id); + + if (process_id == 0) { + LOG_ERROR(Service_ARP, "Must have non-zero process ID!"); + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(ERR_PROCESS_ID_ZERO); + } + + if (issued) { + LOG_ERROR(Service_ARP, + "Attempted to issue registrar, but registrar is already issued!"); + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(ERR_ALREADY_ISSUED); + } + + issue_process_id(process_id, launch, std::move(control)); + issued = true; + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(RESULT_SUCCESS); + } + + void SetApplicationLaunchProperty(Kernel::HLERequestContext& ctx) { + LOG_DEBUG(Service_ARP, "called"); + + if (issued) { + LOG_ERROR( + Service_ARP, + "Attempted to set application launch property, but registrar is already issued!"); + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(ERR_ALREADY_ISSUED); + } + + IPC::RequestParser rp{ctx}; + launch = rp.PopRaw(); + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(RESULT_SUCCESS); + } + + void SetApplicationControlProperty(Kernel::HLERequestContext& ctx) { + LOG_DEBUG(Service_ARP, "called"); + + if (issued) { + LOG_ERROR( + Service_ARP, + "Attempted to set application control property, but registrar is already issued!"); + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(ERR_ALREADY_ISSUED); + } + + control = ctx.ReadBuffer(); + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(RESULT_SUCCESS); + } + + std::function)> issue_process_id; + bool issued = false; + ApplicationLaunchProperty launch; + std::vector control; +}; + +ARP_W::ARP_W(const Core::System& system, ARPManager& manager) + : ServiceFramework{"arp:w"}, system(system), manager(manager) { + // clang-format off + static const FunctionInfo functions[] = { + {0, &ARP_W::AcquireRegistrar, "AcquireRegistrar"}, + {1, &ARP_W::DeleteProperties, "DeleteProperties"}, + }; + // clang-format on + + RegisterHandlers(functions); +} + +ARP_W::~ARP_W() = default; + +void ARP_W::AcquireRegistrar(Kernel::HLERequestContext& ctx) { + LOG_DEBUG(Service_ARP, "called"); + + registrar = std::make_shared( + [this](u64 process_id, ApplicationLaunchProperty launch, std::vector control) { + const auto res = GetTitleIDForProcessID(system, process_id); + if (!res.has_value()) { + return ERR_NONEXISTENT; + } + + return manager.Register(*res, launch, std::move(control)); + }); + + IPC::ResponseBuilder rb{ctx, 2, 0, 1}; + rb.Push(RESULT_SUCCESS); + rb.PushIpcInterface(registrar); +} + +void ARP_W::DeleteProperties(Kernel::HLERequestContext& ctx) { + IPC::RequestParser rp{ctx}; + const auto process_id = rp.PopRaw(); + + LOG_DEBUG(Service_ARP, "called, process_id={:016X}", process_id); + + if (process_id == 0) { + LOG_ERROR(Service_ARP, "Must have non-zero process ID!"); + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(ERR_PROCESS_ID_ZERO); + } + + const auto title_id = GetTitleIDForProcessID(system, process_id); + + if (!title_id.has_value()) { + LOG_ERROR(Service_ARP, "No title ID for process ID!"); + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(ERR_NONEXISTENT); + } + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(manager.Unregister(*title_id)); +} + +} // namespace Service::Glue diff --git a/src/core/hle/service/glue/arp.h b/src/core/hle/service/glue/arp.h new file mode 100644 index 000000000..d5f8a7e7a --- /dev/null +++ b/src/core/hle/service/glue/arp.h @@ -0,0 +1,43 @@ +// Copyright 2019 yuzu emulator team +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#pragma once + +#include "core/hle/service/service.h" + +namespace Service::Glue { + +class ARPManager; +class IRegistrar; + +class ARP_R final : public ServiceFramework { +public: + explicit ARP_R(const Core::System& system, const ARPManager& manager); + ~ARP_R() override; + +private: + void GetApplicationLaunchProperty(Kernel::HLERequestContext& ctx); + void GetApplicationLaunchPropertyWithApplicationId(Kernel::HLERequestContext& ctx); + void GetApplicationControlProperty(Kernel::HLERequestContext& ctx); + void GetApplicationControlPropertyWithApplicationId(Kernel::HLERequestContext& ctx); + + const Core::System& system; + const ARPManager& manager; +}; + +class ARP_W final : public ServiceFramework { +public: + explicit ARP_W(const Core::System& system, ARPManager& manager); + ~ARP_W() override; + +private: + void AcquireRegistrar(Kernel::HLERequestContext& ctx); + void DeleteProperties(Kernel::HLERequestContext& ctx); + + const Core::System& system; + ARPManager& manager; + std::shared_ptr registrar; +}; + +} // namespace Service::Glue diff --git a/src/core/hle/service/service.cpp b/src/core/hle/service/service.cpp index b2954eb34..beae9c510 100644 --- a/src/core/hle/service/service.cpp +++ b/src/core/hle/service/service.cpp @@ -19,7 +19,6 @@ #include "core/hle/service/am/am.h" #include "core/hle/service/aoc/aoc_u.h" #include "core/hle/service/apm/apm.h" -#include "core/hle/service/arp/arp.h" #include "core/hle/service/audio/audio.h" #include "core/hle/service/bcat/module.h" #include "core/hle/service/bpc/bpc.h" @@ -33,6 +32,7 @@ #include "core/hle/service/fgm/fgm.h" #include "core/hle/service/filesystem/filesystem.h" #include "core/hle/service/friend/friend.h" +#include "core/hle/service/glue/glue.h" #include "core/hle/service/grc/grc.h" #include "core/hle/service/hid/hid.h" #include "core/hle/service/lbl/lbl.h" @@ -207,7 +207,6 @@ void Init(std::shared_ptr& sm, Core::System& system, AM::InstallInterfaces(*sm, nv_flinger); AOC::InstallInterfaces(*sm); APM::InstallInterfaces(*sm); - ARP::InstallInterfaces(*sm); Audio::InstallInterfaces(*sm); BCAT::InstallInterfaces(*sm); BPC::InstallInterfaces(*sm); @@ -221,6 +220,7 @@ void Init(std::shared_ptr& sm, Core::System& system, FGM::InstallInterfaces(*sm); FileSystem::InstallInterfaces(*sm, vfs); Friend::InstallInterfaces(*sm); + Glue::InstallInterfaces(system); GRC::InstallInterfaces(*sm); HID::InstallInterfaces(*sm); LBL::InstallInterfaces(*sm); -- cgit v1.2.3 From d10fc2d7277cf075f875fe2831501cb79c50e21a Mon Sep 17 00:00:00 2001 From: Zach Hilman Date: Tue, 25 Jun 2019 22:25:10 -0400 Subject: glue: Correct missing bytes in ApplicationLaunchParameter --- src/core/hle/service/glue/arp.cpp | 30 +++++++++++++++++++++--------- src/core/hle/service/glue/errors.h | 9 ++++----- src/core/hle/service/glue/manager.cpp | 21 +++++++++++++-------- src/core/hle/service/glue/manager.h | 29 +++++++++++++++++++++++------ 4 files changed, 61 insertions(+), 28 deletions(-) (limited to 'src/core/hle/service') diff --git a/src/core/hle/service/glue/arp.cpp b/src/core/hle/service/glue/arp.cpp index 19c75ff2f..b591ce31b 100644 --- a/src/core/hle/service/glue/arp.cpp +++ b/src/core/hle/service/glue/arp.cpp @@ -58,7 +58,8 @@ void ARP_R::GetApplicationLaunchProperty(Kernel::HLERequestContext& ctx) { if (!title_id.has_value()) { LOG_ERROR(Service_ARP, "Failed to get title ID for process ID!"); IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(ERR_NONEXISTENT); + rb.Push(ERR_NOT_REGISTERED); + return; } const auto res = manager.GetLaunchProperty(*title_id); @@ -67,6 +68,7 @@ void ARP_R::GetApplicationLaunchProperty(Kernel::HLERequestContext& ctx) { LOG_ERROR(Service_ARP, "Failed to get launch property!"); IPC::ResponseBuilder rb{ctx, 2}; rb.Push(res.Code()); + return; } IPC::ResponseBuilder rb{ctx, 6}; @@ -86,6 +88,7 @@ void ARP_R::GetApplicationLaunchPropertyWithApplicationId(Kernel::HLERequestCont LOG_ERROR(Service_ARP, "Failed to get launch property!"); IPC::ResponseBuilder rb{ctx, 2}; rb.Push(res.Code()); + return; } IPC::ResponseBuilder rb{ctx, 6}; @@ -103,7 +106,8 @@ void ARP_R::GetApplicationControlProperty(Kernel::HLERequestContext& ctx) { if (!title_id.has_value()) { LOG_ERROR(Service_ARP, "Failed to get title ID for process ID!"); IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(ERR_NONEXISTENT); + rb.Push(ERR_NOT_REGISTERED); + return; } const auto res = manager.GetControlProperty(*title_id); @@ -112,6 +116,7 @@ void ARP_R::GetApplicationControlProperty(Kernel::HLERequestContext& ctx) { LOG_ERROR(Service_ARP, "Failed to get control property!"); IPC::ResponseBuilder rb{ctx, 2}; rb.Push(res.Code()); + return; } ctx.WriteBuffer(*res); @@ -132,6 +137,7 @@ void ARP_R::GetApplicationControlPropertyWithApplicationId(Kernel::HLERequestCon LOG_ERROR(Service_ARP, "Failed to get control property!"); IPC::ResponseBuilder rb{ctx, 2}; rb.Push(res.Code()); + return; } ctx.WriteBuffer(*res); @@ -168,14 +174,16 @@ private: if (process_id == 0) { LOG_ERROR(Service_ARP, "Must have non-zero process ID!"); IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(ERR_PROCESS_ID_ZERO); + rb.Push(ERR_INVALID_PROCESS_ID); + return; } if (issued) { LOG_ERROR(Service_ARP, "Attempted to issue registrar, but registrar is already issued!"); IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(ERR_ALREADY_ISSUED); + rb.Push(ERR_INVALID_ACCESS); + return; } issue_process_id(process_id, launch, std::move(control)); @@ -193,7 +201,8 @@ private: Service_ARP, "Attempted to set application launch property, but registrar is already issued!"); IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(ERR_ALREADY_ISSUED); + rb.Push(ERR_INVALID_ACCESS); + return; } IPC::RequestParser rp{ctx}; @@ -211,7 +220,8 @@ private: Service_ARP, "Attempted to set application control property, but registrar is already issued!"); IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(ERR_ALREADY_ISSUED); + rb.Push(ERR_INVALID_ACCESS); + return; } control = ctx.ReadBuffer(); @@ -247,7 +257,7 @@ void ARP_W::AcquireRegistrar(Kernel::HLERequestContext& ctx) { [this](u64 process_id, ApplicationLaunchProperty launch, std::vector control) { const auto res = GetTitleIDForProcessID(system, process_id); if (!res.has_value()) { - return ERR_NONEXISTENT; + return ERR_NOT_REGISTERED; } return manager.Register(*res, launch, std::move(control)); @@ -267,7 +277,8 @@ void ARP_W::DeleteProperties(Kernel::HLERequestContext& ctx) { if (process_id == 0) { LOG_ERROR(Service_ARP, "Must have non-zero process ID!"); IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(ERR_PROCESS_ID_ZERO); + rb.Push(ERR_INVALID_PROCESS_ID); + return; } const auto title_id = GetTitleIDForProcessID(system, process_id); @@ -275,7 +286,8 @@ void ARP_W::DeleteProperties(Kernel::HLERequestContext& ctx) { if (!title_id.has_value()) { LOG_ERROR(Service_ARP, "No title ID for process ID!"); IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(ERR_NONEXISTENT); + rb.Push(ERR_NOT_REGISTERED); + return; } IPC::ResponseBuilder rb{ctx, 2}; diff --git a/src/core/hle/service/glue/errors.h b/src/core/hle/service/glue/errors.h index 594e20a01..c2874c585 100644 --- a/src/core/hle/service/glue/errors.h +++ b/src/core/hle/service/glue/errors.h @@ -8,10 +8,9 @@ namespace Service::Glue { -constexpr ResultCode ERR_OUTPUT_TOO_SMALL{0x3C9D}; -constexpr ResultCode ERR_PROCESS_ID_ZERO{0x3E9D}; -constexpr ResultCode ERR_TITLE_ID_ZERO{0x3E9D}; -constexpr ResultCode ERR_ALREADY_ISSUED{0x549D}; -constexpr ResultCode ERR_NONEXISTENT{0xCC9D}; +constexpr ResultCode ERR_INVALID_RESOURCE{ErrorModule::ARP, 0x1E}; +constexpr ResultCode ERR_INVALID_PROCESS_ID{ErrorModule::ARP, 0x1F}; +constexpr ResultCode ERR_INVALID_ACCESS{ErrorModule::ARP, 0x2A}; +constexpr ResultCode ERR_NOT_REGISTERED{ErrorModule::ARP, 0x66}; } // namespace Service::Glue diff --git a/src/core/hle/service/glue/manager.cpp b/src/core/hle/service/glue/manager.cpp index 0d5bb4d50..6da52d2d6 100644 --- a/src/core/hle/service/glue/manager.cpp +++ b/src/core/hle/service/glue/manager.cpp @@ -7,18 +7,23 @@ namespace Service::Glue { +struct ARPManager::MapEntry { + ApplicationLaunchProperty launch; + std::vector control; +}; + ARPManager::ARPManager() = default; ARPManager::~ARPManager() = default; ResultVal ARPManager::GetLaunchProperty(u64 title_id) const { if (title_id == 0) { - return ERR_TITLE_ID_ZERO; + return ERR_INVALID_PROCESS_ID; } const auto iter = entries.find(title_id); if (iter == entries.end()) { - return ERR_NONEXISTENT; + return ERR_NOT_REGISTERED; } return MakeResult(iter->second.launch); @@ -26,12 +31,12 @@ ResultVal ARPManager::GetLaunchProperty(u64 title_id) ResultVal> ARPManager::GetControlProperty(u64 title_id) const { if (title_id == 0) { - return ERR_TITLE_ID_ZERO; + return ERR_INVALID_PROCESS_ID; } const auto iter = entries.find(title_id); if (iter == entries.end()) { - return ERR_NONEXISTENT; + return ERR_NOT_REGISTERED; } return MakeResult>(iter->second.control); @@ -40,12 +45,12 @@ ResultVal> ARPManager::GetControlProperty(u64 title_id) const { ResultCode ARPManager::Register(u64 title_id, ApplicationLaunchProperty launch, std::vector control) { if (title_id == 0) { - return ERR_TITLE_ID_ZERO; + return ERR_INVALID_PROCESS_ID; } const auto iter = entries.find(title_id); if (iter != entries.end()) { - return ERR_ALREADY_ISSUED; + return ERR_INVALID_ACCESS; } entries.insert_or_assign(title_id, MapEntry{launch, std::move(control)}); @@ -54,12 +59,12 @@ ResultCode ARPManager::Register(u64 title_id, ApplicationLaunchProperty launch, ResultCode ARPManager::Unregister(u64 title_id) { if (title_id == 0) { - return ERR_TITLE_ID_ZERO; + return ERR_INVALID_PROCESS_ID; } const auto iter = entries.find(title_id); if (iter == entries.end()) { - return ERR_NONEXISTENT; + return ERR_NOT_REGISTERED; } entries.erase(iter); diff --git a/src/core/hle/service/glue/manager.h b/src/core/hle/service/glue/manager.h index 561ebf4e0..a7f5ce3ee 100644 --- a/src/core/hle/service/glue/manager.h +++ b/src/core/hle/service/glue/manager.h @@ -4,6 +4,9 @@ #pragma once +#include +#include +#include "common/common_types.h" #include "core/file_sys/control_metadata.h" #include "core/file_sys/romfs_factory.h" #include "core/hle/result.h" @@ -15,31 +18,45 @@ struct ApplicationLaunchProperty { u32 version; FileSys::StorageId base_game_storage_id; FileSys::StorageId update_storage_id; - INSERT_PADDING_BYTES(0x2); + u8 program_index; + u8 reserved; }; static_assert(sizeof(ApplicationLaunchProperty) == 0x10, "ApplicationLaunchProperty has incorrect size."); +// A class to manage state related to the arp:w and arp:r services, specifically the registration +// and unregistration of launch and control properties. class ARPManager { public: ARPManager(); ~ARPManager(); + // Returns the ApplicationLaunchProperty corresponding to the provided title ID if it was + // previously registered, otherwise ERR_NOT_REGISTERED if it was never registered or + // ERR_INVALID_PROCESS_ID if the title ID is 0. ResultVal GetLaunchProperty(u64 title_id) const; + + // Returns a vector of the raw bytes of NACP data (necessarily 0x4000 in size) corresponding to + // the provided title ID if it was previously registered, otherwise ERR_NOT_REGISTERED if it was + // never registered or ERR_INVALID_PROCESS_ID if the title ID is 0. ResultVal> GetControlProperty(u64 title_id) const; + // Adds a new entry to the internal database with the provided parameters, returning + // ERR_INVALID_ACCESS if attempting to re-register a title ID without an intermediate Unregister + // step, and ERR_INVALID_PROCESS_ID if the title ID is 0. ResultCode Register(u64 title_id, ApplicationLaunchProperty launch, std::vector control); + // Removes the registration for the provided title ID from the database, returning + // ERR_NOT_REGISTERED if it doesn't exist in the database and ERR_INVALID_PROCESS_ID if the + // title ID is 0. ResultCode Unregister(u64 title_id); + // Removes all entries from the database, always succeeds. Should only be used when resetting + // system state. void ResetAll(); private: - struct MapEntry { - ApplicationLaunchProperty launch; - std::vector control; - }; - + struct MapEntry; std::map entries; }; -- cgit v1.2.3