diff options
| author | 2024-02-17 13:46:18 -0500 | |
|---|---|---|
| committer | 2024-02-18 10:32:21 -0500 | |
| commit | 2eded86b4b525fad4221115b716700d63ad8438f (patch) | |
| tree | 284865b9809b7787a4aeb0f0ad774419ddca79f0 /src | |
| parent | ns: rewrite IReadOnlyApplicationRecordInterface (diff) | |
| download | yuzu-2eded86b4b525fad4221115b716700d63ad8438f.tar.gz yuzu-2eded86b4b525fad4221115b716700d63ad8438f.tar.xz yuzu-2eded86b4b525fad4221115b716700d63ad8438f.zip | |
ns: rewrite IReadOnlyApplicationControlDataInterface
Diffstat (limited to 'src')
| -rw-r--r-- | src/core/CMakeLists.txt | 2 | ||||
| -rw-r--r-- | src/core/hle/service/ns/ns.cpp | 46 | ||||
| -rw-r--r-- | src/core/hle/service/ns/ns.h | 10 | ||||
| -rw-r--r-- | src/core/hle/service/ns/ns_types.h | 6 | ||||
| -rw-r--r-- | src/core/hle/service/ns/read_only_application_control_data_interface.cpp | 122 | ||||
| -rw-r--r-- | src/core/hle/service/ns/read_only_application_control_data_interface.h | 29 |
6 files changed, 160 insertions, 55 deletions
diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index ab8b1c6c9..bc515949c 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt | |||
| @@ -765,6 +765,8 @@ add_library(core STATIC | |||
| 765 | hle/service/ns/pdm_qry.h | 765 | hle/service/ns/pdm_qry.h |
| 766 | hle/service/ns/platform_service_manager.cpp | 766 | hle/service/ns/platform_service_manager.cpp |
| 767 | hle/service/ns/platform_service_manager.h | 767 | hle/service/ns/platform_service_manager.h |
| 768 | hle/service/ns/read_only_application_control_data_interface.cpp | ||
| 769 | hle/service/ns/read_only_application_control_data_interface.h | ||
| 768 | hle/service/ns/read_only_application_record_interface.cpp | 770 | hle/service/ns/read_only_application_record_interface.cpp |
| 769 | hle/service/ns/read_only_application_record_interface.h | 771 | hle/service/ns/read_only_application_record_interface.h |
| 770 | hle/service/nvdrv/core/container.cpp | 772 | hle/service/nvdrv/core/container.cpp |
diff --git a/src/core/hle/service/ns/ns.cpp b/src/core/hle/service/ns/ns.cpp index 5dc15dad5..b5ad27dd8 100644 --- a/src/core/hle/service/ns/ns.cpp +++ b/src/core/hle/service/ns/ns.cpp | |||
| @@ -24,6 +24,7 @@ | |||
| 24 | #include "core/hle/service/ns/ns_results.h" | 24 | #include "core/hle/service/ns/ns_results.h" |
| 25 | #include "core/hle/service/ns/pdm_qry.h" | 25 | #include "core/hle/service/ns/pdm_qry.h" |
| 26 | #include "core/hle/service/ns/platform_service_manager.h" | 26 | #include "core/hle/service/ns/platform_service_manager.h" |
| 27 | #include "core/hle/service/ns/read_only_application_control_data_interface.h" | ||
| 27 | #include "core/hle/service/ns/read_only_application_record_interface.h" | 28 | #include "core/hle/service/ns/read_only_application_record_interface.h" |
| 28 | #include "core/hle/service/server_manager.h" | 29 | #include "core/hle/service/server_manager.h" |
| 29 | #include "core/hle/service/set/settings_server.h" | 30 | #include "core/hle/service/set/settings_server.h" |
| @@ -469,51 +470,6 @@ Result IApplicationManagerInterface::ConvertApplicationLanguageToLanguageCode( | |||
| 469 | return ResultSuccess; | 470 | return ResultSuccess; |
| 470 | } | 471 | } |
| 471 | 472 | ||
| 472 | IReadOnlyApplicationControlDataInterface::IReadOnlyApplicationControlDataInterface( | ||
| 473 | Core::System& system_) | ||
| 474 | : ServiceFramework{system_, "IReadOnlyApplicationControlDataInterface"} { | ||
| 475 | // clang-format off | ||
| 476 | static const FunctionInfo functions[] = { | ||
| 477 | {0, &IReadOnlyApplicationControlDataInterface::GetApplicationControlData, "GetApplicationControlData"}, | ||
| 478 | {1, nullptr, "GetApplicationDesiredLanguage"}, | ||
| 479 | {2, nullptr, "ConvertApplicationLanguageToLanguageCode"}, | ||
| 480 | {3, nullptr, "ConvertLanguageCodeToApplicationLanguage"}, | ||
| 481 | {4, nullptr, "SelectApplicationDesiredLanguage"}, | ||
| 482 | }; | ||
| 483 | // clang-format on | ||
| 484 | |||
| 485 | RegisterHandlers(functions); | ||
| 486 | } | ||
| 487 | |||
| 488 | IReadOnlyApplicationControlDataInterface::~IReadOnlyApplicationControlDataInterface() = default; | ||
| 489 | |||
| 490 | void IReadOnlyApplicationControlDataInterface::GetApplicationControlData(HLERequestContext& ctx) { | ||
| 491 | enum class ApplicationControlSource : u8 { | ||
| 492 | CacheOnly, | ||
| 493 | Storage, | ||
| 494 | StorageOnly, | ||
| 495 | }; | ||
| 496 | |||
| 497 | struct RequestParameters { | ||
| 498 | ApplicationControlSource source; | ||
| 499 | u64 application_id; | ||
| 500 | }; | ||
| 501 | static_assert(sizeof(RequestParameters) == 0x10, "RequestParameters has incorrect size."); | ||
| 502 | |||
| 503 | IPC::RequestParser rp{ctx}; | ||
| 504 | std::vector<u8> nacp_data{}; | ||
| 505 | const auto parameters{rp.PopRaw<RequestParameters>()}; | ||
| 506 | const auto result = | ||
| 507 | system.GetARPManager().GetControlProperty(&nacp_data, parameters.application_id); | ||
| 508 | |||
| 509 | if (result == ResultSuccess) { | ||
| 510 | ctx.WriteBuffer(nacp_data.data(), nacp_data.size()); | ||
| 511 | } | ||
| 512 | |||
| 513 | IPC::ResponseBuilder rb{ctx, 2}; | ||
| 514 | rb.Push(result); | ||
| 515 | } | ||
| 516 | |||
| 517 | NS::NS(const char* name, Core::System& system_) : ServiceFramework{system_, name} { | 473 | NS::NS(const char* name, Core::System& system_) : ServiceFramework{system_, name} { |
| 518 | // clang-format off | 474 | // clang-format off |
| 519 | static const FunctionInfo functions[] = { | 475 | static const FunctionInfo functions[] = { |
diff --git a/src/core/hle/service/ns/ns.h b/src/core/hle/service/ns/ns.h index 20a2243ff..39a6b6f21 100644 --- a/src/core/hle/service/ns/ns.h +++ b/src/core/hle/service/ns/ns.h | |||
| @@ -32,16 +32,6 @@ private: | |||
| 32 | void ConvertApplicationLanguageToLanguageCode(HLERequestContext& ctx); | 32 | void ConvertApplicationLanguageToLanguageCode(HLERequestContext& ctx); |
| 33 | }; | 33 | }; |
| 34 | 34 | ||
| 35 | class IReadOnlyApplicationControlDataInterface final | ||
| 36 | : public ServiceFramework<IReadOnlyApplicationControlDataInterface> { | ||
| 37 | public: | ||
| 38 | explicit IReadOnlyApplicationControlDataInterface(Core::System& system_); | ||
| 39 | ~IReadOnlyApplicationControlDataInterface() override; | ||
| 40 | |||
| 41 | private: | ||
| 42 | void GetApplicationControlData(HLERequestContext& ctx); | ||
| 43 | }; | ||
| 44 | |||
| 45 | class NS final : public ServiceFramework<NS> { | 35 | class NS final : public ServiceFramework<NS> { |
| 46 | public: | 36 | public: |
| 47 | explicit NS(const char* name, Core::System& system_); | 37 | explicit NS(const char* name, Core::System& system_); |
diff --git a/src/core/hle/service/ns/ns_types.h b/src/core/hle/service/ns/ns_types.h index d7c16eac0..fa2aad3d9 100644 --- a/src/core/hle/service/ns/ns_types.h +++ b/src/core/hle/service/ns/ns_types.h | |||
| @@ -16,6 +16,12 @@ enum class ApplicationRecordType : u8 { | |||
| 16 | GameCard = 0x10, | 16 | GameCard = 0x10, |
| 17 | }; | 17 | }; |
| 18 | 18 | ||
| 19 | enum class ApplicationControlSource : u8 { | ||
| 20 | CacheOnly = 0, | ||
| 21 | Storage = 1, | ||
| 22 | StorageOnly = 2, | ||
| 23 | }; | ||
| 24 | |||
| 19 | struct ApplicationRecord { | 25 | struct ApplicationRecord { |
| 20 | u64 application_id; | 26 | u64 application_id; |
| 21 | ApplicationRecordType type; | 27 | ApplicationRecordType type; |
diff --git a/src/core/hle/service/ns/read_only_application_control_data_interface.cpp b/src/core/hle/service/ns/read_only_application_control_data_interface.cpp new file mode 100644 index 000000000..6b4751596 --- /dev/null +++ b/src/core/hle/service/ns/read_only_application_control_data_interface.cpp | |||
| @@ -0,0 +1,122 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 3 | |||
| 4 | #include "common/settings.h" | ||
| 5 | #include "core/file_sys/control_metadata.h" | ||
| 6 | #include "core/file_sys/patch_manager.h" | ||
| 7 | #include "core/file_sys/vfs/vfs.h" | ||
| 8 | #include "core/hle/service/cmif_serialization.h" | ||
| 9 | #include "core/hle/service/ns/language.h" | ||
| 10 | #include "core/hle/service/ns/ns_results.h" | ||
| 11 | #include "core/hle/service/ns/read_only_application_control_data_interface.h" | ||
| 12 | #include "core/hle/service/set/settings_server.h" | ||
| 13 | |||
| 14 | namespace Service::NS { | ||
| 15 | |||
| 16 | IReadOnlyApplicationControlDataInterface::IReadOnlyApplicationControlDataInterface( | ||
| 17 | Core::System& system_) | ||
| 18 | : ServiceFramework{system_, "IReadOnlyApplicationControlDataInterface"} { | ||
| 19 | // clang-format off | ||
| 20 | static const FunctionInfo functions[] = { | ||
| 21 | {0, D<&IReadOnlyApplicationControlDataInterface::GetApplicationControlData>, "GetApplicationControlData"}, | ||
| 22 | {1, D<&IReadOnlyApplicationControlDataInterface::GetApplicationDesiredLanguage>, "GetApplicationDesiredLanguage"}, | ||
| 23 | {2, D<&IReadOnlyApplicationControlDataInterface::ConvertApplicationLanguageToLanguageCode>, "ConvertApplicationLanguageToLanguageCode"}, | ||
| 24 | {3, nullptr, "ConvertLanguageCodeToApplicationLanguage"}, | ||
| 25 | {4, nullptr, "SelectApplicationDesiredLanguage"}, | ||
| 26 | }; | ||
| 27 | // clang-format on | ||
| 28 | |||
| 29 | RegisterHandlers(functions); | ||
| 30 | } | ||
| 31 | |||
| 32 | IReadOnlyApplicationControlDataInterface::~IReadOnlyApplicationControlDataInterface() = default; | ||
| 33 | |||
| 34 | Result IReadOnlyApplicationControlDataInterface::GetApplicationControlData( | ||
| 35 | OutBuffer<BufferAttr_HipcMapAlias> out_buffer, Out<u32> out_actual_size, | ||
| 36 | ApplicationControlSource application_control_source, u64 application_id) { | ||
| 37 | LOG_INFO(Service_NS, "called with control_source={}, application_id={:016X}", | ||
| 38 | application_control_source, application_id); | ||
| 39 | |||
| 40 | const FileSys::PatchManager pm{application_id, system.GetFileSystemController(), | ||
| 41 | system.GetContentProvider()}; | ||
| 42 | const auto control = pm.GetControlMetadata(); | ||
| 43 | const auto size = out_buffer.size(); | ||
| 44 | |||
| 45 | const auto icon_size = control.second ? control.second->GetSize() : 0; | ||
| 46 | const auto total_size = 0x4000 + icon_size; | ||
| 47 | |||
| 48 | if (size < total_size) { | ||
| 49 | LOG_ERROR(Service_NS, "output buffer is too small! (actual={:016X}, expected_min=0x4000)", | ||
| 50 | size); | ||
| 51 | R_THROW(ResultUnknown); | ||
| 52 | } | ||
| 53 | |||
| 54 | if (control.first != nullptr) { | ||
| 55 | const auto bytes = control.first->GetRawBytes(); | ||
| 56 | std::memcpy(out_buffer.data(), bytes.data(), bytes.size()); | ||
| 57 | } else { | ||
| 58 | LOG_WARNING(Service_NS, "missing NACP data for application_id={:016X}, defaulting to zero", | ||
| 59 | application_id); | ||
| 60 | std::memset(out_buffer.data(), 0, 0x4000); | ||
| 61 | } | ||
| 62 | |||
| 63 | if (control.second != nullptr) { | ||
| 64 | control.second->Read(out_buffer.data() + 0x4000, icon_size); | ||
| 65 | } else { | ||
| 66 | LOG_WARNING(Service_NS, "missing icon data for application_id={:016X}", application_id); | ||
| 67 | } | ||
| 68 | |||
| 69 | *out_actual_size = static_cast<u32>(total_size); | ||
| 70 | R_SUCCEED(); | ||
| 71 | } | ||
| 72 | |||
| 73 | Result IReadOnlyApplicationControlDataInterface::GetApplicationDesiredLanguage( | ||
| 74 | Out<u8> out_desired_language, u32 supported_languages) { | ||
| 75 | LOG_INFO(Service_NS, "called with supported_languages={:08X}", supported_languages); | ||
| 76 | |||
| 77 | // Get language code from settings | ||
| 78 | const auto language_code = | ||
| 79 | Set::GetLanguageCodeFromIndex(static_cast<s32>(Settings::values.language_index.GetValue())); | ||
| 80 | |||
| 81 | // Convert to application language, get priority list | ||
| 82 | const auto application_language = ConvertToApplicationLanguage(language_code); | ||
| 83 | if (application_language == std::nullopt) { | ||
| 84 | LOG_ERROR(Service_NS, "Could not convert application language! language_code={}", | ||
| 85 | language_code); | ||
| 86 | R_THROW(Service::NS::ResultApplicationLanguageNotFound); | ||
| 87 | } | ||
| 88 | const auto priority_list = GetApplicationLanguagePriorityList(*application_language); | ||
| 89 | if (!priority_list) { | ||
| 90 | LOG_ERROR(Service_NS, | ||
| 91 | "Could not find application language priorities! application_language={}", | ||
| 92 | *application_language); | ||
| 93 | R_THROW(Service::NS::ResultApplicationLanguageNotFound); | ||
| 94 | } | ||
| 95 | |||
| 96 | // Try to find a valid language. | ||
| 97 | for (const auto lang : *priority_list) { | ||
| 98 | const auto supported_flag = GetSupportedLanguageFlag(lang); | ||
| 99 | if (supported_languages == 0 || (supported_languages & supported_flag) == supported_flag) { | ||
| 100 | *out_desired_language = static_cast<u8>(lang); | ||
| 101 | R_SUCCEED(); | ||
| 102 | } | ||
| 103 | } | ||
| 104 | |||
| 105 | LOG_ERROR(Service_NS, "Could not find a valid language! supported_languages={:08X}", | ||
| 106 | supported_languages); | ||
| 107 | R_THROW(Service::NS::ResultApplicationLanguageNotFound); | ||
| 108 | } | ||
| 109 | |||
| 110 | Result IReadOnlyApplicationControlDataInterface::ConvertApplicationLanguageToLanguageCode( | ||
| 111 | Out<u64> out_language_code, ApplicationLanguage application_language) { | ||
| 112 | const auto language_code = ConvertToLanguageCode(application_language); | ||
| 113 | if (language_code == std::nullopt) { | ||
| 114 | LOG_ERROR(Service_NS, "Language not found! application_language={}", application_language); | ||
| 115 | R_THROW(Service::NS::ResultApplicationLanguageNotFound); | ||
| 116 | } | ||
| 117 | |||
| 118 | *out_language_code = static_cast<u64>(*language_code); | ||
| 119 | R_SUCCEED(); | ||
| 120 | } | ||
| 121 | |||
| 122 | } // namespace Service::NS | ||
diff --git a/src/core/hle/service/ns/read_only_application_control_data_interface.h b/src/core/hle/service/ns/read_only_application_control_data_interface.h new file mode 100644 index 000000000..7d470c432 --- /dev/null +++ b/src/core/hle/service/ns/read_only_application_control_data_interface.h | |||
| @@ -0,0 +1,29 @@ | |||
| 1 | // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project | ||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | ||
| 3 | |||
| 4 | #pragma once | ||
| 5 | |||
| 6 | #include "core/hle/service/cmif_types.h" | ||
| 7 | #include "core/hle/service/ns/language.h" | ||
| 8 | #include "core/hle/service/ns/ns_types.h" | ||
| 9 | #include "core/hle/service/service.h" | ||
| 10 | |||
| 11 | namespace Service::NS { | ||
| 12 | |||
| 13 | class IReadOnlyApplicationControlDataInterface final | ||
| 14 | : public ServiceFramework<IReadOnlyApplicationControlDataInterface> { | ||
| 15 | public: | ||
| 16 | explicit IReadOnlyApplicationControlDataInterface(Core::System& system_); | ||
| 17 | ~IReadOnlyApplicationControlDataInterface() override; | ||
| 18 | |||
| 19 | private: | ||
| 20 | Result GetApplicationControlData(OutBuffer<BufferAttr_HipcMapAlias> out_buffer, | ||
| 21 | Out<u32> out_actual_size, | ||
| 22 | ApplicationControlSource application_control_source, | ||
| 23 | u64 application_id); | ||
| 24 | Result GetApplicationDesiredLanguage(Out<u8> out_desired_language, u32 supported_languages); | ||
| 25 | Result ConvertApplicationLanguageToLanguageCode(Out<u64> out_language_code, | ||
| 26 | ApplicationLanguage application_language); | ||
| 27 | }; | ||
| 28 | |||
| 29 | } // namespace Service::NS | ||