diff options
| author | 2019-06-26 10:26:44 -0400 | |
|---|---|---|
| committer | 2019-06-26 10:26:44 -0400 | |
| commit | 4ed2774c26602d6ee1af316da5faf391d377d701 (patch) | |
| tree | a1ef0e65dfd79f8badde8dcd24014432428c51f8 /src/core | |
| parent | Merge pull request #2603 from WamWooWam/master (diff) | |
| parent | glue: Correct missing bytes in ApplicationLaunchParameter (diff) | |
| download | yuzu-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.txt | 11 | ||||
| -rw-r--r-- | src/core/core.cpp | 66 | ||||
| -rw-r--r-- | src/core/core.h | 8 | ||||
| -rw-r--r-- | src/core/file_sys/patch_manager.cpp | 10 | ||||
| -rw-r--r-- | src/core/file_sys/patch_manager.h | 9 | ||||
| -rw-r--r-- | src/core/file_sys/registered_cache.cpp | 14 | ||||
| -rw-r--r-- | src/core/file_sys/registered_cache.h | 3 | ||||
| -rw-r--r-- | src/core/hle/service/arp/arp.cpp | 75 | ||||
| -rw-r--r-- | src/core/hle/service/arp/arp.h | 16 | ||||
| -rw-r--r-- | src/core/hle/service/glue/arp.cpp | 297 | ||||
| -rw-r--r-- | src/core/hle/service/glue/arp.h | 43 | ||||
| -rw-r--r-- | src/core/hle/service/glue/bgtc.cpp | 50 | ||||
| -rw-r--r-- | src/core/hle/service/glue/bgtc.h | 23 | ||||
| -rw-r--r-- | src/core/hle/service/glue/errors.h | 16 | ||||
| -rw-r--r-- | src/core/hle/service/glue/glue.cpp | 25 | ||||
| -rw-r--r-- | src/core/hle/service/glue/glue.h | 16 | ||||
| -rw-r--r-- | src/core/hle/service/glue/manager.cpp | 78 | ||||
| -rw-r--r-- | src/core/hle/service/glue/manager.h | 63 | ||||
| -rw-r--r-- | src/core/hle/service/service.cpp | 4 |
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 | ||
| 40 | namespace Core { | 42 | namespace Core { |
| 41 | 43 | ||
| 44 | namespace { | ||
| 45 | |||
| 46 | FileSys::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 | ||
| 44 | FileSys::VirtualFile GetGameFileFromPath(const FileSys::VirtualFilesystem& vfs, | 70 | FileSys::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 | ||
| 561 | Service::Glue::ARPManager& System::GetARPManager() { | ||
| 562 | return impl->arp_manager; | ||
| 563 | } | ||
| 564 | |||
| 565 | const Service::Glue::ARPManager& System::GetARPManager() const { | ||
| 566 | return impl->arp_manager; | ||
| 567 | } | ||
| 568 | |||
| 503 | System::ResultStatus System::Init(Frontend::EmuWindow& emu_window) { | 569 | System::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; | |||
| 43 | class AppletManager; | 43 | class AppletManager; |
| 44 | } // namespace AM::Applets | 44 | } // namespace AM::Applets |
| 45 | 45 | ||
| 46 | namespace Glue { | ||
| 47 | class ARPManager; | ||
| 48 | } | ||
| 49 | |||
| 46 | namespace SM { | 50 | namespace SM { |
| 47 | class ServiceManager; | 51 | class 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 | |||
| 291 | private: | 299 | private: |
| 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 | ||
| 496 | std::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 | |||
| 496 | std::pair<std::unique_ptr<NACP>, VirtualFile> PatchManager::GetControlMetadata() const { | 506 | std::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 | ||
| 648 | std::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 | |||
| 648 | ManualContentProvider::~ManualContentProvider() = default; | 662 | ManualContentProvider::~ManualContentProvider() = default; |
| 649 | 663 | ||
| 650 | void ManualContentProvider::AddEntry(TitleType title_type, ContentRecordType content_type, | 664 | void 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 | |||
| 202 | private: | 205 | private: |
| 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 | |||
| 14 | namespace Service::ARP { | ||
| 15 | |||
| 16 | class ARP_R final : public ServiceFramework<ARP_R> { | ||
| 17 | public: | ||
| 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 | |||
| 32 | class IRegistrar final : public ServiceFramework<IRegistrar> { | ||
| 33 | public: | ||
| 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 | |||
| 47 | class ARP_W final : public ServiceFramework<ARP_W> { | ||
| 48 | public: | ||
| 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 | |||
| 60 | private: | ||
| 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 | |||
| 70 | void 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 | |||
| 7 | namespace Service::SM { | ||
| 8 | class ServiceManager; | ||
| 9 | } | ||
| 10 | |||
| 11 | namespace Service::ARP { | ||
| 12 | |||
| 13 | /// Registers all ARP services with the specified service manager. | ||
| 14 | void 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 | |||
| 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_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 | |||
| 79 | void 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 | |||
| 99 | void 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 | |||
| 128 | void 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 | |||
| 149 | class IRegistrar final : public ServiceFramework<IRegistrar> { | ||
| 150 | friend class ARP_W; | ||
| 151 | |||
| 152 | public: | ||
| 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 | |||
| 167 | private: | ||
| 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 | |||
| 239 | ARP_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 | |||
| 251 | ARP_W::~ARP_W() = default; | ||
| 252 | |||
| 253 | void 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 | |||
| 271 | void 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 | |||
| 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/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 | |||
| 7 | namespace Service::Glue { | ||
| 8 | |||
| 9 | BGTC_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 | |||
| 32 | BGTC_T::~BGTC_T() = default; | ||
| 33 | |||
| 34 | BGTC_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 | |||
| 48 | BGTC_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 | |||
| 9 | namespace Service::Glue { | ||
| 10 | |||
| 11 | class BGTC_T final : public ServiceFramework<BGTC_T> { | ||
| 12 | public: | ||
| 13 | BGTC_T(); | ||
| 14 | ~BGTC_T() override; | ||
| 15 | }; | ||
| 16 | |||
| 17 | class BGTC_SC final : public ServiceFramework<BGTC_SC> { | ||
| 18 | public: | ||
| 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 | |||
| 9 | namespace Service::Glue { | ||
| 10 | |||
| 11 | constexpr ResultCode ERR_INVALID_RESOURCE{ErrorModule::ARP, 0x1E}; | ||
| 12 | constexpr ResultCode ERR_INVALID_PROCESS_ID{ErrorModule::ARP, 0x1F}; | ||
| 13 | constexpr ResultCode ERR_INVALID_ACCESS{ErrorModule::ARP, 0x2A}; | ||
| 14 | constexpr 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 | |||
| 11 | namespace Service::Glue { | ||
| 12 | |||
| 13 | void 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 | |||
| 7 | namespace Core { | ||
| 8 | class System; | ||
| 9 | } // namespace Core | ||
| 10 | |||
| 11 | namespace Service::Glue { | ||
| 12 | |||
| 13 | /// Registers all Glue services with the specified service manager. | ||
| 14 | void 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 | |||
| 8 | namespace Service::Glue { | ||
| 9 | |||
| 10 | struct ARPManager::MapEntry { | ||
| 11 | ApplicationLaunchProperty launch; | ||
| 12 | std::vector<u8> control; | ||
| 13 | }; | ||
| 14 | |||
| 15 | ARPManager::ARPManager() = default; | ||
| 16 | |||
| 17 | ARPManager::~ARPManager() = default; | ||
| 18 | |||
| 19 | ResultVal<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 | |||
| 32 | ResultVal<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 | |||
| 45 | ResultCode 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 | |||
| 60 | ResultCode 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 | |||
| 74 | void 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 | |||
| 14 | namespace Service::Glue { | ||
| 15 | |||
| 16 | struct 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 | }; | ||
| 24 | static_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. | ||
| 29 | class ARPManager { | ||
| 30 | public: | ||
| 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 | |||
| 58 | private: | ||
| 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); |