summaryrefslogtreecommitdiff
path: root/src/core
diff options
context:
space:
mode:
authorGravatar bunnei2019-06-26 10:26:44 -0400
committerGravatar GitHub2019-06-26 10:26:44 -0400
commit4ed2774c26602d6ee1af316da5faf391d377d701 (patch)
treea1ef0e65dfd79f8badde8dcd24014432428c51f8 /src/core
parentMerge pull request #2603 from WamWooWam/master (diff)
parentglue: Correct missing bytes in ApplicationLaunchParameter (diff)
downloadyuzu-4ed2774c26602d6ee1af316da5faf391d377d701.tar.gz
yuzu-4ed2774c26602d6ee1af316da5faf391d377d701.tar.xz
yuzu-4ed2774c26602d6ee1af316da5faf391d377d701.zip
Merge pull request #2607 from DarkLordZach/arp-1
glue: Implement arp:w and arp:r services
Diffstat (limited to 'src/core')
-rw-r--r--src/core/CMakeLists.txt11
-rw-r--r--src/core/core.cpp66
-rw-r--r--src/core/core.h8
-rw-r--r--src/core/file_sys/patch_manager.cpp10
-rw-r--r--src/core/file_sys/patch_manager.h9
-rw-r--r--src/core/file_sys/registered_cache.cpp14
-rw-r--r--src/core/file_sys/registered_cache.h3
-rw-r--r--src/core/hle/service/arp/arp.cpp75
-rw-r--r--src/core/hle/service/arp/arp.h16
-rw-r--r--src/core/hle/service/glue/arp.cpp297
-rw-r--r--src/core/hle/service/glue/arp.h43
-rw-r--r--src/core/hle/service/glue/bgtc.cpp50
-rw-r--r--src/core/hle/service/glue/bgtc.h23
-rw-r--r--src/core/hle/service/glue/errors.h16
-rw-r--r--src/core/hle/service/glue/glue.cpp25
-rw-r--r--src/core/hle/service/glue/glue.h16
-rw-r--r--src/core/hle/service/glue/manager.cpp78
-rw-r--r--src/core/hle/service/glue/manager.h63
-rw-r--r--src/core/hle/service/service.cpp4
19 files changed, 730 insertions, 97 deletions
diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt
index cdb3bf6ab..d65659b44 100644
--- a/src/core/CMakeLists.txt
+++ b/src/core/CMakeLists.txt
@@ -209,8 +209,6 @@ add_library(core STATIC
209 hle/service/apm/apm.h 209 hle/service/apm/apm.h
210 hle/service/apm/interface.cpp 210 hle/service/apm/interface.cpp
211 hle/service/apm/interface.h 211 hle/service/apm/interface.h
212 hle/service/arp/arp.cpp
213 hle/service/arp/arp.h
214 hle/service/audio/audctl.cpp 212 hle/service/audio/audctl.cpp
215 hle/service/audio/audctl.h 213 hle/service/audio/audctl.h
216 hle/service/audio/auddbg.cpp 214 hle/service/audio/auddbg.cpp
@@ -276,6 +274,15 @@ add_library(core STATIC
276 hle/service/friend/friend.h 274 hle/service/friend/friend.h
277 hle/service/friend/interface.cpp 275 hle/service/friend/interface.cpp
278 hle/service/friend/interface.h 276 hle/service/friend/interface.h
277 hle/service/glue/arp.cpp
278 hle/service/glue/arp.h
279 hle/service/glue/bgtc.cpp
280 hle/service/glue/bgtc.h
281 hle/service/glue/errors.h
282 hle/service/glue/glue.cpp
283 hle/service/glue/glue.h
284 hle/service/glue/manager.cpp
285 hle/service/glue/manager.h
279 hle/service/grc/grc.cpp 286 hle/service/grc/grc.cpp
280 hle/service/grc/grc.h 287 hle/service/grc/grc.h
281 hle/service/hid/hid.cpp 288 hle/service/hid/hid.cpp
diff --git a/src/core/core.cpp b/src/core/core.cpp
index c00dfd33c..df26eb109 100644
--- a/src/core/core.cpp
+++ b/src/core/core.cpp
@@ -25,6 +25,7 @@
25#include "core/hle/kernel/scheduler.h" 25#include "core/hle/kernel/scheduler.h"
26#include "core/hle/kernel/thread.h" 26#include "core/hle/kernel/thread.h"
27#include "core/hle/service/am/applets/applets.h" 27#include "core/hle/service/am/applets/applets.h"
28#include "core/hle/service/glue/manager.h"
28#include "core/hle/service/service.h" 29#include "core/hle/service/service.h"
29#include "core/hle/service/sm/sm.h" 30#include "core/hle/service/sm/sm.h"
30#include "core/loader/loader.h" 31#include "core/loader/loader.h"
@@ -33,12 +34,37 @@
33#include "core/settings.h" 34#include "core/settings.h"
34#include "core/telemetry_session.h" 35#include "core/telemetry_session.h"
35#include "file_sys/cheat_engine.h" 36#include "file_sys/cheat_engine.h"
37#include "file_sys/patch_manager.h"
36#include "video_core/debug_utils/debug_utils.h" 38#include "video_core/debug_utils/debug_utils.h"
37#include "video_core/renderer_base.h" 39#include "video_core/renderer_base.h"
38#include "video_core/video_core.h" 40#include "video_core/video_core.h"
39 41
40namespace Core { 42namespace Core {
41 43
44namespace {
45
46FileSys::StorageId GetStorageIdForFrontendSlot(
47 std::optional<FileSys::ContentProviderUnionSlot> slot) {
48 if (!slot.has_value()) {
49 return FileSys::StorageId::None;
50 }
51
52 switch (*slot) {
53 case FileSys::ContentProviderUnionSlot::UserNAND:
54 return FileSys::StorageId::NandUser;
55 case FileSys::ContentProviderUnionSlot::SysNAND:
56 return FileSys::StorageId::NandSystem;
57 case FileSys::ContentProviderUnionSlot::SDMC:
58 return FileSys::StorageId::SdCard;
59 case FileSys::ContentProviderUnionSlot::FrontendManual:
60 return FileSys::StorageId::Host;
61 default:
62 return FileSys::StorageId::None;
63 }
64}
65
66} // Anonymous namespace
67
42/*static*/ System System::s_instance; 68/*static*/ System System::s_instance;
43 69
44FileSys::VirtualFile GetGameFileFromPath(const FileSys::VirtualFilesystem& vfs, 70FileSys::VirtualFile GetGameFileFromPath(const FileSys::VirtualFilesystem& vfs,
@@ -110,6 +136,9 @@ struct System::Impl {
110 /// Create default implementations of applets if one is not provided. 136 /// Create default implementations of applets if one is not provided.
111 applet_manager.SetDefaultAppletsIfMissing(); 137 applet_manager.SetDefaultAppletsIfMissing();
112 138
139 /// Reset all glue registrations
140 arp_manager.ResetAll();
141
113 telemetry_session = std::make_unique<Core::TelemetrySession>(); 142 telemetry_session = std::make_unique<Core::TelemetrySession>();
114 service_manager = std::make_shared<Service::SM::ServiceManager>(); 143 service_manager = std::make_shared<Service::SM::ServiceManager>();
115 144
@@ -161,6 +190,7 @@ struct System::Impl {
161 return static_cast<ResultStatus>(static_cast<u32>(ResultStatus::ErrorLoader) + 190 return static_cast<ResultStatus>(static_cast<u32>(ResultStatus::ErrorLoader) +
162 static_cast<u32>(load_result)); 191 static_cast<u32>(load_result));
163 } 192 }
193 AddGlueRegistrationForProcess(*app_loader, *main_process);
164 kernel.MakeCurrentProcess(main_process.get()); 194 kernel.MakeCurrentProcess(main_process.get());
165 195
166 // Main process has been loaded and been made current. 196 // Main process has been loaded and been made current.
@@ -219,6 +249,31 @@ struct System::Impl {
219 return app_loader->ReadTitle(out); 249 return app_loader->ReadTitle(out);
220 } 250 }
221 251
252 void AddGlueRegistrationForProcess(Loader::AppLoader& loader, Kernel::Process& process) {
253 std::vector<u8> nacp_data;
254 FileSys::NACP nacp;
255 if (loader.ReadControlData(nacp) == Loader::ResultStatus::Success) {
256 nacp_data = nacp.GetRawBytes();
257 } else {
258 nacp_data.resize(sizeof(FileSys::RawNACP));
259 }
260
261 Service::Glue::ApplicationLaunchProperty launch{};
262 launch.title_id = process.GetTitleID();
263
264 FileSys::PatchManager pm{launch.title_id};
265 launch.version = pm.GetGameVersion().value_or(0);
266
267 // TODO(DarkLordZach): When FSController/Game Card Support is added, if
268 // current_process_game_card use correct StorageId
269 launch.base_game_storage_id = GetStorageIdForFrontendSlot(content_provider->GetSlotForEntry(
270 launch.title_id, FileSys::ContentRecordType::Program));
271 launch.update_storage_id = GetStorageIdForFrontendSlot(content_provider->GetSlotForEntry(
272 FileSys::GetUpdateTitleID(launch.title_id), FileSys::ContentRecordType::Program));
273
274 arp_manager.Register(launch.title_id, launch, std::move(nacp_data));
275 }
276
222 void SetStatus(ResultStatus new_status, const char* details = nullptr) { 277 void SetStatus(ResultStatus new_status, const char* details = nullptr) {
223 status = new_status; 278 status = new_status;
224 if (details) { 279 if (details) {
@@ -249,6 +304,9 @@ struct System::Impl {
249 /// Frontend applets 304 /// Frontend applets
250 Service::AM::Applets::AppletManager applet_manager; 305 Service::AM::Applets::AppletManager applet_manager;
251 306
307 /// Glue services
308 Service::Glue::ARPManager arp_manager;
309
252 /// Service manager 310 /// Service manager
253 std::shared_ptr<Service::SM::ServiceManager> service_manager; 311 std::shared_ptr<Service::SM::ServiceManager> service_manager;
254 312
@@ -500,6 +558,14 @@ const Reporter& System::GetReporter() const {
500 return impl->reporter; 558 return impl->reporter;
501} 559}
502 560
561Service::Glue::ARPManager& System::GetARPManager() {
562 return impl->arp_manager;
563}
564
565const Service::Glue::ARPManager& System::GetARPManager() const {
566 return impl->arp_manager;
567}
568
503System::ResultStatus System::Init(Frontend::EmuWindow& emu_window) { 569System::ResultStatus System::Init(Frontend::EmuWindow& emu_window) {
504 return impl->Init(*this, emu_window); 570 return impl->Init(*this, emu_window);
505} 571}
diff --git a/src/core/core.h b/src/core/core.h
index 226ef4630..70adb7af9 100644
--- a/src/core/core.h
+++ b/src/core/core.h
@@ -43,6 +43,10 @@ struct AppletFrontendSet;
43class AppletManager; 43class AppletManager;
44} // namespace AM::Applets 44} // namespace AM::Applets
45 45
46namespace Glue {
47class ARPManager;
48}
49
46namespace SM { 50namespace SM {
47class ServiceManager; 51class ServiceManager;
48} // namespace SM 52} // namespace SM
@@ -288,6 +292,10 @@ public:
288 292
289 const Reporter& GetReporter() const; 293 const Reporter& GetReporter() const;
290 294
295 Service::Glue::ARPManager& GetARPManager();
296
297 const Service::Glue::ARPManager& GetARPManager() const;
298
291private: 299private:
292 System(); 300 System();
293 301
diff --git a/src/core/file_sys/patch_manager.cpp b/src/core/file_sys/patch_manager.cpp
index da823c37b..a8f80e2c6 100644
--- a/src/core/file_sys/patch_manager.cpp
+++ b/src/core/file_sys/patch_manager.cpp
@@ -493,6 +493,16 @@ std::map<std::string, std::string, std::less<>> PatchManager::GetPatchVersionNam
493 return out; 493 return out;
494} 494}
495 495
496std::optional<u32> PatchManager::GetGameVersion() const {
497 const auto& installed = Core::System::GetInstance().GetContentProvider();
498 const auto update_tid = GetUpdateTitleID(title_id);
499 if (installed.HasEntry(update_tid, ContentRecordType::Program)) {
500 return installed.GetEntryVersion(update_tid);
501 }
502
503 return installed.GetEntryVersion(title_id);
504}
505
496std::pair<std::unique_ptr<NACP>, VirtualFile> PatchManager::GetControlMetadata() const { 506std::pair<std::unique_ptr<NACP>, VirtualFile> PatchManager::GetControlMetadata() const {
497 const auto& installed = Core::System::GetInstance().GetContentProvider(); 507 const auto& installed = Core::System::GetInstance().GetContentProvider();
498 508
diff --git a/src/core/file_sys/patch_manager.h b/src/core/file_sys/patch_manager.h
index 769f8c6f0..a363c6577 100644
--- a/src/core/file_sys/patch_manager.h
+++ b/src/core/file_sys/patch_manager.h
@@ -66,8 +66,13 @@ public:
66 std::map<std::string, std::string, std::less<>> GetPatchVersionNames( 66 std::map<std::string, std::string, std::less<>> GetPatchVersionNames(
67 VirtualFile update_raw = nullptr) const; 67 VirtualFile update_raw = nullptr) const;
68 68
69 // Given title_id of the program, attempts to get the control data of the update and parse it, 69 // If the game update exists, returns the u32 version field in its Meta-type NCA. If that fails,
70 // falling back to the base control data. 70 // it will fallback to the Meta-type NCA of the base game. If that fails, the result will be
71 // std::nullopt
72 std::optional<u32> GetGameVersion() const;
73
74 // Given title_id of the program, attempts to get the control data of the update and parse
75 // it, falling back to the base control data.
71 std::pair<std::unique_ptr<NACP>, VirtualFile> GetControlMetadata() const; 76 std::pair<std::unique_ptr<NACP>, VirtualFile> GetControlMetadata() const;
72 77
73 // Version of GetControlMetadata that takes an arbitrary NCA 78 // Version of GetControlMetadata that takes an arbitrary NCA
diff --git a/src/core/file_sys/registered_cache.cpp b/src/core/file_sys/registered_cache.cpp
index 58917e094..4608490e0 100644
--- a/src/core/file_sys/registered_cache.cpp
+++ b/src/core/file_sys/registered_cache.cpp
@@ -645,6 +645,20 @@ ContentProviderUnion::ListEntriesFilterOrigin(std::optional<ContentProviderUnion
645 return out; 645 return out;
646} 646}
647 647
648std::optional<ContentProviderUnionSlot> ContentProviderUnion::GetSlotForEntry(
649 u64 title_id, ContentRecordType type) const {
650 const auto iter =
651 std::find_if(providers.begin(), providers.end(), [title_id, type](const auto& provider) {
652 return provider.second != nullptr && provider.second->HasEntry(title_id, type);
653 });
654
655 if (iter == providers.end()) {
656 return std::nullopt;
657 }
658
659 return iter->first;
660}
661
648ManualContentProvider::~ManualContentProvider() = default; 662ManualContentProvider::~ManualContentProvider() = default;
649 663
650void ManualContentProvider::AddEntry(TitleType title_type, ContentRecordType content_type, 664void ManualContentProvider::AddEntry(TitleType title_type, ContentRecordType content_type,
diff --git a/src/core/file_sys/registered_cache.h b/src/core/file_sys/registered_cache.h
index ec9052653..4398d63e1 100644
--- a/src/core/file_sys/registered_cache.h
+++ b/src/core/file_sys/registered_cache.h
@@ -199,6 +199,9 @@ public:
199 std::optional<TitleType> title_type = {}, std::optional<ContentRecordType> record_type = {}, 199 std::optional<TitleType> title_type = {}, std::optional<ContentRecordType> record_type = {},
200 std::optional<u64> title_id = {}) const; 200 std::optional<u64> title_id = {}) const;
201 201
202 std::optional<ContentProviderUnionSlot> GetSlotForEntry(u64 title_id,
203 ContentRecordType type) const;
204
202private: 205private:
203 std::map<ContentProviderUnionSlot, ContentProvider*> providers; 206 std::map<ContentProviderUnionSlot, ContentProvider*> providers;
204}; 207};
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 @@
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/hle/ipc_helpers.h"
9#include "core/hle/kernel/hle_ipc.h"
10#include "core/hle/service/arp/arp.h"
11#include "core/hle/service/service.h"
12#include "core/hle/service/sm/sm.h"
13
14namespace Service::ARP {
15
16class ARP_R final : public ServiceFramework<ARP_R> {
17public:
18 explicit ARP_R() : ServiceFramework{"arp:r"} {
19 // clang-format off
20 static const FunctionInfo functions[] = {
21 {0, nullptr, "GetApplicationLaunchProperty"},
22 {1, nullptr, "GetApplicationLaunchPropertyWithApplicationId"},
23 {2, nullptr, "GetApplicationControlProperty"},
24 {3, nullptr, "GetApplicationControlPropertyWithApplicationId"},
25 };
26 // clang-format on
27
28 RegisterHandlers(functions);
29 }
30};
31
32class IRegistrar final : public ServiceFramework<IRegistrar> {
33public:
34 explicit IRegistrar() : ServiceFramework{"IRegistrar"} {
35 // clang-format off
36 static const FunctionInfo functions[] = {
37 {0, nullptr, "Issue"},
38 {1, nullptr, "SetApplicationLaunchProperty"},
39 {2, nullptr, "SetApplicationControlProperty"},
40 };
41 // clang-format on
42
43 RegisterHandlers(functions);
44 }
45};
46
47class ARP_W final : public ServiceFramework<ARP_W> {
48public:
49 explicit ARP_W() : ServiceFramework{"arp:w"} {
50 // clang-format off
51 static const FunctionInfo functions[] = {
52 {0, &ARP_W::AcquireRegistrar, "AcquireRegistrar"},
53 {1, nullptr, "DeleteProperties"},
54 };
55 // clang-format on
56
57 RegisterHandlers(functions);
58 }
59
60private:
61 void AcquireRegistrar(Kernel::HLERequestContext& ctx) {
62 LOG_DEBUG(Service_ARP, "called");
63
64 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
65 rb.Push(RESULT_SUCCESS);
66 rb.PushIpcInterface<IRegistrar>();
67 }
68};
69
70void InstallInterfaces(SM::ServiceManager& sm) {
71 std::make_shared<ARP_R>()->InstallAsService(sm);
72 std::make_shared<ARP_W>()->InstallAsService(sm);
73}
74
75} // 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 @@
1// Copyright 2018 yuzu emulator team
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#pragma once
6
7namespace Service::SM {
8class ServiceManager;
9}
10
11namespace Service::ARP {
12
13/// Registers all ARP services with the specified service manager.
14void InstallInterfaces(SM::ServiceManager& sm);
15
16} // namespace Service::ARP
diff --git a/src/core/hle/service/glue/arp.cpp b/src/core/hle/service/glue/arp.cpp
new file mode 100644
index 000000000..b591ce31b
--- /dev/null
+++ b/src/core/hle/service/glue/arp.cpp
@@ -0,0 +1,297 @@
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_NOT_REGISTERED);
62 return;
63 }
64
65 const auto res = manager.GetLaunchProperty(*title_id);
66
67 if (res.Failed()) {
68 LOG_ERROR(Service_ARP, "Failed to get launch property!");
69 IPC::ResponseBuilder rb{ctx, 2};
70 rb.Push(res.Code());
71 return;
72 }
73
74 IPC::ResponseBuilder rb{ctx, 6};
75 rb.Push(RESULT_SUCCESS);
76 rb.PushRaw(*res);
77}
78
79void ARP_R::GetApplicationLaunchPropertyWithApplicationId(Kernel::HLERequestContext& ctx) {
80 IPC::RequestParser rp{ctx};
81 const auto title_id = rp.PopRaw<u64>();
82
83 LOG_DEBUG(Service_ARP, "called, title_id={:016X}", title_id);
84
85 const auto res = manager.GetLaunchProperty(title_id);
86
87 if (res.Failed()) {
88 LOG_ERROR(Service_ARP, "Failed to get launch property!");
89 IPC::ResponseBuilder rb{ctx, 2};
90 rb.Push(res.Code());
91 return;
92 }
93
94 IPC::ResponseBuilder rb{ctx, 6};
95 rb.Push(RESULT_SUCCESS);
96 rb.PushRaw(*res);
97}
98
99void ARP_R::GetApplicationControlProperty(Kernel::HLERequestContext& ctx) {
100 IPC::RequestParser rp{ctx};
101 const auto process_id = rp.PopRaw<u64>();
102
103 LOG_DEBUG(Service_ARP, "called, process_id={:016X}", process_id);
104
105 const auto title_id = GetTitleIDForProcessID(system, process_id);
106 if (!title_id.has_value()) {
107 LOG_ERROR(Service_ARP, "Failed to get title ID for process ID!");
108 IPC::ResponseBuilder rb{ctx, 2};
109 rb.Push(ERR_NOT_REGISTERED);
110 return;
111 }
112
113 const auto res = manager.GetControlProperty(*title_id);
114
115 if (res.Failed()) {
116 LOG_ERROR(Service_ARP, "Failed to get control property!");
117 IPC::ResponseBuilder rb{ctx, 2};
118 rb.Push(res.Code());
119 return;
120 }
121
122 ctx.WriteBuffer(*res);
123
124 IPC::ResponseBuilder rb{ctx, 2};
125 rb.Push(RESULT_SUCCESS);
126}
127
128void ARP_R::GetApplicationControlPropertyWithApplicationId(Kernel::HLERequestContext& ctx) {
129 IPC::RequestParser rp{ctx};
130 const auto title_id = rp.PopRaw<u64>();
131
132 LOG_DEBUG(Service_ARP, "called, title_id={:016X}", title_id);
133
134 const auto res = manager.GetControlProperty(title_id);
135
136 if (res.Failed()) {
137 LOG_ERROR(Service_ARP, "Failed to get control property!");
138 IPC::ResponseBuilder rb{ctx, 2};
139 rb.Push(res.Code());
140 return;
141 }
142
143 ctx.WriteBuffer(*res);
144
145 IPC::ResponseBuilder rb{ctx, 2};
146 rb.Push(RESULT_SUCCESS);
147}
148
149class IRegistrar final : public ServiceFramework<IRegistrar> {
150 friend class ARP_W;
151
152public:
153 explicit IRegistrar(
154 std::function<ResultCode(u64, ApplicationLaunchProperty, std::vector<u8>)> issuer)
155 : ServiceFramework{"IRegistrar"}, issue_process_id(std::move(issuer)) {
156 // clang-format off
157 static const FunctionInfo functions[] = {
158 {0, &IRegistrar::Issue, "Issue"},
159 {1, &IRegistrar::SetApplicationLaunchProperty, "SetApplicationLaunchProperty"},
160 {2, &IRegistrar::SetApplicationControlProperty, "SetApplicationControlProperty"},
161 };
162 // clang-format on
163
164 RegisterHandlers(functions);
165 }
166
167private:
168 void Issue(Kernel::HLERequestContext& ctx) {
169 IPC::RequestParser rp{ctx};
170 const auto process_id = rp.PopRaw<u64>();
171
172 LOG_DEBUG(Service_ARP, "called, process_id={:016X}", process_id);
173
174 if (process_id == 0) {
175 LOG_ERROR(Service_ARP, "Must have non-zero process ID!");
176 IPC::ResponseBuilder rb{ctx, 2};
177 rb.Push(ERR_INVALID_PROCESS_ID);
178 return;
179 }
180
181 if (issued) {
182 LOG_ERROR(Service_ARP,
183 "Attempted to issue registrar, but registrar is already issued!");
184 IPC::ResponseBuilder rb{ctx, 2};
185 rb.Push(ERR_INVALID_ACCESS);
186 return;
187 }
188
189 issue_process_id(process_id, launch, std::move(control));
190 issued = true;
191
192 IPC::ResponseBuilder rb{ctx, 2};
193 rb.Push(RESULT_SUCCESS);
194 }
195
196 void SetApplicationLaunchProperty(Kernel::HLERequestContext& ctx) {
197 LOG_DEBUG(Service_ARP, "called");
198
199 if (issued) {
200 LOG_ERROR(
201 Service_ARP,
202 "Attempted to set application launch property, but registrar is already issued!");
203 IPC::ResponseBuilder rb{ctx, 2};
204 rb.Push(ERR_INVALID_ACCESS);
205 return;
206 }
207
208 IPC::RequestParser rp{ctx};
209 launch = rp.PopRaw<ApplicationLaunchProperty>();
210
211 IPC::ResponseBuilder rb{ctx, 2};
212 rb.Push(RESULT_SUCCESS);
213 }
214
215 void SetApplicationControlProperty(Kernel::HLERequestContext& ctx) {
216 LOG_DEBUG(Service_ARP, "called");
217
218 if (issued) {
219 LOG_ERROR(
220 Service_ARP,
221 "Attempted to set application control property, but registrar is already issued!");
222 IPC::ResponseBuilder rb{ctx, 2};
223 rb.Push(ERR_INVALID_ACCESS);
224 return;
225 }
226
227 control = ctx.ReadBuffer();
228
229 IPC::ResponseBuilder rb{ctx, 2};
230 rb.Push(RESULT_SUCCESS);
231 }
232
233 std::function<ResultCode(u64, ApplicationLaunchProperty, std::vector<u8>)> issue_process_id;
234 bool issued = false;
235 ApplicationLaunchProperty launch;
236 std::vector<u8> control;
237};
238
239ARP_W::ARP_W(const Core::System& system, ARPManager& manager)
240 : ServiceFramework{"arp:w"}, system(system), manager(manager) {
241 // clang-format off
242 static const FunctionInfo functions[] = {
243 {0, &ARP_W::AcquireRegistrar, "AcquireRegistrar"},
244 {1, &ARP_W::DeleteProperties, "DeleteProperties"},
245 };
246 // clang-format on
247
248 RegisterHandlers(functions);
249}
250
251ARP_W::~ARP_W() = default;
252
253void ARP_W::AcquireRegistrar(Kernel::HLERequestContext& ctx) {
254 LOG_DEBUG(Service_ARP, "called");
255
256 registrar = std::make_shared<IRegistrar>(
257 [this](u64 process_id, ApplicationLaunchProperty launch, std::vector<u8> control) {
258 const auto res = GetTitleIDForProcessID(system, process_id);
259 if (!res.has_value()) {
260 return ERR_NOT_REGISTERED;
261 }
262
263 return manager.Register(*res, launch, std::move(control));
264 });
265
266 IPC::ResponseBuilder rb{ctx, 2, 0, 1};
267 rb.Push(RESULT_SUCCESS);
268 rb.PushIpcInterface(registrar);
269}
270
271void ARP_W::DeleteProperties(Kernel::HLERequestContext& ctx) {
272 IPC::RequestParser rp{ctx};
273 const auto process_id = rp.PopRaw<u64>();
274
275 LOG_DEBUG(Service_ARP, "called, process_id={:016X}", process_id);
276
277 if (process_id == 0) {
278 LOG_ERROR(Service_ARP, "Must have non-zero process ID!");
279 IPC::ResponseBuilder rb{ctx, 2};
280 rb.Push(ERR_INVALID_PROCESS_ID);
281 return;
282 }
283
284 const auto title_id = GetTitleIDForProcessID(system, process_id);
285
286 if (!title_id.has_value()) {
287 LOG_ERROR(Service_ARP, "No title ID for process ID!");
288 IPC::ResponseBuilder rb{ctx, 2};
289 rb.Push(ERR_NOT_REGISTERED);
290 return;
291 }
292
293 IPC::ResponseBuilder rb{ctx, 2};
294 rb.Push(manager.Unregister(*title_id));
295}
296
297} // 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/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 @@
1// Copyright 2019 yuzu emulator team
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#include "core/hle/service/glue/bgtc.h"
6
7namespace Service::Glue {
8
9BGTC_T::BGTC_T() : ServiceFramework{"bgtc:t"} {
10 // clang-format off
11 static const FunctionInfo functions[] = {
12 {1, nullptr, "NotifyTaskStarting"},
13 {2, nullptr, "NotifyTaskFinished"},
14 {3, nullptr, "GetTriggerEvent"},
15 {4, nullptr, "IsInHalfAwake"},
16 {5, nullptr, "NotifyClientName"},
17 {6, nullptr, "IsInFullAwake"},
18 {11, nullptr, "ScheduleTask"},
19 {12, nullptr, "GetScheduledTaskInterval"},
20 {13, nullptr, "UnscheduleTask"},
21 {14, nullptr, "GetScheduleEvent"},
22 {15, nullptr, "SchedulePeriodicTask"},
23 {101, nullptr, "GetOperationMode"},
24 {102, nullptr, "WillDisconnectNetworkWhenEnteringSleep"},
25 {103, nullptr, "WillStayHalfAwakeInsteadSleep"},
26 };
27 // clang-format on
28
29 RegisterHandlers(functions);
30}
31
32BGTC_T::~BGTC_T() = default;
33
34BGTC_SC::BGTC_SC() : ServiceFramework{"bgtc:sc"} {
35 // clang-format off
36 static const FunctionInfo functions[] = {
37 {1, nullptr, "GetState"},
38 {2, nullptr, "GetStateChangedEvent"},
39 {3, nullptr, "NotifyEnteringHalfAwake"},
40 {4, nullptr, "NotifyLeavingHalfAwake"},
41 {5, nullptr, "SetIsUsingSleepUnsupportedDevices"},
42 };
43 // clang-format on
44
45 RegisterHandlers(functions);
46}
47
48BGTC_SC::~BGTC_SC() = default;
49
50} // 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 @@
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 BGTC_T final : public ServiceFramework<BGTC_T> {
12public:
13 BGTC_T();
14 ~BGTC_T() override;
15};
16
17class BGTC_SC final : public ServiceFramework<BGTC_SC> {
18public:
19 BGTC_SC();
20 ~BGTC_SC() override;
21};
22
23} // namespace Service::Glue
diff --git a/src/core/hle/service/glue/errors.h b/src/core/hle/service/glue/errors.h
new file mode 100644
index 000000000..c2874c585
--- /dev/null
+++ b/src/core/hle/service/glue/errors.h
@@ -0,0 +1,16 @@
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/result.h"
8
9namespace Service::Glue {
10
11constexpr ResultCode ERR_INVALID_RESOURCE{ErrorModule::ARP, 0x1E};
12constexpr ResultCode ERR_INVALID_PROCESS_ID{ErrorModule::ARP, 0x1F};
13constexpr ResultCode ERR_INVALID_ACCESS{ErrorModule::ARP, 0x2A};
14constexpr ResultCode ERR_NOT_REGISTERED{ErrorModule::ARP, 0x66};
15
16} // 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 @@
1// Copyright 2019 yuzu emulator team
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#include <memory>
6#include "core/core.h"
7#include "core/hle/service/glue/arp.h"
8#include "core/hle/service/glue/bgtc.h"
9#include "core/hle/service/glue/glue.h"
10
11namespace Service::Glue {
12
13void InstallInterfaces(Core::System& system) {
14 // ARP
15 std::make_shared<ARP_R>(system, system.GetARPManager())
16 ->InstallAsService(system.ServiceManager());
17 std::make_shared<ARP_W>(system, system.GetARPManager())
18 ->InstallAsService(system.ServiceManager());
19
20 // BackGround Task Controller
21 std::make_shared<BGTC_T>()->InstallAsService(system.ServiceManager());
22 std::make_shared<BGTC_SC>()->InstallAsService(system.ServiceManager());
23}
24
25} // 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 @@
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
7namespace Core {
8class System;
9} // namespace Core
10
11namespace Service::Glue {
12
13/// Registers all Glue services with the specified service manager.
14void InstallInterfaces(Core::System& system);
15
16} // namespace Service::Glue
diff --git a/src/core/hle/service/glue/manager.cpp b/src/core/hle/service/glue/manager.cpp
new file mode 100644
index 000000000..6da52d2d6
--- /dev/null
+++ b/src/core/hle/service/glue/manager.cpp
@@ -0,0 +1,78 @@
1// Copyright 2019 yuzu emulator team
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#include "core/hle/service/glue/errors.h"
6#include "core/hle/service/glue/manager.h"
7
8namespace Service::Glue {
9
10struct ARPManager::MapEntry {
11 ApplicationLaunchProperty launch;
12 std::vector<u8> control;
13};
14
15ARPManager::ARPManager() = default;
16
17ARPManager::~ARPManager() = default;
18
19ResultVal<ApplicationLaunchProperty> ARPManager::GetLaunchProperty(u64 title_id) const {
20 if (title_id == 0) {
21 return ERR_INVALID_PROCESS_ID;
22 }
23
24 const auto iter = entries.find(title_id);
25 if (iter == entries.end()) {
26 return ERR_NOT_REGISTERED;
27 }
28
29 return MakeResult<ApplicationLaunchProperty>(iter->second.launch);
30}
31
32ResultVal<std::vector<u8>> ARPManager::GetControlProperty(u64 title_id) const {
33 if (title_id == 0) {
34 return ERR_INVALID_PROCESS_ID;
35 }
36
37 const auto iter = entries.find(title_id);
38 if (iter == entries.end()) {
39 return ERR_NOT_REGISTERED;
40 }
41
42 return MakeResult<std::vector<u8>>(iter->second.control);
43}
44
45ResultCode ARPManager::Register(u64 title_id, ApplicationLaunchProperty launch,
46 std::vector<u8> control) {
47 if (title_id == 0) {
48 return ERR_INVALID_PROCESS_ID;
49 }
50
51 const auto iter = entries.find(title_id);
52 if (iter != entries.end()) {
53 return ERR_INVALID_ACCESS;
54 }
55
56 entries.insert_or_assign(title_id, MapEntry{launch, std::move(control)});
57 return RESULT_SUCCESS;
58}
59
60ResultCode ARPManager::Unregister(u64 title_id) {
61 if (title_id == 0) {
62 return ERR_INVALID_PROCESS_ID;
63 }
64
65 const auto iter = entries.find(title_id);
66 if (iter == entries.end()) {
67 return ERR_NOT_REGISTERED;
68 }
69
70 entries.erase(iter);
71 return RESULT_SUCCESS;
72}
73
74void ARPManager::ResetAll() {
75 entries.clear();
76}
77
78} // 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..a7f5ce3ee
--- /dev/null
+++ b/src/core/hle/service/glue/manager.h
@@ -0,0 +1,63 @@
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 <map>
8#include <vector>
9#include "common/common_types.h"
10#include "core/file_sys/control_metadata.h"
11#include "core/file_sys/romfs_factory.h"
12#include "core/hle/result.h"
13
14namespace Service::Glue {
15
16struct ApplicationLaunchProperty {
17 u64 title_id;
18 u32 version;
19 FileSys::StorageId base_game_storage_id;
20 FileSys::StorageId update_storage_id;
21 u8 program_index;
22 u8 reserved;
23};
24static_assert(sizeof(ApplicationLaunchProperty) == 0x10,
25 "ApplicationLaunchProperty has incorrect size.");
26
27// A class to manage state related to the arp:w and arp:r services, specifically the registration
28// and unregistration of launch and control properties.
29class ARPManager {
30public:
31 ARPManager();
32 ~ARPManager();
33
34 // Returns the ApplicationLaunchProperty corresponding to the provided title ID if it was
35 // previously registered, otherwise ERR_NOT_REGISTERED if it was never registered or
36 // ERR_INVALID_PROCESS_ID if the title ID is 0.
37 ResultVal<ApplicationLaunchProperty> GetLaunchProperty(u64 title_id) const;
38
39 // Returns a vector of the raw bytes of NACP data (necessarily 0x4000 in size) corresponding to
40 // the provided title ID if it was previously registered, otherwise ERR_NOT_REGISTERED if it was
41 // never registered or ERR_INVALID_PROCESS_ID if the title ID is 0.
42 ResultVal<std::vector<u8>> GetControlProperty(u64 title_id) const;
43
44 // Adds a new entry to the internal database with the provided parameters, returning
45 // ERR_INVALID_ACCESS if attempting to re-register a title ID without an intermediate Unregister
46 // step, and ERR_INVALID_PROCESS_ID if the title ID is 0.
47 ResultCode Register(u64 title_id, ApplicationLaunchProperty launch, std::vector<u8> control);
48
49 // Removes the registration for the provided title ID from the database, returning
50 // ERR_NOT_REGISTERED if it doesn't exist in the database and ERR_INVALID_PROCESS_ID if the
51 // title ID is 0.
52 ResultCode Unregister(u64 title_id);
53
54 // Removes all entries from the database, always succeeds. Should only be used when resetting
55 // system state.
56 void ResetAll();
57
58private:
59 struct MapEntry;
60 std::map<u64, MapEntry> entries;
61};
62
63} // 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);