| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298 |
- // Copyright 2018 yuzu emulator team
- // Licensed under GPLv2 or any later version
- // Refer to the license.txt file included.
- #include <memory>
- #include "common/logging/log.h"
- #include "core/core.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<u64> 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<u64>();
- 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_NOT_REGISTERED);
- return;
- }
- 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());
- return;
- }
- 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<u64>();
- 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());
- return;
- }
- 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<u64>();
- 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_NOT_REGISTERED);
- return;
- }
- 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());
- return;
- }
- 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<u64>();
- 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());
- return;
- }
- ctx.WriteBuffer(*res);
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(RESULT_SUCCESS);
- }
- class IRegistrar final : public ServiceFramework<IRegistrar> {
- friend class ARP_W;
- public:
- explicit IRegistrar(
- std::function<ResultCode(u64, ApplicationLaunchProperty, std::vector<u8>)> 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<u64>();
- 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_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_INVALID_ACCESS);
- return;
- }
- 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_INVALID_ACCESS);
- return;
- }
- IPC::RequestParser rp{ctx};
- launch = rp.PopRaw<ApplicationLaunchProperty>();
- 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_INVALID_ACCESS);
- return;
- }
- control = ctx.ReadBuffer();
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(RESULT_SUCCESS);
- }
- std::function<ResultCode(u64, ApplicationLaunchProperty, std::vector<u8>)> issue_process_id;
- bool issued = false;
- ApplicationLaunchProperty launch;
- std::vector<u8> 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<IRegistrar>(
- [this](u64 process_id, ApplicationLaunchProperty launch, std::vector<u8> control) {
- const auto res = GetTitleIDForProcessID(system, process_id);
- if (!res.has_value()) {
- return ERR_NOT_REGISTERED;
- }
- 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<u64>();
- 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_INVALID_PROCESS_ID);
- return;
- }
- 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_NOT_REGISTERED);
- return;
- }
- IPC::ResponseBuilder rb{ctx, 2};
- rb.Push(manager.Unregister(*title_id));
- }
- } // namespace Service::Glue
|