summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Zach Hilman2019-06-24 19:26:16 -0400
committerGravatar Zach Hilman2019-06-24 19:26:16 -0400
commitce2197302236c0990d2d5234ab52f1579c126090 (patch)
tree7ed28d8bdf835371dbc44ca0f799ba0a9ab77b1b
parentglue: Add errors for glue/arp services (diff)
downloadyuzu-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.cpp285
-rw-r--r--src/core/hle/service/glue/arp.h43
-rw-r--r--src/core/hle/service/service.cpp4
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
18namespace Service::Glue {
19
20namespace {
21std::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
35ARP_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
49ARP_R::~ARP_R() = default;
50
51void 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
77void 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
96void 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
123void 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
143class IRegistrar final : public ServiceFramework<IRegistrar> {
144 friend class ARP_W;
145
146public:
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
161private:
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
229ARP_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
241ARP_W::~ARP_W() = default;
242
243void 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
261void 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
9namespace Service::Glue {
10
11class ARPManager;
12class IRegistrar;
13
14class ARP_R final : public ServiceFramework<ARP_R> {
15public:
16 explicit ARP_R(const Core::System& system, const ARPManager& manager);
17 ~ARP_R() override;
18
19private:
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
29class ARP_W final : public ServiceFramework<ARP_W> {
30public:
31 explicit ARP_W(const Core::System& system, ARPManager& manager);
32 ~ARP_W() override;
33
34private:
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);