diff options
| author | 2019-06-24 19:26:16 -0400 | |
|---|---|---|
| committer | 2019-06-24 19:26:16 -0400 | |
| commit | ce2197302236c0990d2d5234ab52f1579c126090 (patch) | |
| tree | 7ed28d8bdf835371dbc44ca0f799ba0a9ab77b1b | |
| parent | glue: Add errors for glue/arp services (diff) | |
| download | yuzu-ce2197302236c0990d2d5234ab52f1579c126090.tar.gz yuzu-ce2197302236c0990d2d5234ab52f1579c126090.tar.xz yuzu-ce2197302236c0990d2d5234ab52f1579c126090.zip | |
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.
| -rw-r--r-- | src/core/hle/service/glue/arp.cpp | 285 | ||||
| -rw-r--r-- | src/core/hle/service/glue/arp.h | 43 | ||||
| -rw-r--r-- | src/core/hle/service/service.cpp | 4 |
3 files changed, 330 insertions, 2 deletions
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 @@ | |||
| 1 | // Copyright 2018 yuzu emulator team | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #include <memory> | ||
| 6 | |||
| 7 | #include "common/logging/log.h" | ||
| 8 | #include "core/file_sys/control_metadata.h" | ||
| 9 | #include "core/hle/ipc_helpers.h" | ||
| 10 | #include "core/hle/kernel/hle_ipc.h" | ||
| 11 | #include "core/hle/kernel/kernel.h" | ||
| 12 | #include "core/hle/kernel/process.h" | ||
| 13 | #include "core/hle/service/glue/arp.h" | ||
| 14 | #include "core/hle/service/glue/errors.h" | ||
| 15 | #include "core/hle/service/glue/manager.h" | ||
| 16 | #include "core/hle/service/service.h" | ||
| 17 | |||
| 18 | namespace Service::Glue { | ||
| 19 | |||
| 20 | namespace { | ||
| 21 | std::optional<u64> GetTitleIDForProcessID(const Core::System& system, u64 process_id) { | ||
| 22 | const auto& list = system.Kernel().GetProcessList(); | ||
| 23 | const auto iter = std::find_if(list.begin(), list.end(), [&process_id](const auto& process) { | ||
| 24 | return process->GetProcessID() == process_id; | ||
| 25 | }); | ||
| 26 | |||
| 27 | if (iter == list.end()) { | ||
| 28 | return std::nullopt; | ||
| 29 | } | ||
| 30 | |||
| 31 | return (*iter)->GetTitleID(); | ||
| 32 | } | ||
| 33 | } // Anonymous namespace | ||
| 34 | |||
| 35 | ARP_R::ARP_R(const Core::System& system, const ARPManager& manager) | ||
| 36 | : ServiceFramework{"arp:r"}, system(system), manager(manager) { | ||
| 37 | // clang-format off | ||
| 38 | static const FunctionInfo functions[] = { | ||
| 39 | {0, &ARP_R::GetApplicationLaunchProperty, "GetApplicationLaunchProperty"}, | ||
| 40 | {1, &ARP_R::GetApplicationLaunchPropertyWithApplicationId, "GetApplicationLaunchPropertyWithApplicationId"}, | ||
| 41 | {2, &ARP_R::GetApplicationControlProperty, "GetApplicationControlProperty"}, | ||
| 42 | {3, &ARP_R::GetApplicationControlPropertyWithApplicationId, "GetApplicationControlPropertyWithApplicationId"}, | ||
| 43 | }; | ||
| 44 | // clang-format on | ||
| 45 | |||
| 46 | RegisterHandlers(functions); | ||
| 47 | } | ||
| 48 | |||
| 49 | ARP_R::~ARP_R() = default; | ||
| 50 | |||
| 51 | void ARP_R::GetApplicationLaunchProperty(Kernel::HLERequestContext& ctx) { | ||
| 52 | IPC::RequestParser rp{ctx}; | ||
| 53 | const auto process_id = rp.PopRaw<u64>(); | ||
| 54 | |||
| 55 | LOG_DEBUG(Service_ARP, "called, process_id={:016X}", process_id); | ||
| 56 | |||
| 57 | const auto title_id = GetTitleIDForProcessID(system, process_id); | ||
| 58 | if (!title_id.has_value()) { | ||
| 59 | LOG_ERROR(Service_ARP, "Failed to get title ID for process ID!"); | ||
| 60 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 61 | rb.Push(ERR_NONEXISTENT); | ||
| 62 | } | ||
| 63 | |||
| 64 | const auto res = manager.GetLaunchProperty(*title_id); | ||
| 65 | |||
| 66 | if (res.Failed()) { | ||
| 67 | LOG_ERROR(Service_ARP, "Failed to get launch property!"); | ||
| 68 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 69 | rb.Push(res.Code()); | ||
| 70 | } | ||
| 71 | |||
| 72 | IPC::ResponseBuilder rb{ctx, 6}; | ||
| 73 | rb.Push(RESULT_SUCCESS); | ||
| 74 | rb.PushRaw(*res); | ||
| 75 | } | ||
| 76 | |||
| 77 | void ARP_R::GetApplicationLaunchPropertyWithApplicationId(Kernel::HLERequestContext& ctx) { | ||
| 78 | IPC::RequestParser rp{ctx}; | ||
| 79 | const auto title_id = rp.PopRaw<u64>(); | ||
| 80 | |||
| 81 | LOG_DEBUG(Service_ARP, "called, title_id={:016X}", title_id); | ||
| 82 | |||
| 83 | const auto res = manager.GetLaunchProperty(title_id); | ||
| 84 | |||
| 85 | if (res.Failed()) { | ||
| 86 | LOG_ERROR(Service_ARP, "Failed to get launch property!"); | ||
| 87 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 88 | rb.Push(res.Code()); | ||
| 89 | } | ||
| 90 | |||
| 91 | IPC::ResponseBuilder rb{ctx, 6}; | ||
| 92 | rb.Push(RESULT_SUCCESS); | ||
| 93 | rb.PushRaw(*res); | ||
| 94 | } | ||
| 95 | |||
| 96 | void ARP_R::GetApplicationControlProperty(Kernel::HLERequestContext& ctx) { | ||
| 97 | IPC::RequestParser rp{ctx}; | ||
| 98 | const auto process_id = rp.PopRaw<u64>(); | ||
| 99 | |||
| 100 | LOG_DEBUG(Service_ARP, "called, process_id={:016X}", process_id); | ||
| 101 | |||
| 102 | const auto title_id = GetTitleIDForProcessID(system, process_id); | ||
| 103 | if (!title_id.has_value()) { | ||
| 104 | LOG_ERROR(Service_ARP, "Failed to get title ID for process ID!"); | ||
| 105 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 106 | rb.Push(ERR_NONEXISTENT); | ||
| 107 | } | ||
| 108 | |||
| 109 | const auto res = manager.GetControlProperty(*title_id); | ||
| 110 | |||
| 111 | if (res.Failed()) { | ||
| 112 | LOG_ERROR(Service_ARP, "Failed to get control property!"); | ||
| 113 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 114 | rb.Push(res.Code()); | ||
| 115 | } | ||
| 116 | |||
| 117 | ctx.WriteBuffer(*res); | ||
| 118 | |||
| 119 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 120 | rb.Push(RESULT_SUCCESS); | ||
| 121 | } | ||
| 122 | |||
| 123 | void ARP_R::GetApplicationControlPropertyWithApplicationId(Kernel::HLERequestContext& ctx) { | ||
| 124 | IPC::RequestParser rp{ctx}; | ||
| 125 | const auto title_id = rp.PopRaw<u64>(); | ||
| 126 | |||
| 127 | LOG_DEBUG(Service_ARP, "called, title_id={:016X}", title_id); | ||
| 128 | |||
| 129 | const auto res = manager.GetControlProperty(title_id); | ||
| 130 | |||
| 131 | if (res.Failed()) { | ||
| 132 | LOG_ERROR(Service_ARP, "Failed to get control property!"); | ||
| 133 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 134 | rb.Push(res.Code()); | ||
| 135 | } | ||
| 136 | |||
| 137 | ctx.WriteBuffer(*res); | ||
| 138 | |||
| 139 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 140 | rb.Push(RESULT_SUCCESS); | ||
| 141 | } | ||
| 142 | |||
| 143 | class IRegistrar final : public ServiceFramework<IRegistrar> { | ||
| 144 | friend class ARP_W; | ||
| 145 | |||
| 146 | public: | ||
| 147 | explicit IRegistrar( | ||
| 148 | std::function<ResultCode(u64, ApplicationLaunchProperty, std::vector<u8>)> issuer) | ||
| 149 | : ServiceFramework{"IRegistrar"}, issue_process_id(std::move(issuer)) { | ||
| 150 | // clang-format off | ||
| 151 | static const FunctionInfo functions[] = { | ||
| 152 | {0, &IRegistrar::Issue, "Issue"}, | ||
| 153 | {1, &IRegistrar::SetApplicationLaunchProperty, "SetApplicationLaunchProperty"}, | ||
| 154 | {2, &IRegistrar::SetApplicationControlProperty, "SetApplicationControlProperty"}, | ||
| 155 | }; | ||
| 156 | // clang-format on | ||
| 157 | |||
| 158 | RegisterHandlers(functions); | ||
| 159 | } | ||
| 160 | |||
| 161 | private: | ||
| 162 | void Issue(Kernel::HLERequestContext& ctx) { | ||
| 163 | IPC::RequestParser rp{ctx}; | ||
| 164 | const auto process_id = rp.PopRaw<u64>(); | ||
| 165 | |||
| 166 | LOG_DEBUG(Service_ARP, "called, process_id={:016X}", process_id); | ||
| 167 | |||
| 168 | if (process_id == 0) { | ||
| 169 | LOG_ERROR(Service_ARP, "Must have non-zero process ID!"); | ||
| 170 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 171 | rb.Push(ERR_PROCESS_ID_ZERO); | ||
| 172 | } | ||
| 173 | |||
| 174 | if (issued) { | ||
| 175 | LOG_ERROR(Service_ARP, | ||
| 176 | "Attempted to issue registrar, but registrar is already issued!"); | ||
| 177 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 178 | rb.Push(ERR_ALREADY_ISSUED); | ||
| 179 | } | ||
| 180 | |||
| 181 | issue_process_id(process_id, launch, std::move(control)); | ||
| 182 | issued = true; | ||
| 183 | |||
| 184 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 185 | rb.Push(RESULT_SUCCESS); | ||
| 186 | } | ||
| 187 | |||
| 188 | void SetApplicationLaunchProperty(Kernel::HLERequestContext& ctx) { | ||
| 189 | LOG_DEBUG(Service_ARP, "called"); | ||
| 190 | |||
| 191 | if (issued) { | ||
| 192 | LOG_ERROR( | ||
| 193 | Service_ARP, | ||
| 194 | "Attempted to set application launch property, but registrar is already issued!"); | ||
| 195 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 196 | rb.Push(ERR_ALREADY_ISSUED); | ||
| 197 | } | ||
| 198 | |||
| 199 | IPC::RequestParser rp{ctx}; | ||
| 200 | launch = rp.PopRaw<ApplicationLaunchProperty>(); | ||
| 201 | |||
| 202 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 203 | rb.Push(RESULT_SUCCESS); | ||
| 204 | } | ||
| 205 | |||
| 206 | void SetApplicationControlProperty(Kernel::HLERequestContext& ctx) { | ||
| 207 | LOG_DEBUG(Service_ARP, "called"); | ||
| 208 | |||
| 209 | if (issued) { | ||
| 210 | LOG_ERROR( | ||
| 211 | Service_ARP, | ||
| 212 | "Attempted to set application control property, but registrar is already issued!"); | ||
| 213 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 214 | rb.Push(ERR_ALREADY_ISSUED); | ||
| 215 | } | ||
| 216 | |||
| 217 | control = ctx.ReadBuffer(); | ||
| 218 | |||
| 219 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 220 | rb.Push(RESULT_SUCCESS); | ||
| 221 | } | ||
| 222 | |||
| 223 | std::function<ResultCode(u64, ApplicationLaunchProperty, std::vector<u8>)> issue_process_id; | ||
| 224 | bool issued = false; | ||
| 225 | ApplicationLaunchProperty launch; | ||
| 226 | std::vector<u8> control; | ||
| 227 | }; | ||
| 228 | |||
| 229 | ARP_W::ARP_W(const Core::System& system, ARPManager& manager) | ||
| 230 | : ServiceFramework{"arp:w"}, system(system), manager(manager) { | ||
| 231 | // clang-format off | ||
| 232 | static const FunctionInfo functions[] = { | ||
| 233 | {0, &ARP_W::AcquireRegistrar, "AcquireRegistrar"}, | ||
| 234 | {1, &ARP_W::DeleteProperties, "DeleteProperties"}, | ||
| 235 | }; | ||
| 236 | // clang-format on | ||
| 237 | |||
| 238 | RegisterHandlers(functions); | ||
| 239 | } | ||
| 240 | |||
| 241 | ARP_W::~ARP_W() = default; | ||
| 242 | |||
| 243 | void ARP_W::AcquireRegistrar(Kernel::HLERequestContext& ctx) { | ||
| 244 | LOG_DEBUG(Service_ARP, "called"); | ||
| 245 | |||
| 246 | registrar = std::make_shared<IRegistrar>( | ||
| 247 | [this](u64 process_id, ApplicationLaunchProperty launch, std::vector<u8> control) { | ||
| 248 | const auto res = GetTitleIDForProcessID(system, process_id); | ||
| 249 | if (!res.has_value()) { | ||
| 250 | return ERR_NONEXISTENT; | ||
| 251 | } | ||
| 252 | |||
| 253 | return manager.Register(*res, launch, std::move(control)); | ||
| 254 | }); | ||
| 255 | |||
| 256 | IPC::ResponseBuilder rb{ctx, 2, 0, 1}; | ||
| 257 | rb.Push(RESULT_SUCCESS); | ||
| 258 | rb.PushIpcInterface(registrar); | ||
| 259 | } | ||
| 260 | |||
| 261 | void ARP_W::DeleteProperties(Kernel::HLERequestContext& ctx) { | ||
| 262 | IPC::RequestParser rp{ctx}; | ||
| 263 | const auto process_id = rp.PopRaw<u64>(); | ||
| 264 | |||
| 265 | LOG_DEBUG(Service_ARP, "called, process_id={:016X}", process_id); | ||
| 266 | |||
| 267 | if (process_id == 0) { | ||
| 268 | LOG_ERROR(Service_ARP, "Must have non-zero process ID!"); | ||
| 269 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 270 | rb.Push(ERR_PROCESS_ID_ZERO); | ||
| 271 | } | ||
| 272 | |||
| 273 | const auto title_id = GetTitleIDForProcessID(system, process_id); | ||
| 274 | |||
| 275 | if (!title_id.has_value()) { | ||
| 276 | LOG_ERROR(Service_ARP, "No title ID for process ID!"); | ||
| 277 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 278 | rb.Push(ERR_NONEXISTENT); | ||
| 279 | } | ||
| 280 | |||
| 281 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 282 | rb.Push(manager.Unregister(*title_id)); | ||
| 283 | } | ||
| 284 | |||
| 285 | } // 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 @@ | |||
| 1 | // Copyright 2019 yuzu emulator team | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #pragma once | ||
| 6 | |||
| 7 | #include "core/hle/service/service.h" | ||
| 8 | |||
| 9 | namespace Service::Glue { | ||
| 10 | |||
| 11 | class ARPManager; | ||
| 12 | class IRegistrar; | ||
| 13 | |||
| 14 | class ARP_R final : public ServiceFramework<ARP_R> { | ||
| 15 | public: | ||
| 16 | explicit ARP_R(const Core::System& system, const ARPManager& manager); | ||
| 17 | ~ARP_R() override; | ||
| 18 | |||
| 19 | private: | ||
| 20 | void GetApplicationLaunchProperty(Kernel::HLERequestContext& ctx); | ||
| 21 | void GetApplicationLaunchPropertyWithApplicationId(Kernel::HLERequestContext& ctx); | ||
| 22 | void GetApplicationControlProperty(Kernel::HLERequestContext& ctx); | ||
| 23 | void GetApplicationControlPropertyWithApplicationId(Kernel::HLERequestContext& ctx); | ||
| 24 | |||
| 25 | const Core::System& system; | ||
| 26 | const ARPManager& manager; | ||
| 27 | }; | ||
| 28 | |||
| 29 | class ARP_W final : public ServiceFramework<ARP_W> { | ||
| 30 | public: | ||
| 31 | explicit ARP_W(const Core::System& system, ARPManager& manager); | ||
| 32 | ~ARP_W() override; | ||
| 33 | |||
| 34 | private: | ||
| 35 | void AcquireRegistrar(Kernel::HLERequestContext& ctx); | ||
| 36 | void DeleteProperties(Kernel::HLERequestContext& ctx); | ||
| 37 | |||
| 38 | const Core::System& system; | ||
| 39 | ARPManager& manager; | ||
| 40 | std::shared_ptr<IRegistrar> registrar; | ||
| 41 | }; | ||
| 42 | |||
| 43 | } // 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 @@ | |||
| 19 | #include "core/hle/service/am/am.h" | 19 | #include "core/hle/service/am/am.h" |
| 20 | #include "core/hle/service/aoc/aoc_u.h" | 20 | #include "core/hle/service/aoc/aoc_u.h" |
| 21 | #include "core/hle/service/apm/apm.h" | 21 | #include "core/hle/service/apm/apm.h" |
| 22 | #include "core/hle/service/arp/arp.h" | ||
| 23 | #include "core/hle/service/audio/audio.h" | 22 | #include "core/hle/service/audio/audio.h" |
| 24 | #include "core/hle/service/bcat/module.h" | 23 | #include "core/hle/service/bcat/module.h" |
| 25 | #include "core/hle/service/bpc/bpc.h" | 24 | #include "core/hle/service/bpc/bpc.h" |
| @@ -33,6 +32,7 @@ | |||
| 33 | #include "core/hle/service/fgm/fgm.h" | 32 | #include "core/hle/service/fgm/fgm.h" |
| 34 | #include "core/hle/service/filesystem/filesystem.h" | 33 | #include "core/hle/service/filesystem/filesystem.h" |
| 35 | #include "core/hle/service/friend/friend.h" | 34 | #include "core/hle/service/friend/friend.h" |
| 35 | #include "core/hle/service/glue/glue.h" | ||
| 36 | #include "core/hle/service/grc/grc.h" | 36 | #include "core/hle/service/grc/grc.h" |
| 37 | #include "core/hle/service/hid/hid.h" | 37 | #include "core/hle/service/hid/hid.h" |
| 38 | #include "core/hle/service/lbl/lbl.h" | 38 | #include "core/hle/service/lbl/lbl.h" |
| @@ -207,7 +207,6 @@ void Init(std::shared_ptr<SM::ServiceManager>& sm, Core::System& system, | |||
| 207 | AM::InstallInterfaces(*sm, nv_flinger); | 207 | AM::InstallInterfaces(*sm, nv_flinger); |
| 208 | AOC::InstallInterfaces(*sm); | 208 | AOC::InstallInterfaces(*sm); |
| 209 | APM::InstallInterfaces(*sm); | 209 | APM::InstallInterfaces(*sm); |
| 210 | ARP::InstallInterfaces(*sm); | ||
| 211 | Audio::InstallInterfaces(*sm); | 210 | Audio::InstallInterfaces(*sm); |
| 212 | BCAT::InstallInterfaces(*sm); | 211 | BCAT::InstallInterfaces(*sm); |
| 213 | BPC::InstallInterfaces(*sm); | 212 | BPC::InstallInterfaces(*sm); |
| @@ -221,6 +220,7 @@ void Init(std::shared_ptr<SM::ServiceManager>& sm, Core::System& system, | |||
| 221 | FGM::InstallInterfaces(*sm); | 220 | FGM::InstallInterfaces(*sm); |
| 222 | FileSystem::InstallInterfaces(*sm, vfs); | 221 | FileSystem::InstallInterfaces(*sm, vfs); |
| 223 | Friend::InstallInterfaces(*sm); | 222 | Friend::InstallInterfaces(*sm); |
| 223 | Glue::InstallInterfaces(system); | ||
| 224 | GRC::InstallInterfaces(*sm); | 224 | GRC::InstallInterfaces(*sm); |
| 225 | HID::InstallInterfaces(*sm); | 225 | HID::InstallInterfaces(*sm); |
| 226 | LBL::InstallInterfaces(*sm); | 226 | LBL::InstallInterfaces(*sm); |