diff options
Diffstat (limited to 'src/core')
45 files changed, 1138 insertions, 538 deletions
diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index 93e403b26..de158eea7 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -486,8 +486,10 @@ add_library(core STATIC hle/service/am/service/system_applet_proxy.h hle/service/am/service/window_controller.cpp hle/service/am/service/window_controller.h - hle/service/aoc/aoc_u.cpp - hle/service/aoc/aoc_u.h + hle/service/aoc/addon_content_manager.cpp + hle/service/aoc/addon_content_manager.h + hle/service/aoc/purchase_event_manager.cpp + hle/service/aoc/purchase_event_manager.h hle/service/apm/apm.cpp hle/service/apm/apm.h hle/service/apm/apm_controller.cpp @@ -1049,9 +1051,12 @@ add_library(core STATIC hle/service/spl/spl_module.h hle/service/spl/spl_results.h hle/service/spl/spl_types.h + hle/service/ssl/cert_store.cpp + hle/service/ssl/cert_store.h hle/service/ssl/ssl.cpp hle/service/ssl/ssl.h hle/service/ssl/ssl_backend.h + hle/service/ssl/ssl_types.h hle/service/usb/usb.cpp hle/service/usb/usb.h hle/service/vi/application_display_service.cpp diff --git a/src/core/core.cpp b/src/core/core.cpp index 9e8936728..dc515bc82 100644 --- a/src/core/core.cpp +++ b/src/core/core.cpp @@ -425,11 +425,6 @@ struct System::Impl { room_member->SendGameInfo(game_info); } - // Workarounds: - // Activate this in Super Smash Brothers Ultimate, it only affects AMD cards using AMDVLK - Settings::values.renderer_amdvlk_depth_bias_workaround = - params.program_id == 0x1006A800016E000ULL; - status = SystemResultStatus::Success; return status; } @@ -489,9 +484,6 @@ struct System::Impl { room_member->SendGameInfo(game_info); } - // Workarounds - Settings::values.renderer_amdvlk_depth_bias_workaround = false; - LOG_DEBUG(Core, "Shutdown OK"); } diff --git a/src/core/file_sys/fssystem/fssystem_aes_xts_storage.cpp b/src/core/file_sys/fssystem/fssystem_aes_xts_storage.cpp index 022424229..efc5aa0b1 100644 --- a/src/core/file_sys/fssystem/fssystem_aes_xts_storage.cpp +++ b/src/core/file_sys/fssystem/fssystem_aes_xts_storage.cpp @@ -31,8 +31,8 @@ AesXtsStorage::AesXtsStorage(VirtualFile base, const void* key1, const void* key ASSERT(iv_size == IvSize); ASSERT(Common::IsAligned(m_block_size, AesBlockSize)); - std::memcpy(m_key.data() + 0, key1, KeySize); - std::memcpy(m_key.data() + 0x10, key2, KeySize); + std::memcpy(m_key.data() + 0, key1, KeySize / 2); + std::memcpy(m_key.data() + 0x10, key2, KeySize / 2); std::memcpy(m_iv.data(), iv, IvSize); m_cipher.emplace(m_key, Core::Crypto::Mode::XTS); diff --git a/src/core/hle/service/acc/acc.cpp b/src/core/hle/service/acc/acc.cpp index f21553644..fad111d44 100644 --- a/src/core/hle/service/acc/acc.cpp +++ b/src/core/hle/service/acc/acc.cpp @@ -25,8 +25,8 @@ #include "core/hle/service/acc/async_context.h" #include "core/hle/service/acc/errors.h" #include "core/hle/service/acc/profile_manager.h" +#include "core/hle/service/cmif_serialization.h" #include "core/hle/service/glue/glue_manager.h" -#include "core/hle/service/ipc_helpers.h" #include "core/hle/service/server_manager.h" #include "core/loader/loader.h" @@ -74,12 +74,12 @@ static void SanitizeJPEGImageSize(std::vector<u8>& image) { class IManagerForSystemService final : public ServiceFramework<IManagerForSystemService> { public: - explicit IManagerForSystemService(Core::System& system_, Common::UUID) - : ServiceFramework{system_, "IManagerForSystemService"} { + explicit IManagerForSystemService(Core::System& system_, Common::UUID uuid) + : ServiceFramework{system_, "IManagerForSystemService"}, account_id{uuid} { // clang-format off static const FunctionInfo functions[] = { - {0, &IManagerForSystemService::CheckAvailability, "CheckAvailability"}, - {1, nullptr, "GetAccountId"}, + {0, D<&IManagerForSystemService::CheckAvailability>, "CheckAvailability"}, + {1, D<&IManagerForSystemService::GetAccountId>, "GetAccountId"}, {2, nullptr, "EnsureIdTokenCacheAsync"}, {3, nullptr, "LoadIdTokenCache"}, {100, nullptr, "SetSystemProgramIdentification"}, @@ -109,11 +109,18 @@ public: } private: - void CheckAvailability(HLERequestContext& ctx) { + Result CheckAvailability() { LOG_WARNING(Service_ACC, "(STUBBED) called"); - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(ResultSuccess); + R_SUCCEED(); } + + Result GetAccountId(Out<u64> out_account_id) { + LOG_WARNING(Service_ACC, "(STUBBED) called"); + *out_account_id = account_id.Hash(); + R_SUCCEED(); + } + + Common::UUID account_id; }; // 3.0.0+ diff --git a/src/core/hle/service/acc/acc_u1.cpp b/src/core/hle/service/acc/acc_u1.cpp index 92f704c2f..eecc94387 100644 --- a/src/core/hle/service/acc/acc_u1.cpp +++ b/src/core/hle/service/acc/acc_u1.cpp @@ -23,7 +23,7 @@ ACC_U1::ACC_U1(std::shared_ptr<Module> module_, std::shared_ptr<ProfileManager> {99, nullptr, "DebugActivateOpenContextRetention"}, {100, nullptr, "GetUserRegistrationNotifier"}, {101, nullptr, "GetUserStateChangeNotifier"}, - {102, nullptr, "GetBaasAccountManagerForSystemService"}, + {102, &ACC_U1::GetBaasAccountManagerForSystemService, "GetBaasAccountManagerForSystemService"}, {103, nullptr, "GetBaasUserAvailabilityChangeNotifier"}, {104, nullptr, "GetProfileUpdateNotifier"}, {105, nullptr, "CheckNetworkServiceAvailabilityAsync"}, diff --git a/src/core/hle/service/am/am_types.h b/src/core/hle/service/am/am_types.h index 46afb3996..a14defb40 100644 --- a/src/core/hle/service/am/am_types.h +++ b/src/core/hle/service/am/am_types.h @@ -48,11 +48,6 @@ enum class SystemButtonType { CaptureButtonLongPressing, }; -enum class SysPlatformRegion : s32 { - Global = 1, - Terra = 2, -}; - struct AppletProcessLaunchReason { u8 flag; INSERT_PADDING_BYTES(3); diff --git a/src/core/hle/service/am/service/common_state_getter.cpp b/src/core/hle/service/am/service/common_state_getter.cpp index 548498e83..a32855ffa 100644 --- a/src/core/hle/service/am/service/common_state_getter.cpp +++ b/src/core/hle/service/am/service/common_state_getter.cpp @@ -260,9 +260,9 @@ Result ICommonStateGetter::GetAppletLaunchedHistory( } Result ICommonStateGetter::GetSettingsPlatformRegion( - Out<SysPlatformRegion> out_settings_platform_region) { + Out<Set::PlatformRegion> out_settings_platform_region) { LOG_INFO(Service_AM, "called"); - *out_settings_platform_region = SysPlatformRegion::Global; + *out_settings_platform_region = Set::PlatformRegion::Global; R_SUCCEED(); } diff --git a/src/core/hle/service/am/service/common_state_getter.h b/src/core/hle/service/am/service/common_state_getter.h index 5a8dca3d6..59a46fa94 100644 --- a/src/core/hle/service/am/service/common_state_getter.h +++ b/src/core/hle/service/am/service/common_state_getter.h @@ -8,6 +8,7 @@ #include "core/hle/service/cmif_types.h" #include "core/hle/service/pm/pm.h" #include "core/hle/service/service.h" +#include "core/hle/service/set/settings_types.h" namespace Kernel { class KReadableEvent; @@ -50,7 +51,7 @@ private: Result GetOperationModeSystemInfo(Out<u32> out_operation_mode_system_info); Result GetAppletLaunchedHistory(Out<s32> out_count, OutArray<AppletId, BufferAttr_HipcMapAlias> out_applet_ids); - Result GetSettingsPlatformRegion(Out<SysPlatformRegion> out_settings_platform_region); + Result GetSettingsPlatformRegion(Out<Set::PlatformRegion> out_settings_platform_region); Result SetRequestExitToLibraryAppletAtExecuteNextProgramEnabled(); void SetCpuBoostMode(HLERequestContext& ctx); diff --git a/src/core/hle/service/aoc/addon_content_manager.cpp b/src/core/hle/service/aoc/addon_content_manager.cpp new file mode 100644 index 000000000..d47f57d64 --- /dev/null +++ b/src/core/hle/service/aoc/addon_content_manager.cpp @@ -0,0 +1,223 @@ +// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include <algorithm> +#include <numeric> +#include <vector> + +#include "common/logging/log.h" +#include "common/settings.h" +#include "core/core.h" +#include "core/file_sys/common_funcs.h" +#include "core/file_sys/content_archive.h" +#include "core/file_sys/control_metadata.h" +#include "core/file_sys/nca_metadata.h" +#include "core/file_sys/patch_manager.h" +#include "core/file_sys/registered_cache.h" +#include "core/hle/kernel/k_event.h" +#include "core/hle/service/aoc/addon_content_manager.h" +#include "core/hle/service/aoc/purchase_event_manager.h" +#include "core/hle/service/cmif_serialization.h" +#include "core/hle/service/ipc_helpers.h" +#include "core/hle/service/server_manager.h" +#include "core/loader/loader.h" + +namespace Service::AOC { + +static bool CheckAOCTitleIDMatchesBase(u64 title_id, u64 base) { + return FileSys::GetBaseTitleID(title_id) == base; +} + +static std::vector<u64> AccumulateAOCTitleIDs(Core::System& system) { + std::vector<u64> add_on_content; + const auto& rcu = system.GetContentProvider(); + const auto list = + rcu.ListEntriesFilter(FileSys::TitleType::AOC, FileSys::ContentRecordType::Data); + std::transform(list.begin(), list.end(), std::back_inserter(add_on_content), + [](const FileSys::ContentProviderEntry& rce) { return rce.title_id; }); + add_on_content.erase( + std::remove_if( + add_on_content.begin(), add_on_content.end(), + [&rcu](u64 tid) { + return rcu.GetEntry(tid, FileSys::ContentRecordType::Data)->GetStatus() != + Loader::ResultStatus::Success; + }), + add_on_content.end()); + return add_on_content; +} + +IAddOnContentManager::IAddOnContentManager(Core::System& system_) + : ServiceFramework{system_, "aoc:u"}, add_on_content{AccumulateAOCTitleIDs(system)}, + service_context{system_, "aoc:u"} { + // clang-format off + static const FunctionInfo functions[] = { + {0, nullptr, "CountAddOnContentByApplicationId"}, + {1, nullptr, "ListAddOnContentByApplicationId"}, + {2, D<&IAddOnContentManager::CountAddOnContent>, "CountAddOnContent"}, + {3, D<&IAddOnContentManager::ListAddOnContent>, "ListAddOnContent"}, + {4, nullptr, "GetAddOnContentBaseIdByApplicationId"}, + {5, D<&IAddOnContentManager::GetAddOnContentBaseId>, "GetAddOnContentBaseId"}, + {6, nullptr, "PrepareAddOnContentByApplicationId"}, + {7, D<&IAddOnContentManager::PrepareAddOnContent>, "PrepareAddOnContent"}, + {8, D<&IAddOnContentManager::GetAddOnContentListChangedEvent>, "GetAddOnContentListChangedEvent"}, + {9, nullptr, "GetAddOnContentLostErrorCode"}, + {10, D<&IAddOnContentManager::GetAddOnContentListChangedEventWithProcessId>, "GetAddOnContentListChangedEventWithProcessId"}, + {11, D<&IAddOnContentManager::NotifyMountAddOnContent>, "NotifyMountAddOnContent"}, + {12, D<&IAddOnContentManager::NotifyUnmountAddOnContent>, "NotifyUnmountAddOnContent"}, + {13, nullptr, "IsAddOnContentMountedForDebug"}, + {50, D<&IAddOnContentManager::CheckAddOnContentMountStatus>, "CheckAddOnContentMountStatus"}, + {100, D<&IAddOnContentManager::CreateEcPurchasedEventManager>, "CreateEcPurchasedEventManager"}, + {101, D<&IAddOnContentManager::CreatePermanentEcPurchasedEventManager>, "CreatePermanentEcPurchasedEventManager"}, + {110, nullptr, "CreateContentsServiceManager"}, + {200, nullptr, "SetRequiredAddOnContentsOnContentsAvailabilityTransition"}, + {300, nullptr, "SetupHostAddOnContent"}, + {301, nullptr, "GetRegisteredAddOnContentPath"}, + {302, nullptr, "UpdateCachedList"}, + }; + // clang-format on + + RegisterHandlers(functions); + + aoc_change_event = service_context.CreateEvent("GetAddOnContentListChanged:Event"); +} + +IAddOnContentManager::~IAddOnContentManager() { + service_context.CloseEvent(aoc_change_event); +} + +Result IAddOnContentManager::CountAddOnContent(Out<u32> out_count, ClientProcessId process_id) { + LOG_DEBUG(Service_AOC, "called. process_id={}", process_id.pid); + + const auto current = system.GetApplicationProcessProgramID(); + + const auto& disabled = Settings::values.disabled_addons[current]; + if (std::find(disabled.begin(), disabled.end(), "DLC") != disabled.end()) { + *out_count = 0; + R_SUCCEED(); + } + + *out_count = static_cast<u32>( + std::count_if(add_on_content.begin(), add_on_content.end(), + [current](u64 tid) { return CheckAOCTitleIDMatchesBase(tid, current); })); + + R_SUCCEED(); +} + +Result IAddOnContentManager::ListAddOnContent(Out<u32> out_count, + OutBuffer<BufferAttr_HipcMapAlias> out_addons, + u32 offset, u32 count, ClientProcessId process_id) { + LOG_DEBUG(Service_AOC, "called with offset={}, count={}, process_id={}", offset, count, + process_id.pid); + + const auto current = FileSys::GetBaseTitleID(system.GetApplicationProcessProgramID()); + + std::vector<u32> out; + const auto& disabled = Settings::values.disabled_addons[current]; + if (std::find(disabled.begin(), disabled.end(), "DLC") == disabled.end()) { + for (u64 content_id : add_on_content) { + if (FileSys::GetBaseTitleID(content_id) != current) { + continue; + } + + out.push_back(static_cast<u32>(FileSys::GetAOCID(content_id))); + } + } + + // TODO(DarkLordZach): Find the correct error code. + R_UNLESS(out.size() >= offset, ResultUnknown); + + *out_count = static_cast<u32>(std::min<size_t>(out.size() - offset, count)); + std::rotate(out.begin(), out.begin() + offset, out.end()); + + std::memcpy(out_addons.data(), out.data(), *out_count * sizeof(u32)); + + R_SUCCEED(); +} + +Result IAddOnContentManager::GetAddOnContentBaseId(Out<u64> out_title_id, + ClientProcessId process_id) { + LOG_DEBUG(Service_AOC, "called. process_id={}", process_id.pid); + + const auto title_id = system.GetApplicationProcessProgramID(); + const FileSys::PatchManager pm{title_id, system.GetFileSystemController(), + system.GetContentProvider()}; + + const auto res = pm.GetControlMetadata(); + if (res.first == nullptr) { + *out_title_id = FileSys::GetAOCBaseTitleID(title_id); + R_SUCCEED(); + } + + *out_title_id = res.first->GetDLCBaseTitleId(); + + R_SUCCEED(); +} + +Result IAddOnContentManager::PrepareAddOnContent(s32 addon_index, ClientProcessId process_id) { + LOG_WARNING(Service_AOC, "(STUBBED) called with addon_index={}, process_id={}", addon_index, + process_id.pid); + + R_SUCCEED(); +} + +Result IAddOnContentManager::GetAddOnContentListChangedEvent( + OutCopyHandle<Kernel::KReadableEvent> out_event) { + LOG_WARNING(Service_AOC, "(STUBBED) called"); + + *out_event = &aoc_change_event->GetReadableEvent(); + + R_SUCCEED(); +} + +Result IAddOnContentManager::GetAddOnContentListChangedEventWithProcessId( + OutCopyHandle<Kernel::KReadableEvent> out_event, ClientProcessId process_id) { + LOG_WARNING(Service_AOC, "(STUBBED) called"); + + *out_event = &aoc_change_event->GetReadableEvent(); + + R_SUCCEED(); +} + +Result IAddOnContentManager::NotifyMountAddOnContent() { + LOG_WARNING(Service_AOC, "(STUBBED) called"); + + R_SUCCEED(); +} + +Result IAddOnContentManager::NotifyUnmountAddOnContent() { + LOG_WARNING(Service_AOC, "(STUBBED) called"); + + R_SUCCEED(); +} + +Result IAddOnContentManager::CheckAddOnContentMountStatus() { + LOG_WARNING(Service_AOC, "(STUBBED) called"); + + R_SUCCEED(); +} + +Result IAddOnContentManager::CreateEcPurchasedEventManager( + OutInterface<IPurchaseEventManager> out_interface) { + LOG_WARNING(Service_AOC, "(STUBBED) called"); + + *out_interface = std::make_shared<IPurchaseEventManager>(system); + + R_SUCCEED(); +} + +Result IAddOnContentManager::CreatePermanentEcPurchasedEventManager( + OutInterface<IPurchaseEventManager> out_interface) { + LOG_WARNING(Service_AOC, "(STUBBED) called"); + + *out_interface = std::make_shared<IPurchaseEventManager>(system); + + R_SUCCEED(); +} + +void LoopProcess(Core::System& system) { + auto server_manager = std::make_unique<ServerManager>(system); + server_manager->RegisterNamedService("aoc:u", std::make_shared<IAddOnContentManager>(system)); + ServerManager::RunServer(std::move(server_manager)); +} + +} // namespace Service::AOC diff --git a/src/core/hle/service/aoc/addon_content_manager.h b/src/core/hle/service/aoc/addon_content_manager.h new file mode 100644 index 000000000..91857df4c --- /dev/null +++ b/src/core/hle/service/aoc/addon_content_manager.h @@ -0,0 +1,51 @@ +// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include "core/hle/service/cmif_types.h" +#include "core/hle/service/kernel_helpers.h" +#include "core/hle/service/service.h" + +namespace Core { +class System; +} + +namespace Kernel { +class KEvent; +} + +namespace Service::AOC { + +class IPurchaseEventManager; + +class IAddOnContentManager final : public ServiceFramework<IAddOnContentManager> { +public: + explicit IAddOnContentManager(Core::System& system); + ~IAddOnContentManager() override; + + Result CountAddOnContent(Out<u32> out_count, ClientProcessId process_id); + Result ListAddOnContent(Out<u32> out_count, OutBuffer<BufferAttr_HipcMapAlias> out_addons, + u32 offset, u32 count, ClientProcessId process_id); + Result GetAddOnContentBaseId(Out<u64> out_title_id, ClientProcessId process_id); + Result PrepareAddOnContent(s32 addon_index, ClientProcessId process_id); + Result GetAddOnContentListChangedEvent(OutCopyHandle<Kernel::KReadableEvent> out_event); + Result GetAddOnContentListChangedEventWithProcessId( + OutCopyHandle<Kernel::KReadableEvent> out_event, ClientProcessId process_id); + Result NotifyMountAddOnContent(); + Result NotifyUnmountAddOnContent(); + Result CheckAddOnContentMountStatus(); + Result CreateEcPurchasedEventManager(OutInterface<IPurchaseEventManager> out_interface); + Result CreatePermanentEcPurchasedEventManager( + OutInterface<IPurchaseEventManager> out_interface); + +private: + std::vector<u64> add_on_content; + KernelHelpers::ServiceContext service_context; + + Kernel::KEvent* aoc_change_event; +}; + +void LoopProcess(Core::System& system); + +} // namespace Service::AOC diff --git a/src/core/hle/service/aoc/aoc_u.cpp b/src/core/hle/service/aoc/aoc_u.cpp deleted file mode 100644 index 486719cc0..000000000 --- a/src/core/hle/service/aoc/aoc_u.cpp +++ /dev/null @@ -1,340 +0,0 @@ -// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later - -#include <algorithm> -#include <numeric> -#include <vector> - -#include "common/logging/log.h" -#include "common/settings.h" -#include "core/core.h" -#include "core/file_sys/common_funcs.h" -#include "core/file_sys/content_archive.h" -#include "core/file_sys/control_metadata.h" -#include "core/file_sys/nca_metadata.h" -#include "core/file_sys/patch_manager.h" -#include "core/file_sys/registered_cache.h" -#include "core/hle/kernel/k_event.h" -#include "core/hle/service/aoc/aoc_u.h" -#include "core/hle/service/ipc_helpers.h" -#include "core/hle/service/server_manager.h" -#include "core/loader/loader.h" - -namespace Service::AOC { - -constexpr Result ResultNoPurchasedProductInfoAvailable{ErrorModule::NIMShop, 400}; - -static bool CheckAOCTitleIDMatchesBase(u64 title_id, u64 base) { - return FileSys::GetBaseTitleID(title_id) == base; -} - -static std::vector<u64> AccumulateAOCTitleIDs(Core::System& system) { - std::vector<u64> add_on_content; - const auto& rcu = system.GetContentProvider(); - const auto list = - rcu.ListEntriesFilter(FileSys::TitleType::AOC, FileSys::ContentRecordType::Data); - std::transform(list.begin(), list.end(), std::back_inserter(add_on_content), - [](const FileSys::ContentProviderEntry& rce) { return rce.title_id; }); - add_on_content.erase( - std::remove_if( - add_on_content.begin(), add_on_content.end(), - [&rcu](u64 tid) { - return rcu.GetEntry(tid, FileSys::ContentRecordType::Data)->GetStatus() != - Loader::ResultStatus::Success; - }), - add_on_content.end()); - return add_on_content; -} - -class IPurchaseEventManager final : public ServiceFramework<IPurchaseEventManager> { -public: - explicit IPurchaseEventManager(Core::System& system_) - : ServiceFramework{system_, "IPurchaseEventManager"}, service_context{ - system, "IPurchaseEventManager"} { - // clang-format off - static const FunctionInfo functions[] = { - {0, &IPurchaseEventManager::SetDefaultDeliveryTarget, "SetDefaultDeliveryTarget"}, - {1, &IPurchaseEventManager::SetDeliveryTarget, "SetDeliveryTarget"}, - {2, &IPurchaseEventManager::GetPurchasedEventReadableHandle, "GetPurchasedEventReadableHandle"}, - {3, &IPurchaseEventManager::PopPurchasedProductInfo, "PopPurchasedProductInfo"}, - {4, &IPurchaseEventManager::PopPurchasedProductInfoWithUid, "PopPurchasedProductInfoWithUid"}, - }; - // clang-format on - - RegisterHandlers(functions); - - purchased_event = service_context.CreateEvent("IPurchaseEventManager:PurchasedEvent"); - } - - ~IPurchaseEventManager() override { - service_context.CloseEvent(purchased_event); - } - -private: - void SetDefaultDeliveryTarget(HLERequestContext& ctx) { - IPC::RequestParser rp{ctx}; - - const auto unknown_1 = rp.Pop<u64>(); - [[maybe_unused]] const auto unknown_2 = ctx.ReadBuffer(); - - LOG_WARNING(Service_AOC, "(STUBBED) called, unknown_1={}", unknown_1); - - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(ResultSuccess); - } - - void SetDeliveryTarget(HLERequestContext& ctx) { - IPC::RequestParser rp{ctx}; - - const auto unknown_1 = rp.Pop<u64>(); - [[maybe_unused]] const auto unknown_2 = ctx.ReadBuffer(); - - LOG_WARNING(Service_AOC, "(STUBBED) called, unknown_1={}", unknown_1); - - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(ResultSuccess); - } - - void GetPurchasedEventReadableHandle(HLERequestContext& ctx) { - LOG_WARNING(Service_AOC, "called"); - - IPC::ResponseBuilder rb{ctx, 2, 1}; - rb.Push(ResultSuccess); - rb.PushCopyObjects(purchased_event->GetReadableEvent()); - } - - void PopPurchasedProductInfo(HLERequestContext& ctx) { - LOG_DEBUG(Service_AOC, "(STUBBED) called"); - - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(ResultNoPurchasedProductInfoAvailable); - } - - void PopPurchasedProductInfoWithUid(HLERequestContext& ctx) { - LOG_DEBUG(Service_AOC, "(STUBBED) called"); - - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(ResultNoPurchasedProductInfoAvailable); - } - - KernelHelpers::ServiceContext service_context; - - Kernel::KEvent* purchased_event; -}; - -AOC_U::AOC_U(Core::System& system_) - : ServiceFramework{system_, "aoc:u"}, add_on_content{AccumulateAOCTitleIDs(system)}, - service_context{system_, "aoc:u"} { - // clang-format off - static const FunctionInfo functions[] = { - {0, nullptr, "CountAddOnContentByApplicationId"}, - {1, nullptr, "ListAddOnContentByApplicationId"}, - {2, &AOC_U::CountAddOnContent, "CountAddOnContent"}, - {3, &AOC_U::ListAddOnContent, "ListAddOnContent"}, - {4, nullptr, "GetAddOnContentBaseIdByApplicationId"}, - {5, &AOC_U::GetAddOnContentBaseId, "GetAddOnContentBaseId"}, - {6, nullptr, "PrepareAddOnContentByApplicationId"}, - {7, &AOC_U::PrepareAddOnContent, "PrepareAddOnContent"}, - {8, &AOC_U::GetAddOnContentListChangedEvent, "GetAddOnContentListChangedEvent"}, - {9, nullptr, "GetAddOnContentLostErrorCode"}, - {10, &AOC_U::GetAddOnContentListChangedEventWithProcessId, "GetAddOnContentListChangedEventWithProcessId"}, - {11, &AOC_U::NotifyMountAddOnContent, "NotifyMountAddOnContent"}, - {12, &AOC_U::NotifyUnmountAddOnContent, "NotifyUnmountAddOnContent"}, - {13, nullptr, "IsAddOnContentMountedForDebug"}, - {50, &AOC_U::CheckAddOnContentMountStatus, "CheckAddOnContentMountStatus"}, - {100, &AOC_U::CreateEcPurchasedEventManager, "CreateEcPurchasedEventManager"}, - {101, &AOC_U::CreatePermanentEcPurchasedEventManager, "CreatePermanentEcPurchasedEventManager"}, - {110, nullptr, "CreateContentsServiceManager"}, - {200, nullptr, "SetRequiredAddOnContentsOnContentsAvailabilityTransition"}, - {300, nullptr, "SetupHostAddOnContent"}, - {301, nullptr, "GetRegisteredAddOnContentPath"}, - {302, nullptr, "UpdateCachedList"}, - }; - // clang-format on - - RegisterHandlers(functions); - - aoc_change_event = service_context.CreateEvent("GetAddOnContentListChanged:Event"); -} - -AOC_U::~AOC_U() { - service_context.CloseEvent(aoc_change_event); -} - -void AOC_U::CountAddOnContent(HLERequestContext& ctx) { - struct Parameters { - u64 process_id; - }; - static_assert(sizeof(Parameters) == 8); - - IPC::RequestParser rp{ctx}; - const auto params = rp.PopRaw<Parameters>(); - - LOG_DEBUG(Service_AOC, "called. process_id={}", params.process_id); - - IPC::ResponseBuilder rb{ctx, 3}; - rb.Push(ResultSuccess); - - const auto current = system.GetApplicationProcessProgramID(); - - const auto& disabled = Settings::values.disabled_addons[current]; - if (std::find(disabled.begin(), disabled.end(), "DLC") != disabled.end()) { - rb.Push<u32>(0); - return; - } - - rb.Push<u32>(static_cast<u32>( - std::count_if(add_on_content.begin(), add_on_content.end(), - [current](u64 tid) { return CheckAOCTitleIDMatchesBase(tid, current); }))); -} - -void AOC_U::ListAddOnContent(HLERequestContext& ctx) { - struct Parameters { - u32 offset; - u32 count; - u64 process_id; - }; - static_assert(sizeof(Parameters) == 16); - - IPC::RequestParser rp{ctx}; - const auto [offset, count, process_id] = rp.PopRaw<Parameters>(); - - LOG_DEBUG(Service_AOC, "called with offset={}, count={}, process_id={}", offset, count, - process_id); - - const auto current = FileSys::GetBaseTitleID(system.GetApplicationProcessProgramID()); - - std::vector<u32> out; - const auto& disabled = Settings::values.disabled_addons[current]; - if (std::find(disabled.begin(), disabled.end(), "DLC") == disabled.end()) { - for (u64 content_id : add_on_content) { - if (FileSys::GetBaseTitleID(content_id) != current) { - continue; - } - - out.push_back(static_cast<u32>(FileSys::GetAOCID(content_id))); - } - } - - if (out.size() < offset) { - IPC::ResponseBuilder rb{ctx, 2}; - // TODO(DarkLordZach): Find the correct error code. - rb.Push(ResultUnknown); - return; - } - - const auto out_count = static_cast<u32>(std::min<size_t>(out.size() - offset, count)); - std::rotate(out.begin(), out.begin() + offset, out.end()); - out.resize(out_count); - - ctx.WriteBuffer(out); - - IPC::ResponseBuilder rb{ctx, 3}; - rb.Push(ResultSuccess); - rb.Push(out_count); -} - -void AOC_U::GetAddOnContentBaseId(HLERequestContext& ctx) { - struct Parameters { - u64 process_id; - }; - static_assert(sizeof(Parameters) == 8); - - IPC::RequestParser rp{ctx}; - const auto params = rp.PopRaw<Parameters>(); - - LOG_DEBUG(Service_AOC, "called. process_id={}", params.process_id); - - IPC::ResponseBuilder rb{ctx, 4}; - rb.Push(ResultSuccess); - - const auto title_id = system.GetApplicationProcessProgramID(); - const FileSys::PatchManager pm{title_id, system.GetFileSystemController(), - system.GetContentProvider()}; - - const auto res = pm.GetControlMetadata(); - if (res.first == nullptr) { - rb.Push(FileSys::GetAOCBaseTitleID(title_id)); - return; - } - - rb.Push(res.first->GetDLCBaseTitleId()); -} - -void AOC_U::PrepareAddOnContent(HLERequestContext& ctx) { - struct Parameters { - s32 addon_index; - u64 process_id; - }; - static_assert(sizeof(Parameters) == 16); - - IPC::RequestParser rp{ctx}; - const auto [addon_index, process_id] = rp.PopRaw<Parameters>(); - - LOG_WARNING(Service_AOC, "(STUBBED) called with addon_index={}, process_id={}", addon_index, - process_id); - - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(ResultSuccess); -} - -void AOC_U::GetAddOnContentListChangedEvent(HLERequestContext& ctx) { - LOG_WARNING(Service_AOC, "(STUBBED) called"); - - IPC::ResponseBuilder rb{ctx, 2, 1}; - rb.Push(ResultSuccess); - rb.PushCopyObjects(aoc_change_event->GetReadableEvent()); -} - -void AOC_U::GetAddOnContentListChangedEventWithProcessId(HLERequestContext& ctx) { - LOG_WARNING(Service_AOC, "(STUBBED) called"); - - IPC::ResponseBuilder rb{ctx, 2, 1}; - rb.Push(ResultSuccess); - rb.PushCopyObjects(aoc_change_event->GetReadableEvent()); -} - -void AOC_U::NotifyMountAddOnContent(HLERequestContext& ctx) { - LOG_WARNING(Service_AOC, "(STUBBED) called"); - - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(ResultSuccess); -} - -void AOC_U::NotifyUnmountAddOnContent(HLERequestContext& ctx) { - LOG_WARNING(Service_AOC, "(STUBBED) called"); - - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(ResultSuccess); -} - -void AOC_U::CheckAddOnContentMountStatus(HLERequestContext& ctx) { - LOG_WARNING(Service_AOC, "(STUBBED) called"); - - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(ResultSuccess); -} - -void AOC_U::CreateEcPurchasedEventManager(HLERequestContext& ctx) { - LOG_WARNING(Service_AOC, "(STUBBED) called"); - - IPC::ResponseBuilder rb{ctx, 2, 0, 1}; - rb.Push(ResultSuccess); - rb.PushIpcInterface<IPurchaseEventManager>(system); -} - -void AOC_U::CreatePermanentEcPurchasedEventManager(HLERequestContext& ctx) { - LOG_WARNING(Service_AOC, "(STUBBED) called"); - - IPC::ResponseBuilder rb{ctx, 2, 0, 1}; - rb.Push(ResultSuccess); - rb.PushIpcInterface<IPurchaseEventManager>(system); -} - -void LoopProcess(Core::System& system) { - auto server_manager = std::make_unique<ServerManager>(system); - server_manager->RegisterNamedService("aoc:u", std::make_shared<AOC_U>(system)); - ServerManager::RunServer(std::move(server_manager)); -} - -} // namespace Service::AOC diff --git a/src/core/hle/service/aoc/aoc_u.h b/src/core/hle/service/aoc/aoc_u.h deleted file mode 100644 index 12ccfeb6a..000000000 --- a/src/core/hle/service/aoc/aoc_u.h +++ /dev/null @@ -1,45 +0,0 @@ -// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later - -#pragma once - -#include "core/hle/service/kernel_helpers.h" -#include "core/hle/service/service.h" - -namespace Core { -class System; -} - -namespace Kernel { -class KEvent; -} - -namespace Service::AOC { - -class AOC_U final : public ServiceFramework<AOC_U> { -public: - explicit AOC_U(Core::System& system); - ~AOC_U() override; - -private: - void CountAddOnContent(HLERequestContext& ctx); - void ListAddOnContent(HLERequestContext& ctx); - void GetAddOnContentBaseId(HLERequestContext& ctx); - void PrepareAddOnContent(HLERequestContext& ctx); - void GetAddOnContentListChangedEvent(HLERequestContext& ctx); - void GetAddOnContentListChangedEventWithProcessId(HLERequestContext& ctx); - void NotifyMountAddOnContent(HLERequestContext& ctx); - void NotifyUnmountAddOnContent(HLERequestContext& ctx); - void CheckAddOnContentMountStatus(HLERequestContext& ctx); - void CreateEcPurchasedEventManager(HLERequestContext& ctx); - void CreatePermanentEcPurchasedEventManager(HLERequestContext& ctx); - - std::vector<u64> add_on_content; - KernelHelpers::ServiceContext service_context; - - Kernel::KEvent* aoc_change_event; -}; - -void LoopProcess(Core::System& system); - -} // namespace Service::AOC diff --git a/src/core/hle/service/aoc/purchase_event_manager.cpp b/src/core/hle/service/aoc/purchase_event_manager.cpp new file mode 100644 index 000000000..9e718510b --- /dev/null +++ b/src/core/hle/service/aoc/purchase_event_manager.cpp @@ -0,0 +1,67 @@ +// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "core/hle/service/aoc/purchase_event_manager.h" +#include "core/hle/service/cmif_serialization.h" + +namespace Service::AOC { + +constexpr Result ResultNoPurchasedProductInfoAvailable{ErrorModule::NIMShop, 400}; + +IPurchaseEventManager::IPurchaseEventManager(Core::System& system_) + : ServiceFramework{system_, "IPurchaseEventManager"}, service_context{system, + "IPurchaseEventManager"} { + // clang-format off + static const FunctionInfo functions[] = { + {0, D<&IPurchaseEventManager::SetDefaultDeliveryTarget>, "SetDefaultDeliveryTarget"}, + {1, D<&IPurchaseEventManager::SetDeliveryTarget>, "SetDeliveryTarget"}, + {2, D<&IPurchaseEventManager::GetPurchasedEvent>, "GetPurchasedEvent"}, + {3, D<&IPurchaseEventManager::PopPurchasedProductInfo>, "PopPurchasedProductInfo"}, + {4, D<&IPurchaseEventManager::PopPurchasedProductInfoWithUid>, "PopPurchasedProductInfoWithUid"}, + }; + // clang-format on + + RegisterHandlers(functions); + + purchased_event = service_context.CreateEvent("IPurchaseEventManager:PurchasedEvent"); +} + +IPurchaseEventManager::~IPurchaseEventManager() { + service_context.CloseEvent(purchased_event); +} + +Result IPurchaseEventManager::SetDefaultDeliveryTarget( + ClientProcessId process_id, InBuffer<BufferAttr_HipcMapAlias> in_buffer) { + LOG_WARNING(Service_AOC, "(STUBBED) called, process_id={}", process_id.pid); + + R_SUCCEED(); +} + +Result IPurchaseEventManager::SetDeliveryTarget(u64 unknown, + InBuffer<BufferAttr_HipcMapAlias> in_buffer) { + LOG_WARNING(Service_AOC, "(STUBBED) called, unknown={}", unknown); + + R_SUCCEED(); +} + +Result IPurchaseEventManager::GetPurchasedEvent(OutCopyHandle<Kernel::KReadableEvent> out_event) { + LOG_WARNING(Service_AOC, "called"); + + *out_event = &purchased_event->GetReadableEvent(); + + R_SUCCEED(); +} + +Result IPurchaseEventManager::PopPurchasedProductInfo() { + LOG_DEBUG(Service_AOC, "(STUBBED) called"); + + R_RETURN(ResultNoPurchasedProductInfoAvailable); +} + +Result IPurchaseEventManager::PopPurchasedProductInfoWithUid() { + LOG_DEBUG(Service_AOC, "(STUBBED) called"); + + R_RETURN(ResultNoPurchasedProductInfoAvailable); +} + +} // namespace Service::AOC diff --git a/src/core/hle/service/aoc/purchase_event_manager.h b/src/core/hle/service/aoc/purchase_event_manager.h new file mode 100644 index 000000000..ea3836bc9 --- /dev/null +++ b/src/core/hle/service/aoc/purchase_event_manager.h @@ -0,0 +1,30 @@ +// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include "core/hle/service/cmif_types.h" +#include "core/hle/service/kernel_helpers.h" +#include "core/hle/service/os/event.h" +#include "core/hle/service/service.h" + +namespace Service::AOC { + +class IPurchaseEventManager final : public ServiceFramework<IPurchaseEventManager> { +public: + explicit IPurchaseEventManager(Core::System& system_); + ~IPurchaseEventManager() override; + + Result SetDefaultDeliveryTarget(ClientProcessId process_id, + InBuffer<BufferAttr_HipcMapAlias> in_buffer); + Result SetDeliveryTarget(u64 unknown, InBuffer<BufferAttr_HipcMapAlias> in_buffer); + Result GetPurchasedEvent(OutCopyHandle<Kernel::KReadableEvent> out_event); + Result PopPurchasedProductInfo(); + Result PopPurchasedProductInfoWithUid(); + +private: + KernelHelpers::ServiceContext service_context; + Kernel::KEvent* purchased_event; +}; + +} // namespace Service::AOC diff --git a/src/core/hle/service/audio/audio_controller.cpp b/src/core/hle/service/audio/audio_controller.cpp index c9804cf9c..7a51d1023 100644 --- a/src/core/hle/service/audio/audio_controller.cpp +++ b/src/core/hle/service/audio/audio_controller.cpp @@ -138,7 +138,7 @@ Result IAudioController::SetOutputModeSetting(Set::AudioOutputModeTarget target, } Result IAudioController::SetHeadphoneOutputLevelMode(HeadphoneOutputLevelMode output_level_mode) { - LOG_WARNING(Audio, "(STUBBED) called"); + LOG_WARNING(Audio, "(STUBBED) called, output_level_mode={}", output_level_mode); R_SUCCEED(); } diff --git a/src/core/hle/service/btdrv/btdrv.cpp b/src/core/hle/service/btdrv/btdrv.cpp index 38cdd57ad..83618a956 100644 --- a/src/core/hle/service/btdrv/btdrv.cpp +++ b/src/core/hle/service/btdrv/btdrv.cpp @@ -5,6 +5,7 @@ #include "core/core.h" #include "core/hle/kernel/k_event.h" #include "core/hle/service/btdrv/btdrv.h" +#include "core/hle/service/cmif_serialization.h" #include "core/hle/service/ipc_helpers.h" #include "core/hle/service/kernel_helpers.h" #include "core/hle/service/server_manager.h" @@ -13,9 +14,9 @@ namespace Service::BtDrv { -class Bt final : public ServiceFramework<Bt> { +class IBluetoothUser final : public ServiceFramework<IBluetoothUser> { public: - explicit Bt(Core::System& system_) + explicit IBluetoothUser(Core::System& system_) : ServiceFramework{system_, "bt"}, service_context{system_, "bt"} { // clang-format off static const FunctionInfo functions[] = { @@ -28,7 +29,7 @@ public: {6, nullptr, "SetLeResponse"}, {7, nullptr, "LeSendIndication"}, {8, nullptr, "GetLeEventInfo"}, - {9, &Bt::RegisterBleEvent, "RegisterBleEvent"}, + {9, C<&IBluetoothUser::RegisterBleEvent>, "RegisterBleEvent"}, }; // clang-format on RegisterHandlers(functions); @@ -36,17 +37,16 @@ public: register_event = service_context.CreateEvent("BT:RegisterEvent"); } - ~Bt() override { + ~IBluetoothUser() override { service_context.CloseEvent(register_event); } private: - void RegisterBleEvent(HLERequestContext& ctx) { + Result RegisterBleEvent(OutCopyHandle<Kernel::KReadableEvent> out_event) { LOG_WARNING(Service_BTM, "(STUBBED) called"); - IPC::ResponseBuilder rb{ctx, 2, 1}; - rb.Push(ResultSuccess); - rb.PushCopyObjects(register_event->GetReadableEvent()); + *out_event = ®ister_event->GetReadableEvent(); + R_SUCCEED(); } KernelHelpers::ServiceContext service_context; @@ -54,9 +54,9 @@ private: Kernel::KEvent* register_event; }; -class BtDrv final : public ServiceFramework<BtDrv> { +class IBluetoothDriver final : public ServiceFramework<IBluetoothDriver> { public: - explicit BtDrv(Core::System& system_) : ServiceFramework{system_, "btdrv"} { + explicit IBluetoothDriver(Core::System& system_) : ServiceFramework{system_, "btdrv"} { // clang-format off static const FunctionInfo functions[] = { {0, nullptr, "InitializeBluetoothDriver"}, @@ -93,7 +93,7 @@ public: {31, nullptr, "EnableMcMode"}, {32, nullptr, "EnableLlrScan"}, {33, nullptr, "DisableLlrScan"}, - {34, nullptr, "EnableRadio"}, + {34, C<&IBluetoothDriver::EnableRadio>, "EnableRadio"}, {35, nullptr, "SetVisibility"}, {36, nullptr, "EnableTbfcScan"}, {37, nullptr, "RegisterHidReportEvent"}, @@ -195,13 +195,19 @@ public: RegisterHandlers(functions); } + +private: + Result EnableRadio() { + LOG_WARNING(Service_BTDRV, "(STUBBED) called"); + R_SUCCEED(); + } }; void LoopProcess(Core::System& system) { auto server_manager = std::make_unique<ServerManager>(system); - server_manager->RegisterNamedService("btdrv", std::make_shared<BtDrv>(system)); - server_manager->RegisterNamedService("bt", std::make_shared<Bt>(system)); + server_manager->RegisterNamedService("btdrv", std::make_shared<IBluetoothDriver>(system)); + server_manager->RegisterNamedService("bt", std::make_shared<IBluetoothUser>(system)); ServerManager::RunServer(std::move(server_manager)); } diff --git a/src/core/hle/service/erpt/erpt.cpp b/src/core/hle/service/erpt/erpt.cpp index 39ae3a723..6b7eab5ef 100644 --- a/src/core/hle/service/erpt/erpt.cpp +++ b/src/core/hle/service/erpt/erpt.cpp @@ -18,7 +18,7 @@ public: // clang-format off static const FunctionInfo functions[] = { {0, C<&ErrorReportContext::SubmitContext>, "SubmitContext"}, - {1, nullptr, "CreateReportV0"}, + {1, C<&ErrorReportContext::CreateReportV0>, "CreateReportV0"}, {2, nullptr, "SetInitialLaunchSettingsCompletionTime"}, {3, nullptr, "ClearInitialLaunchSettingsCompletionTime"}, {4, nullptr, "UpdatePowerOnTime"}, @@ -28,7 +28,8 @@ public: {8, nullptr, "ClearApplicationLaunchTime"}, {9, nullptr, "SubmitAttachment"}, {10, nullptr, "CreateReportWithAttachments"}, - {11, nullptr, "CreateReport"}, + {11, C<&ErrorReportContext::CreateReportV1>, "CreateReportV1"}, + {12, C<&ErrorReportContext::CreateReport>, "CreateReport"}, {20, nullptr, "RegisterRunningApplet"}, {21, nullptr, "UnregisterRunningApplet"}, {22, nullptr, "UpdateAppletSuspendedDuration"}, @@ -40,10 +41,37 @@ public: } private: - Result SubmitContext(InBuffer<BufferAttr_HipcMapAlias> buffer_a, - InBuffer<BufferAttr_HipcMapAlias> buffer_b) { - LOG_WARNING(Service_SET, "(STUBBED) called, buffer_a_size={}, buffer_b_size={}", - buffer_a.size(), buffer_b.size()); + Result SubmitContext(InBuffer<BufferAttr_HipcMapAlias> context_entry, + InBuffer<BufferAttr_HipcMapAlias> field_list) { + LOG_WARNING(Service_SET, "(STUBBED) called, context_entry_size={}, field_list_size={}", + context_entry.size(), field_list.size()); + R_SUCCEED(); + } + + Result CreateReportV0(u32 report_type, InBuffer<BufferAttr_HipcMapAlias> context_entry, + InBuffer<BufferAttr_HipcMapAlias> report_list, + InBuffer<BufferAttr_HipcMapAlias> report_meta_data) { + LOG_WARNING(Service_SET, "(STUBBED) called, report_type={:#x}", report_type); + R_SUCCEED(); + } + + Result CreateReportV1(u32 report_type, u32 unknown, + InBuffer<BufferAttr_HipcMapAlias> context_entry, + InBuffer<BufferAttr_HipcMapAlias> report_list, + InBuffer<BufferAttr_HipcMapAlias> report_meta_data) { + LOG_WARNING(Service_SET, "(STUBBED) called, report_type={:#x}, unknown={:#x}", report_type, + unknown); + R_SUCCEED(); + } + + Result CreateReport(u32 report_type, u32 unknown, u32 create_report_option_flag, + InBuffer<BufferAttr_HipcMapAlias> context_entry, + InBuffer<BufferAttr_HipcMapAlias> report_list, + InBuffer<BufferAttr_HipcMapAlias> report_meta_data) { + LOG_WARNING( + Service_SET, + "(STUBBED) called, report_type={:#x}, unknown={:#x}, create_report_option_flag={:#x}", + report_type, unknown, create_report_option_flag); R_SUCCEED(); } }; diff --git a/src/core/hle/service/filesystem/fsp/fsp_srv.cpp b/src/core/hle/service/filesystem/fsp/fsp_srv.cpp index 223284255..60290f1a6 100644 --- a/src/core/hle/service/filesystem/fsp/fsp_srv.cpp +++ b/src/core/hle/service/filesystem/fsp/fsp_srv.cpp @@ -71,7 +71,7 @@ FSP_SRV::FSP_SRV(Core::System& system_) {28, nullptr, "DeleteSaveDataFileSystemBySaveDataAttribute"}, {30, nullptr, "OpenGameCardStorage"}, {31, nullptr, "OpenGameCardFileSystem"}, - {32, nullptr, "ExtendSaveDataFileSystem"}, + {32, D<&FSP_SRV::ExtendSaveDataFileSystem>, "ExtendSaveDataFileSystem"}, {33, nullptr, "DeleteCacheStorage"}, {34, D<&FSP_SRV::GetCacheStorageSize>, "GetCacheStorageSize"}, {35, nullptr, "CreateSaveDataFileSystemByHashSalt"}, @@ -79,9 +79,9 @@ FSP_SRV::FSP_SRV(Core::System& system_) {51, D<&FSP_SRV::OpenSaveDataFileSystem>, "OpenSaveDataFileSystem"}, {52, D<&FSP_SRV::OpenSaveDataFileSystemBySystemSaveDataId>, "OpenSaveDataFileSystemBySystemSaveDataId"}, {53, D<&FSP_SRV::OpenReadOnlySaveDataFileSystem>, "OpenReadOnlySaveDataFileSystem"}, - {57, nullptr, "ReadSaveDataFileSystemExtraDataBySaveDataSpaceId"}, - {58, nullptr, "ReadSaveDataFileSystemExtraData"}, - {59, nullptr, "WriteSaveDataFileSystemExtraData"}, + {57, D<&FSP_SRV::ReadSaveDataFileSystemExtraDataBySaveDataSpaceId>, "ReadSaveDataFileSystemExtraDataBySaveDataSpaceId"}, + {58, D<&FSP_SRV::ReadSaveDataFileSystemExtraData>, "ReadSaveDataFileSystemExtraData"}, + {59, D<&FSP_SRV::WriteSaveDataFileSystemExtraData>, "WriteSaveDataFileSystemExtraData"}, {60, nullptr, "OpenSaveDataInfoReader"}, {61, D<&FSP_SRV::OpenSaveDataInfoReaderBySaveDataSpaceId>, "OpenSaveDataInfoReaderBySaveDataSpaceId"}, {62, D<&FSP_SRV::OpenSaveDataInfoReaderOnlyCacheStorage>, "OpenSaveDataInfoReaderOnlyCacheStorage"}, @@ -90,8 +90,8 @@ FSP_SRV::FSP_SRV(Core::System& system_) {66, nullptr, "WriteSaveDataFileSystemExtraData2"}, {67, D<&FSP_SRV::FindSaveDataWithFilter>, "FindSaveDataWithFilter"}, {68, nullptr, "OpenSaveDataInfoReaderBySaveDataFilter"}, - {69, nullptr, "ReadSaveDataFileSystemExtraDataBySaveDataAttribute"}, - {70, D<&FSP_SRV::WriteSaveDataFileSystemExtraDataBySaveDataAttribute>, "WriteSaveDataFileSystemExtraDataBySaveDataAttribute"}, + {69, D<&FSP_SRV::ReadSaveDataFileSystemExtraDataBySaveDataAttribute>, "ReadSaveDataFileSystemExtraDataBySaveDataAttribute"}, + {70, D<&FSP_SRV::WriteSaveDataFileSystemExtraDataWithMaskBySaveDataAttribute>, "WriteSaveDataFileSystemExtraDataWithMaskBySaveDataAttribute"}, {71, D<&FSP_SRV::ReadSaveDataFileSystemExtraDataWithMaskBySaveDataAttribute>, "ReadSaveDataFileSystemExtraDataWithMaskBySaveDataAttribute"}, {80, nullptr, "OpenSaveDataMetaFile"}, {81, nullptr, "OpenSaveDataTransferManager"}, @@ -317,9 +317,23 @@ Result FSP_SRV::FindSaveDataWithFilter(Out<s64> out_count, R_THROW(FileSys::ResultTargetNotFound); } -Result FSP_SRV::WriteSaveDataFileSystemExtraDataBySaveDataAttribute() { - LOG_WARNING(Service_FS, "(STUBBED) called."); +Result FSP_SRV::WriteSaveDataFileSystemExtraData(InBuffer<BufferAttr_HipcMapAlias> buffer, + FileSys::SaveDataSpaceId space_id, + u64 save_data_id) { + LOG_WARNING(Service_FS, "(STUBBED) called, space_id={}, save_data_id={:016X}", space_id, + save_data_id); + R_SUCCEED(); +} +Result FSP_SRV::WriteSaveDataFileSystemExtraDataWithMaskBySaveDataAttribute( + InBuffer<BufferAttr_HipcMapAlias> buffer, InBuffer<BufferAttr_HipcMapAlias> mask_buffer, + FileSys::SaveDataSpaceId space_id, FileSys::SaveDataAttribute attribute) { + LOG_WARNING(Service_FS, + "(STUBBED) called, space_id={}, attribute.program_id={:016X}\n" + "attribute.user_id={:016X}{:016X}, attribute.save_id={:016X}\n" + "attribute.type={}, attribute.rank={}, attribute.index={}", + space_id, attribute.program_id, attribute.user_id[1], attribute.user_id[0], + attribute.system_save_data_id, attribute.type, attribute.rank, attribute.index); R_SUCCEED(); } @@ -341,6 +355,38 @@ Result FSP_SRV::ReadSaveDataFileSystemExtraDataWithMaskBySaveDataAttribute( R_SUCCEED(); } +Result FSP_SRV::ReadSaveDataFileSystemExtraData(OutBuffer<BufferAttr_HipcMapAlias> out_buffer, + u64 save_data_id) { + // Stub, backend needs an impl to read/write the SaveDataExtraData + LOG_WARNING(Service_FS, "(STUBBED) called, save_data_id={:016X}", save_data_id); + std::memset(out_buffer.data(), 0, out_buffer.size()); + R_SUCCEED(); +} + +Result FSP_SRV::ReadSaveDataFileSystemExtraDataBySaveDataAttribute( + OutBuffer<BufferAttr_HipcMapAlias> out_buffer, FileSys::SaveDataSpaceId space_id, + FileSys::SaveDataAttribute attribute) { + // Stub, backend needs an impl to read/write the SaveDataExtraData + LOG_WARNING(Service_FS, + "(STUBBED) called, space_id={}, attribute.program_id={:016X}\n" + "attribute.user_id={:016X}{:016X}, attribute.save_id={:016X}\n" + "attribute.type={}, attribute.rank={}, attribute.index={}", + space_id, attribute.program_id, attribute.user_id[1], attribute.user_id[0], + attribute.system_save_data_id, attribute.type, attribute.rank, attribute.index); + std::memset(out_buffer.data(), 0, out_buffer.size()); + R_SUCCEED(); +} + +Result FSP_SRV::ReadSaveDataFileSystemExtraDataBySaveDataSpaceId( + OutBuffer<BufferAttr_HipcMapAlias> out_buffer, FileSys::SaveDataSpaceId space_id, + u64 save_data_id) { + // Stub, backend needs an impl to read/write the SaveDataExtraData + LOG_WARNING(Service_FS, "(STUBBED) called, space_id={}, save_data_id={:016X}", space_id, + save_data_id); + std::memset(out_buffer.data(), 0, out_buffer.size()); + R_SUCCEED(); +} + Result FSP_SRV::OpenSaveDataTransferProhibiter( OutInterface<ISaveDataTransferProhibiter> out_prohibiter, u64 id) { LOG_WARNING(Service_FS, "(STUBBED) called, id={:016X}", id); @@ -476,6 +522,16 @@ Result FSP_SRV::FlushAccessLogOnSdCard() { R_SUCCEED(); } +Result FSP_SRV::ExtendSaveDataFileSystem(FileSys::SaveDataSpaceId space_id, u64 save_data_id, + s64 available_size, s64 journal_size) { + // We don't have an index of save data ids, so we can't implement this. + LOG_WARNING(Service_FS, + "(STUBBED) called, space_id={}, save_data_id={:016X}, available_size={:#x}, " + "journal_size={:#x}", + space_id, save_data_id, available_size, journal_size); + R_SUCCEED(); +} + Result FSP_SRV::GetCacheStorageSize(s32 index, Out<s64> out_data_size, Out<s64> out_journal_size) { LOG_WARNING(Service_FS, "(STUBBED) called with index={}", index); diff --git a/src/core/hle/service/filesystem/fsp/fsp_srv.h b/src/core/hle/service/filesystem/fsp/fsp_srv.h index 83d9cb51c..b565cace0 100644 --- a/src/core/hle/service/filesystem/fsp/fsp_srv.h +++ b/src/core/hle/service/filesystem/fsp/fsp_srv.h @@ -70,7 +70,19 @@ private: Result FindSaveDataWithFilter(Out<s64> out_count, OutBuffer<BufferAttr_HipcMapAlias> out_buffer, FileSys::SaveDataSpaceId space_id, FileSys::SaveDataFilter filter); - Result WriteSaveDataFileSystemExtraDataBySaveDataAttribute(); + Result WriteSaveDataFileSystemExtraData(InBuffer<BufferAttr_HipcMapAlias> buffer, + FileSys::SaveDataSpaceId space_id, u64 save_data_id); + Result WriteSaveDataFileSystemExtraDataWithMaskBySaveDataAttribute( + InBuffer<BufferAttr_HipcMapAlias> buffer, InBuffer<BufferAttr_HipcMapAlias> mask_buffer, + FileSys::SaveDataSpaceId space_id, FileSys::SaveDataAttribute attribute); + Result ReadSaveDataFileSystemExtraData(OutBuffer<BufferAttr_HipcMapAlias> out_buffer, + u64 save_data_id); + Result ReadSaveDataFileSystemExtraDataBySaveDataAttribute( + OutBuffer<BufferAttr_HipcMapAlias> out_buffer, FileSys::SaveDataSpaceId space_id, + FileSys::SaveDataAttribute attribute); + Result ReadSaveDataFileSystemExtraDataBySaveDataSpaceId( + OutBuffer<BufferAttr_HipcMapAlias> out_buffer, FileSys::SaveDataSpaceId space_id, + u64 save_data_id); Result ReadSaveDataFileSystemExtraDataWithMaskBySaveDataAttribute( FileSys::SaveDataSpaceId space_id, FileSys::SaveDataAttribute attribute, InBuffer<BufferAttr_HipcMapAlias> mask_buffer, @@ -91,6 +103,8 @@ private: Result GetProgramIndexForAccessLog(Out<AccessLogVersion> out_access_log_version, Out<u32> out_access_log_program_index); Result OpenMultiCommitManager(OutInterface<IMultiCommitManager> out_interface); + Result ExtendSaveDataFileSystem(FileSys::SaveDataSpaceId space_id, u64 save_data_id, + s64 available_size, s64 journal_size); Result GetCacheStorageSize(s32 index, Out<s64> out_data_size, Out<s64> out_journal_size); FileSystemController& fsc; diff --git a/src/core/hle/service/friend/friend.cpp b/src/core/hle/service/friend/friend.cpp index aeb849efa..38e62761b 100644 --- a/src/core/hle/service/friend/friend.cpp +++ b/src/core/hle/service/friend/friend.cpp @@ -42,13 +42,13 @@ public: {10701, nullptr, "GetPlayHistoryRegistrationKeyWithNetworkServiceAccountId"}, {10702, nullptr, "AddPlayHistory"}, {11000, nullptr, "GetProfileImageUrl"}, - {20100, nullptr, "GetFriendCount"}, - {20101, nullptr, "GetNewlyFriendCount"}, + {20100, &IFriendService::GetFriendCount, "GetFriendCount"}, + {20101, &IFriendService::GetNewlyFriendCount, "GetNewlyFriendCount"}, {20102, nullptr, "GetFriendDetailedInfo"}, {20103, nullptr, "SyncFriendList"}, {20104, nullptr, "RequestSyncFriendList"}, {20110, nullptr, "LoadFriendSetting"}, - {20200, nullptr, "GetReceivedFriendRequestCount"}, + {20200, &IFriendService::GetReceivedFriendRequestCount, "GetReceivedFriendRequestCount"}, {20201, nullptr, "GetFriendRequestList"}, {20300, nullptr, "GetFriendCandidateList"}, {20301, nullptr, "GetNintendoNetworkIdInfo"}, @@ -61,14 +61,14 @@ public: {20501, nullptr, "GetRelationship"}, {20600, nullptr, "GetUserPresenceView"}, {20700, nullptr, "GetPlayHistoryList"}, - {20701, nullptr, "GetPlayHistoryStatistics"}, + {20701, &IFriendService::GetPlayHistoryStatistics, "GetPlayHistoryStatistics"}, {20800, nullptr, "LoadUserSetting"}, {20801, nullptr, "SyncUserSetting"}, {20900, nullptr, "RequestListSummaryOverlayNotification"}, {21000, nullptr, "GetExternalApplicationCatalog"}, {22000, nullptr, "GetReceivedFriendInvitationList"}, {22001, nullptr, "GetReceivedFriendInvitationDetailedInfo"}, - {22010, nullptr, "GetReceivedFriendInvitationCountCache"}, + {22010, &IFriendService::GetReceivedFriendInvitationCountCache, "GetReceivedFriendInvitationCountCache"}, {30100, nullptr, "DropFriendNewlyFlags"}, {30101, nullptr, "DeleteFriend"}, {30110, nullptr, "DropFriendNewlyFlag"}, @@ -144,6 +144,33 @@ private: rb.PushCopyObjects(completion_event->GetReadableEvent()); } + void GetFriendList(HLERequestContext& ctx) { + IPC::RequestParser rp{ctx}; + const auto friend_offset = rp.Pop<u32>(); + const auto uuid = rp.PopRaw<Common::UUID>(); + [[maybe_unused]] const auto filter = rp.PopRaw<SizedFriendFilter>(); + const auto pid = rp.Pop<u64>(); + LOG_WARNING(Service_Friend, "(STUBBED) called, offset={}, uuid=0x{}, pid={}", friend_offset, + uuid.RawString(), pid); + + IPC::ResponseBuilder rb{ctx, 3}; + rb.Push(ResultSuccess); + + rb.Push<u32>(0); // Friend count + // TODO(ogniK): Return a buffer of u64s which are the "NetworkServiceAccountId" + } + + void CheckFriendListAvailability(HLERequestContext& ctx) { + IPC::RequestParser rp{ctx}; + const auto uuid{rp.PopRaw<Common::UUID>()}; + + LOG_WARNING(Service_Friend, "(STUBBED) called, uuid=0x{}", uuid.RawString()); + + IPC::ResponseBuilder rb{ctx, 3}; + rb.Push(ResultSuccess); + rb.Push(true); + } + void GetBlockedUserListIds(HLERequestContext& ctx) { // This is safe to stub, as there should be no adverse consequences from reporting no // blocked users. @@ -153,6 +180,17 @@ private: rb.Push<u32>(0); // Indicates there are no blocked users } + void CheckBlockedUserListAvailability(HLERequestContext& ctx) { + IPC::RequestParser rp{ctx}; + const auto uuid{rp.PopRaw<Common::UUID>()}; + + LOG_WARNING(Service_Friend, "(STUBBED) called, uuid=0x{}", uuid.RawString()); + + IPC::ResponseBuilder rb{ctx, 3}; + rb.Push(ResultSuccess); + rb.Push(true); + } + void DeclareCloseOnlinePlaySession(HLERequestContext& ctx) { // Stub used by Splatoon 2 LOG_WARNING(Service_Friend, "(STUBBED) called"); @@ -179,42 +217,43 @@ private: rb.Push(ResultSuccess); } - void GetFriendList(HLERequestContext& ctx) { - IPC::RequestParser rp{ctx}; - const auto friend_offset = rp.Pop<u32>(); - const auto uuid = rp.PopRaw<Common::UUID>(); - [[maybe_unused]] const auto filter = rp.PopRaw<SizedFriendFilter>(); - const auto pid = rp.Pop<u64>(); - LOG_WARNING(Service_Friend, "(STUBBED) called, offset={}, uuid=0x{}, pid={}", friend_offset, - uuid.RawString(), pid); + void GetFriendCount(HLERequestContext& ctx) { + LOG_DEBUG(Service_Friend, "(STUBBED) called"); IPC::ResponseBuilder rb{ctx, 3}; rb.Push(ResultSuccess); - - rb.Push<u32>(0); // Friend count - // TODO(ogniK): Return a buffer of u64s which are the "NetworkServiceAccountId" + rb.Push(0); } - void CheckFriendListAvailability(HLERequestContext& ctx) { - IPC::RequestParser rp{ctx}; - const auto uuid{rp.PopRaw<Common::UUID>()}; + void GetNewlyFriendCount(HLERequestContext& ctx) { + LOG_DEBUG(Service_Friend, "(STUBBED) called"); - LOG_WARNING(Service_Friend, "(STUBBED) called, uuid=0x{}", uuid.RawString()); + IPC::ResponseBuilder rb{ctx, 3}; + rb.Push(ResultSuccess); + rb.Push(0); + } + + void GetReceivedFriendRequestCount(HLERequestContext& ctx) { + LOG_DEBUG(Service_Friend, "(STUBBED) called"); IPC::ResponseBuilder rb{ctx, 3}; rb.Push(ResultSuccess); - rb.Push(true); + rb.Push(0); } - void CheckBlockedUserListAvailability(HLERequestContext& ctx) { - IPC::RequestParser rp{ctx}; - const auto uuid{rp.PopRaw<Common::UUID>()}; + void GetPlayHistoryStatistics(HLERequestContext& ctx) { + LOG_ERROR(Service_Friend, "(STUBBED) called, check in out"); - LOG_WARNING(Service_Friend, "(STUBBED) called, uuid=0x{}", uuid.RawString()); + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(ResultSuccess); + } + + void GetReceivedFriendInvitationCountCache(HLERequestContext& ctx) { + LOG_DEBUG(Service_Friend, "(STUBBED) called, check in out"); IPC::ResponseBuilder rb{ctx, 3}; rb.Push(ResultSuccess); - rb.Push(true); + rb.Push(0); } KernelHelpers::ServiceContext service_context; diff --git a/src/core/hle/service/glue/time/manager.cpp b/src/core/hle/service/glue/time/manager.cpp index 059ac3fc9..cb88486dd 100644 --- a/src/core/hle/service/glue/time/manager.cpp +++ b/src/core/hle/service/glue/time/manager.cpp @@ -51,16 +51,17 @@ s64 CalendarTimeToEpoch(Service::PSC::Time::CalendarTime calendar) { } s64 GetEpochTimeFromInitialYear(std::shared_ptr<Service::Set::ISystemSettingsServer>& set_sys) { + s32 year{2000}; + set_sys->GetSettingsItemValueImpl(year, "time", "standard_user_clock_initial_year"); + Service::PSC::Time::CalendarTime calendar{ - .year = 2000, + .year = static_cast<s16>(year), .month = 1, .day = 1, .hour = 0, .minute = 0, .second = 0, }; - set_sys->GetSettingsItemValueImpl<s16>(calendar.year, "time", - "standard_user_clock_initial_year"); return CalendarTimeToEpoch(calendar); } diff --git a/src/core/hle/service/glue/time/worker.cpp b/src/core/hle/service/glue/time/worker.cpp index b28569b68..b6bbd7965 100644 --- a/src/core/hle/service/glue/time/worker.cpp +++ b/src/core/hle/service/glue/time/worker.cpp @@ -26,12 +26,9 @@ Service::PSC::Time::SystemClockContext g_report_ephemeral_clock_context{}; template <typename T> T GetSettingsItemValue(std::shared_ptr<Service::Set::ISystemSettingsServer>& set_sys, const char* category, const char* name) { - std::vector<u8> interval_buf; - auto res = set_sys->GetSettingsItemValueImpl(interval_buf, category, name); - ASSERT(res == ResultSuccess); - T v{}; - std::memcpy(&v, interval_buf.data(), sizeof(T)); + auto res = set_sys->GetSettingsItemValueImpl(v, category, name); + ASSERT(res == ResultSuccess); return v; } diff --git a/src/core/hle/service/hid/hid_system_server.cpp b/src/core/hle/service/hid/hid_system_server.cpp index 7126a1dcd..b0cd63d72 100644 --- a/src/core/hle/service/hid/hid_system_server.cpp +++ b/src/core/hle/service/hid/hid_system_server.cpp @@ -201,7 +201,7 @@ IHidSystemServer::IHidSystemServer(Core::System& system_, std::shared_ptr<Resour {1269, nullptr, "DeleteButtonConfigStorageLeft"}, {1270, nullptr, "DeleteButtonConfigStorageRight"}, {1271, &IHidSystemServer::IsUsingCustomButtonConfig, "IsUsingCustomButtonConfig"}, - {1272, nullptr, "IsAnyCustomButtonConfigEnabled"}, + {1272, &IHidSystemServer::IsAnyCustomButtonConfigEnabled, "IsAnyCustomButtonConfigEnabled"}, {1273, nullptr, "SetAllCustomButtonConfigEnabled"}, {1274, nullptr, "SetDefaultButtonConfig"}, {1275, nullptr, "SetAllDefaultButtonConfig"}, @@ -926,6 +926,16 @@ void IHidSystemServer::IsUsingCustomButtonConfig(HLERequestContext& ctx) { rb.Push(is_enabled); } +void IHidSystemServer::IsAnyCustomButtonConfigEnabled(HLERequestContext& ctx) { + const bool is_enabled = false; + + LOG_DEBUG(Service_HID, "(STUBBED) called, is_enabled={}", is_enabled); + + IPC::ResponseBuilder rb{ctx, 3}; + rb.Push(ResultSuccess); + rb.Push(is_enabled); +} + std::shared_ptr<ResourceManager> IHidSystemServer::GetResourceManager() { resource_manager->Initialize(); return resource_manager; diff --git a/src/core/hle/service/hid/hid_system_server.h b/src/core/hle/service/hid/hid_system_server.h index 738313e08..1a4f244d7 100644 --- a/src/core/hle/service/hid/hid_system_server.h +++ b/src/core/hle/service/hid/hid_system_server.h @@ -77,6 +77,7 @@ private: void GetTouchScreenDefaultConfiguration(HLERequestContext& ctx); void SetForceHandheldStyleVibration(HLERequestContext& ctx); void IsUsingCustomButtonConfig(HLERequestContext& ctx); + void IsAnyCustomButtonConfigEnabled(HLERequestContext& ctx); std::shared_ptr<ResourceManager> GetResourceManager(); diff --git a/src/core/hle/service/lbl/lbl.cpp b/src/core/hle/service/lbl/lbl.cpp index 98a79365d..c14b24142 100644 --- a/src/core/hle/service/lbl/lbl.cpp +++ b/src/core/hle/service/lbl/lbl.cpp @@ -18,8 +18,8 @@ public: explicit LBL(Core::System& system_) : ServiceFramework{system_, "lbl"} { // clang-format off static const FunctionInfo functions[] = { - {0, nullptr, "SaveCurrentSetting"}, - {1, nullptr, "LoadCurrentSetting"}, + {0, &LBL::SaveCurrentSetting, "SaveCurrentSetting"}, + {1, &LBL::LoadCurrentSetting, "LoadCurrentSetting"}, {2, &LBL::SetCurrentBrightnessSetting, "SetCurrentBrightnessSetting"}, {3, &LBL::GetCurrentBrightnessSetting, "GetCurrentBrightnessSetting"}, {4, nullptr, "ApplyCurrentBrightnessSettingToBacklight"}, @@ -47,7 +47,7 @@ public: {26, &LBL::EnableVrMode, "EnableVrMode"}, {27, &LBL::DisableVrMode, "DisableVrMode"}, {28, &LBL::IsVrModeEnabled, "IsVrModeEnabled"}, - {29, nullptr, "IsAutoBrightnessControlSupported"}, + {29, &LBL::IsAutoBrightnessControlSupported, "IsAutoBrightnessControlSupported"}, }; // clang-format on @@ -60,6 +60,20 @@ private: On = 1, }; + void SaveCurrentSetting(HLERequestContext& ctx) { + LOG_WARNING(Service_LBL, "(STUBBED) called"); + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(ResultSuccess); + } + + void LoadCurrentSetting(HLERequestContext& ctx) { + LOG_WARNING(Service_LBL, "(STUBBED) called"); + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(ResultSuccess); + } + void SetCurrentBrightnessSetting(HLERequestContext& ctx) { IPC::RequestParser rp{ctx}; auto brightness = rp.Pop<float>(); @@ -310,6 +324,14 @@ private: rb.Push(vr_mode_enabled); } + void IsAutoBrightnessControlSupported(HLERequestContext& ctx) { + LOG_DEBUG(Service_LBL, "called"); + + IPC::ResponseBuilder rb{ctx, 3}; + rb.Push(ResultSuccess); + rb.Push<u8>(auto_brightness_supported); + } + bool vr_mode_enabled = false; float current_brightness = 1.0f; float ambient_light_value = 0.0f; @@ -317,7 +339,8 @@ private: bool dimming = true; bool backlight_enabled = true; bool update_instantly = false; - bool auto_brightness = false; // TODO(ogniK): Move to system settings + bool auto_brightness = false; + bool auto_brightness_supported = true; // TODO(ogniK): Move to system settings }; void LoopProcess(Core::System& system) { diff --git a/src/core/hle/service/ldn/monitor_service.cpp b/src/core/hle/service/ldn/monitor_service.cpp index 3471f69da..ea6ac4d5d 100644 --- a/src/core/hle/service/ldn/monitor_service.cpp +++ b/src/core/hle/service/ldn/monitor_service.cpp @@ -2,6 +2,7 @@ // SPDX-License-Identifier: GPL-3.0-or-later #include "core/hle/service/cmif_serialization.h" +#include "core/hle/service/ldn/ldn_results.h" #include "core/hle/service/ldn/monitor_service.h" namespace Service::LDN { @@ -17,7 +18,7 @@ IMonitorService::IMonitorService(Core::System& system_) {4, nullptr, "GetSecurityParameterForMonitor"}, {5, nullptr, "GetNetworkConfigForMonitor"}, {100, C<&IMonitorService::InitializeMonitor>, "InitializeMonitor"}, - {101, nullptr, "FinalizeMonitor"}, + {101, C<&IMonitorService::FinalizeMonitor>, "FinalizeMonitor"}, }; // clang-format on @@ -27,16 +28,18 @@ IMonitorService::IMonitorService(Core::System& system_) IMonitorService::~IMonitorService() = default; Result IMonitorService::GetStateForMonitor(Out<State> out_state) { - LOG_INFO(Service_LDN, "called"); - - *out_state = state; + LOG_WARNING(Service_LDN, "(STUBBED) called"); + *out_state = State::None; R_SUCCEED(); } Result IMonitorService::InitializeMonitor() { LOG_INFO(Service_LDN, "called"); + R_SUCCEED(); +} - state = State::Initialized; +Result IMonitorService::FinalizeMonitor() { + LOG_INFO(Service_LDN, "called"); R_SUCCEED(); } diff --git a/src/core/hle/service/ldn/monitor_service.h b/src/core/hle/service/ldn/monitor_service.h index 61aacef30..e663145b4 100644 --- a/src/core/hle/service/ldn/monitor_service.h +++ b/src/core/hle/service/ldn/monitor_service.h @@ -21,6 +21,7 @@ public: private: Result GetStateForMonitor(Out<State> out_state); Result InitializeMonitor(); + Result FinalizeMonitor(); State state{State::None}; }; diff --git a/src/core/hle/service/nfc/common/device_manager.cpp b/src/core/hle/service/nfc/common/device_manager.cpp index 94a8243b5..2dd3e9f89 100644 --- a/src/core/hle/service/nfc/common/device_manager.cpp +++ b/src/core/hle/service/nfc/common/device_manager.cpp @@ -13,6 +13,7 @@ #include "core/hle/service/nfc/nfc_result.h" #include "core/hle/service/psc/time/steady_clock.h" #include "core/hle/service/service.h" +#include "core/hle/service/set/system_settings_server.h" #include "core/hle/service/sm/sm.h" #include "hid_core/hid_types.h" #include "hid_core/hid_util.h" @@ -32,6 +33,9 @@ DeviceManager::DeviceManager(Core::System& system_, KernelHelpers::ServiceContex } is_initialized = false; + + m_set_sys = + system.ServiceManager().GetService<Service::Set::ISystemSettingsServer>("set:sys", true); } DeviceManager ::~DeviceManager() { @@ -774,8 +778,8 @@ Result DeviceManager::CheckDeviceState(std::shared_ptr<NfcDevice> device) const } Result DeviceManager::IsNfcEnabled() const { - // TODO: This calls nn::settings::detail::GetNfcEnableFlag - const bool is_enabled = true; + bool is_enabled{}; + R_TRY(m_set_sys->GetNfcEnableFlag(&is_enabled)); if (!is_enabled) { return ResultNfcDisabled; } diff --git a/src/core/hle/service/nfc/common/device_manager.h b/src/core/hle/service/nfc/common/device_manager.h index c56a2fbda..6c0e6b255 100644 --- a/src/core/hle/service/nfc/common/device_manager.h +++ b/src/core/hle/service/nfc/common/device_manager.h @@ -15,6 +15,10 @@ #include "core/hle/service/service.h" #include "hid_core/hid_types.h" +namespace Service::Set { +class ISystemSettingsServer; +} + namespace Service::NFC { class NfcDevice; @@ -98,6 +102,7 @@ private: Core::System& system; KernelHelpers::ServiceContext service_context; Kernel::KEvent* availability_change_event; + std::shared_ptr<Service::Set::ISystemSettingsServer> m_set_sys; }; } // namespace Service::NFC diff --git a/src/core/hle/service/nfc/nfc.cpp b/src/core/hle/service/nfc/nfc.cpp index 30ae989b9..9d4808dbe 100644 --- a/src/core/hle/service/nfc/nfc.cpp +++ b/src/core/hle/service/nfc/nfc.cpp @@ -57,7 +57,7 @@ public: {1, &NfcInterface::Finalize, "FinalizeOld"}, {2, &NfcInterface::GetState, "GetStateOld"}, {3, &NfcInterface::IsNfcEnabled, "IsNfcEnabledOld"}, - {100, nullptr, "SetNfcEnabledOld"}, + {100, &NfcInterface::SetNfcEnabled, "SetNfcEnabledOld"}, {400, &NfcInterface::Initialize, "Initialize"}, {401, &NfcInterface::Finalize, "Finalize"}, {402, &NfcInterface::GetState, "GetState"}, @@ -71,7 +71,7 @@ public: {410, &NfcInterface::GetTagInfo, "GetTagInfo"}, {411, &NfcInterface::AttachActivateEvent, "AttachActivateEvent"}, {412, &NfcInterface::AttachDeactivateEvent, "AttachDeactivateEvent"}, - {500, nullptr, "SetNfcEnabled"}, + {500, &NfcInterface::SetNfcEnabled, "SetNfcEnabled"}, {510, nullptr, "OutputTestWave"}, {1000, &NfcInterface::ReadMifare, "ReadMifare"}, {1001, &NfcInterface::WriteMifare, "WriteMifare"}, diff --git a/src/core/hle/service/nfc/nfc_interface.cpp b/src/core/hle/service/nfc/nfc_interface.cpp index 3e2c7deab..c28e55431 100644 --- a/src/core/hle/service/nfc/nfc_interface.cpp +++ b/src/core/hle/service/nfc/nfc_interface.cpp @@ -13,13 +13,18 @@ #include "core/hle/service/nfc/nfc_result.h" #include "core/hle/service/nfc/nfc_types.h" #include "core/hle/service/nfp/nfp_result.h" +#include "core/hle/service/set/system_settings_server.h" +#include "core/hle/service/sm/sm.h" #include "hid_core/hid_types.h" namespace Service::NFC { NfcInterface::NfcInterface(Core::System& system_, const char* name, BackendType service_backend) : ServiceFramework{system_, name}, service_context{system_, service_name}, - backend_type{service_backend} {} + backend_type{service_backend} { + m_set_sys = + system.ServiceManager().GetService<Service::Set::ISystemSettingsServer>("set:sys", true); +} NfcInterface ::~NfcInterface() = default; @@ -65,11 +70,11 @@ void NfcInterface::GetState(HLERequestContext& ctx) { void NfcInterface::IsNfcEnabled(HLERequestContext& ctx) { LOG_DEBUG(Service_NFC, "called"); - // TODO: This calls nn::settings::detail::GetNfcEnableFlag - const bool is_enabled = true; + bool is_enabled{}; + const auto result = m_set_sys->GetNfcEnableFlag(&is_enabled); IPC::ResponseBuilder rb{ctx, 3}; - rb.Push(ResultSuccess); + rb.Push(result); rb.Push(is_enabled); } @@ -212,6 +217,17 @@ void NfcInterface::AttachDeactivateEvent(HLERequestContext& ctx) { rb.PushCopyObjects(out_event); } +void NfcInterface::SetNfcEnabled(HLERequestContext& ctx) { + IPC::RequestParser rp{ctx}; + const auto is_enabled{rp.Pop<bool>()}; + LOG_DEBUG(Service_NFC, "called, is_enabled={}", is_enabled); + + const auto result = m_set_sys->SetNfcEnableFlag(is_enabled); + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(result); +} + void NfcInterface::ReadMifare(HLERequestContext& ctx) { IPC::RequestParser rp{ctx}; const auto device_handle{rp.Pop<u64>()}; diff --git a/src/core/hle/service/nfc/nfc_interface.h b/src/core/hle/service/nfc/nfc_interface.h index 08be174d8..5cc0d8ec0 100644 --- a/src/core/hle/service/nfc/nfc_interface.h +++ b/src/core/hle/service/nfc/nfc_interface.h @@ -7,6 +7,10 @@ #include "core/hle/service/nfc/nfc_types.h" #include "core/hle/service/service.h" +namespace Service::Set { +class ISystemSettingsServer; +} + namespace Service::NFC { class DeviceManager; @@ -29,6 +33,7 @@ public: void AttachActivateEvent(HLERequestContext& ctx); void AttachDeactivateEvent(HLERequestContext& ctx); void ReadMifare(HLERequestContext& ctx); + void SetNfcEnabled(HLERequestContext& ctx); void WriteMifare(HLERequestContext& ctx); void SendCommandByPassThrough(HLERequestContext& ctx); @@ -44,6 +49,7 @@ protected: BackendType backend_type; State state{State::NonInitialized}; std::shared_ptr<DeviceManager> device_manager = nullptr; + std::shared_ptr<Service::Set::ISystemSettingsServer> m_set_sys; }; } // namespace Service::NFC diff --git a/src/core/hle/service/npns/npns.cpp b/src/core/hle/service/npns/npns.cpp index a162e5c54..e54827efe 100644 --- a/src/core/hle/service/npns/npns.cpp +++ b/src/core/hle/service/npns/npns.cpp @@ -3,22 +3,26 @@ #include <memory> +#include "core/hle/kernel/k_event.h" +#include "core/hle/service/cmif_serialization.h" +#include "core/hle/service/kernel_helpers.h" #include "core/hle/service/npns/npns.h" #include "core/hle/service/server_manager.h" #include "core/hle/service/service.h" namespace Service::NPNS { -class NPNS_S final : public ServiceFramework<NPNS_S> { +class INpnsSystem final : public ServiceFramework<INpnsSystem> { public: - explicit NPNS_S(Core::System& system_) : ServiceFramework{system_, "npns:s"} { + explicit INpnsSystem(Core::System& system_) + : ServiceFramework{system_, "npns:s"}, service_context{system, "npns:s"} { // clang-format off static const FunctionInfo functions[] = { {1, nullptr, "ListenAll"}, - {2, nullptr, "ListenTo"}, + {2, C<&INpnsSystem::ListenTo>, "ListenTo"}, {3, nullptr, "Receive"}, {4, nullptr, "ReceiveRaw"}, - {5, nullptr, "GetReceiveEvent"}, + {5, C<&INpnsSystem::GetReceiveEvent>, "GetReceiveEvent"}, {6, nullptr, "ListenUndelivered"}, {7, nullptr, "GetStateChangeEVent"}, {11, nullptr, "SubscribeTopic"}, @@ -59,12 +63,34 @@ public: // clang-format on RegisterHandlers(functions); + + get_receive_event = service_context.CreateEvent("npns:s:GetReceiveEvent"); } + + ~INpnsSystem() override { + service_context.CloseEvent(get_receive_event); + } + +private: + Result ListenTo(u32 program_id) { + LOG_WARNING(Service_AM, "(STUBBED) called, program_id={}", program_id); + R_SUCCEED(); + } + + Result GetReceiveEvent(OutCopyHandle<Kernel::KReadableEvent> out_event) { + LOG_WARNING(Service_AM, "(STUBBED) called"); + + *out_event = &get_receive_event->GetReadableEvent(); + R_SUCCEED(); + } + + KernelHelpers::ServiceContext service_context; + Kernel::KEvent* get_receive_event; }; -class NPNS_U final : public ServiceFramework<NPNS_U> { +class INpnsUser final : public ServiceFramework<INpnsUser> { public: - explicit NPNS_U(Core::System& system_) : ServiceFramework{system_, "npns:u"} { + explicit INpnsUser(Core::System& system_) : ServiceFramework{system_, "npns:u"} { // clang-format off static const FunctionInfo functions[] = { {1, nullptr, "ListenAll"}, @@ -97,8 +123,8 @@ public: void LoopProcess(Core::System& system) { auto server_manager = std::make_unique<ServerManager>(system); - server_manager->RegisterNamedService("npns:s", std::make_shared<NPNS_S>(system)); - server_manager->RegisterNamedService("npns:u", std::make_shared<NPNS_U>(system)); + server_manager->RegisterNamedService("npns:s", std::make_shared<INpnsSystem>(system)); + server_manager->RegisterNamedService("npns:u", std::make_shared<INpnsUser>(system)); ServerManager::RunServer(std::move(server_manager)); } diff --git a/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp b/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp index bf12d69a5..efc9cca1c 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp +++ b/src/core/hle/service/nvdrv/devices/nvhost_gpu.cpp @@ -5,6 +5,7 @@ #include "common/assert.h" #include "common/logging/log.h" #include "core/core.h" +#include "core/hle/kernel/k_process.h" #include "core/hle/service/nvdrv/core/container.h" #include "core/hle/service/nvdrv/core/nvmap.h" #include "core/hle/service/nvdrv/core/syncpoint_manager.h" @@ -75,7 +76,7 @@ NvResult nvhost_gpu::Ioctl1(DeviceFD fd, Ioctl command, std::span<const u8> inpu case 0xd: return WrapFixed(this, &nvhost_gpu::SetChannelPriority, input, output); case 0x1a: - return WrapFixed(this, &nvhost_gpu::AllocGPFIFOEx2, input, output); + return WrapFixed(this, &nvhost_gpu::AllocGPFIFOEx2, input, output, fd); case 0x1b: return WrapFixedVariable(this, &nvhost_gpu::SubmitGPFIFOBase1, input, output, true); case 0x1d: @@ -120,8 +121,13 @@ NvResult nvhost_gpu::Ioctl3(DeviceFD fd, Ioctl command, std::span<const u8> inpu return NvResult::NotImplemented; } -void nvhost_gpu::OnOpen(NvCore::SessionId session_id, DeviceFD fd) {} -void nvhost_gpu::OnClose(DeviceFD fd) {} +void nvhost_gpu::OnOpen(NvCore::SessionId session_id, DeviceFD fd) { + sessions[fd] = session_id; +} + +void nvhost_gpu::OnClose(DeviceFD fd) { + sessions.erase(fd); +} NvResult nvhost_gpu::SetNVMAPfd(IoctlSetNvmapFD& params) { LOG_DEBUG(Service_NVDRV, "called, fd={}", params.nvmap_fd); @@ -161,7 +167,7 @@ NvResult nvhost_gpu::SetChannelPriority(IoctlChannelSetPriority& params) { return NvResult::Success; } -NvResult nvhost_gpu::AllocGPFIFOEx2(IoctlAllocGpfifoEx2& params) { +NvResult nvhost_gpu::AllocGPFIFOEx2(IoctlAllocGpfifoEx2& params, DeviceFD fd) { LOG_WARNING(Service_NVDRV, "(STUBBED) called, num_entries={:X}, flags={:X}, unk0={:X}, " "unk1={:X}, unk2={:X}, unk3={:X}", @@ -173,7 +179,12 @@ NvResult nvhost_gpu::AllocGPFIFOEx2(IoctlAllocGpfifoEx2& params) { return NvResult::AlreadyAllocated; } - system.GPU().InitChannel(*channel_state); + u64 program_id{}; + if (auto* const session = core.GetSession(sessions[fd]); session != nullptr) { + program_id = session->process->GetProgramId(); + } + + system.GPU().InitChannel(*channel_state, program_id); params.fence_out = syncpoint_manager.GetSyncpointFence(channel_syncpoint); diff --git a/src/core/hle/service/nvdrv/devices/nvhost_gpu.h b/src/core/hle/service/nvdrv/devices/nvhost_gpu.h index e34a978db..e0aeef953 100644 --- a/src/core/hle/service/nvdrv/devices/nvhost_gpu.h +++ b/src/core/hle/service/nvdrv/devices/nvhost_gpu.h @@ -192,7 +192,7 @@ private: NvResult ZCullBind(IoctlZCullBind& params); NvResult SetErrorNotifier(IoctlSetErrorNotifier& params); NvResult SetChannelPriority(IoctlChannelSetPriority& params); - NvResult AllocGPFIFOEx2(IoctlAllocGpfifoEx2& params); + NvResult AllocGPFIFOEx2(IoctlAllocGpfifoEx2& params, DeviceFD fd); NvResult AllocateObjectContext(IoctlAllocObjCtx& params); NvResult SubmitGPFIFOImpl(IoctlSubmitGpfifo& params, Tegra::CommandList&& entries); @@ -210,6 +210,7 @@ private: NvCore::SyncpointManager& syncpoint_manager; NvCore::NvMap& nvmap; std::shared_ptr<Tegra::Control::ChannelState> channel_state; + std::unordered_map<DeviceFD, NvCore::SessionId> sessions; u32 channel_syncpoint; std::mutex channel_mutex; diff --git a/src/core/hle/service/server_manager.cpp b/src/core/hle/service/server_manager.cpp index 0b41bbcb9..3d898725e 100644 --- a/src/core/hle/service/server_manager.cpp +++ b/src/core/hle/service/server_manager.cpp @@ -93,13 +93,19 @@ ServerManager::~ServerManager() { m_threads.clear(); // Clean up ports. - for (auto it = m_servers.begin(); it != m_servers.end(); it = m_servers.erase(it)) { - delete std::addressof(*it); + auto port_it = m_servers.begin(); + while (port_it != m_servers.end()) { + auto* const port = std::addressof(*port_it); + port_it = m_servers.erase(port_it); + delete port; } // Clean up sessions. - for (auto it = m_sessions.begin(); it != m_sessions.end(); it = m_sessions.erase(it)) { - delete std::addressof(*it); + auto session_it = m_sessions.begin(); + while (session_it != m_sessions.end()) { + auto* const session = std::addressof(*session_it); + session_it = m_sessions.erase(session_it); + delete session; } // Close wakeup event. diff --git a/src/core/hle/service/services.cpp b/src/core/hle/service/services.cpp index 1aa85ea54..3defa4b31 100644 --- a/src/core/hle/service/services.cpp +++ b/src/core/hle/service/services.cpp @@ -5,7 +5,7 @@ #include "core/hle/service/acc/acc.h" #include "core/hle/service/am/am.h" -#include "core/hle/service/aoc/aoc_u.h" +#include "core/hle/service/aoc/addon_content_manager.h" #include "core/hle/service/apm/apm.h" #include "core/hle/service/audio/audio.h" #include "core/hle/service/bcat/bcat.h" diff --git a/src/core/hle/service/set/setting_formats/system_settings.cpp b/src/core/hle/service/set/setting_formats/system_settings.cpp index 7231ff78e..caa30c2d5 100644 --- a/src/core/hle/service/set/setting_formats/system_settings.cpp +++ b/src/core/hle/service/set/setting_formats/system_settings.cpp @@ -52,6 +52,10 @@ SystemSettings DefaultSystemSettings() { settings.battery_percentage_flag = true; settings.chinese_traditional_input_method = ChineseTraditionalInputMethod::Unknown0; settings.vibration_master_volume = 1.0f; + settings.touch_screen_mode = TouchScreenMode::Standard; + settings.nfc_enable_flag = true; + settings.bluetooth_enable_flag = true; + settings.wireless_lan_enable_flag = true; const auto language_code = available_language_codes[static_cast<s32>(::Settings::values.language_index.GetValue())]; diff --git a/src/core/hle/service/set/settings_types.h b/src/core/hle/service/set/settings_types.h index 29664e88c..92c2948b0 100644 --- a/src/core/hle/service/set/settings_types.h +++ b/src/core/hle/service/set/settings_types.h @@ -243,6 +243,11 @@ enum class TvResolution : u32 { Resolution480p, }; +enum class PlatformRegion : s32 { + Global = 1, + Terra = 2, +}; + constexpr std::array<LanguageCode, 18> available_language_codes = {{ LanguageCode::JA, LanguageCode::EN_US, @@ -405,8 +410,7 @@ struct EulaVersion { SystemRegionCode region_code; EulaVersionClockType clock_type; INSERT_PADDING_BYTES(0x4); - s64 posix_time; - Service::PSC::Time::SteadyClockTimePoint timestamp; + Service::PSC::Time::SystemClockContext system_clock_context; }; static_assert(sizeof(EulaVersion) == 0x30, "EulaVersion is incorrect size"); diff --git a/src/core/hle/service/set/system_settings_server.cpp b/src/core/hle/service/set/system_settings_server.cpp index 93925f783..0dc8db821 100644 --- a/src/core/hle/service/set/system_settings_server.cpp +++ b/src/core/hle/service/set/system_settings_server.cpp @@ -26,7 +26,7 @@ namespace Service::Set { namespace { -constexpr u32 SETTINGS_VERSION{3u}; +constexpr u32 SETTINGS_VERSION{4u}; constexpr auto SETTINGS_MAGIC = Common::MakeMagic('y', 'u', 'z', 'u', '_', 's', 'e', 't'); struct SettingsHeader { u64 magic; @@ -272,8 +272,8 @@ ISystemSettingsServer::ISystemSettingsServer(Core::System& system_) {180, nullptr, "SetZoomFlag"}, {181, nullptr, "GetT"}, {182, nullptr, "SetT"}, - {183, nullptr, "GetPlatformRegion"}, - {184, nullptr, "SetPlatformRegion"}, + {183, C<&ISystemSettingsServer::GetPlatformRegion>, "GetPlatformRegion"}, + {184, C<&ISystemSettingsServer::SetPlatformRegion>, "SetPlatformRegion"}, {185, C<&ISystemSettingsServer::GetHomeMenuSchemeModel>, "GetHomeMenuSchemeModel"}, {186, nullptr, "GetMemoryUsageRateFlag"}, {187, C<&ISystemSettingsServer::GetTouchScreenMode>, "GetTouchScreenMode"}, @@ -306,6 +306,20 @@ ISystemSettingsServer::ISystemSettingsServer(Core::System& system_) RegisterHandlers(functions); SetupSettings(); + + m_system_settings.region_code = + static_cast<SystemRegionCode>(::Settings::values.region_index.GetValue()); + + // TODO: Remove this when starter applet is fully functional + EulaVersion eula_version{ + .version = 0x10000, + .region_code = m_system_settings.region_code, + .clock_type = EulaVersionClockType::SteadyClock, + .system_clock_context = m_system_settings.user_system_clock_context, + }; + m_system_settings.eula_versions[0] = eula_version; + m_system_settings.eula_version_count = 1; + m_save_thread = std::jthread([this](std::stop_token stop_token) { StoreSettingsThreadFunc(stop_token); }); } @@ -701,7 +715,7 @@ Result ISystemSettingsServer::GetSettingsItemValueSize( } Result ISystemSettingsServer::GetSettingsItemValue( - OutBuffer<BufferAttr_HipcMapAlias> out_data, + Out<u64> out_size, OutBuffer<BufferAttr_HipcMapAlias> out_data, InLargeData<SettingItemName, BufferAttr_HipcPointer> setting_category_buffer, InLargeData<SettingItemName, BufferAttr_HipcPointer> setting_name_buffer) { const std::string setting_category{Common::StringFromBuffer(*setting_category_buffer)}; @@ -709,7 +723,7 @@ Result ISystemSettingsServer::GetSettingsItemValue( LOG_INFO(Service_SET, "called, category={}, name={}", setting_category, setting_name); - R_RETURN(GetSettingsItemValueImpl(out_data, setting_category, setting_name)); + R_RETURN(GetSettingsItemValueImpl(out_data, *out_size, setting_category, setting_name)); } Result ISystemSettingsServer::GetTvSettings(Out<TvSettings> out_tv_settings) { @@ -1236,6 +1250,18 @@ Result ISystemSettingsServer::GetHomeMenuScheme(Out<HomeMenuScheme> out_home_men R_SUCCEED(); } +Result ISystemSettingsServer::GetPlatformRegion(Out<PlatformRegion> out_platform_region) { + LOG_WARNING(Service_SET, "(STUBBED) called"); + + *out_platform_region = PlatformRegion::Global; + R_SUCCEED(); +} + +Result ISystemSettingsServer::SetPlatformRegion(PlatformRegion platform_region) { + LOG_WARNING(Service_SET, "(STUBBED) called"); + R_SUCCEED(); +} + Result ISystemSettingsServer::GetHomeMenuSchemeModel(Out<u32> out_home_menu_scheme_model) { LOG_WARNING(Service_SET, "(STUBBED) called"); @@ -1349,13 +1375,16 @@ void ISystemSettingsServer::SetSaveNeeded() { m_save_needed = true; } -Result ISystemSettingsServer::GetSettingsItemValueImpl(std::vector<u8>& out_value, +Result ISystemSettingsServer::GetSettingsItemValueImpl(std::span<u8> out_value, u64& out_size, const std::string& category, const std::string& name) { auto settings{GetSettings()}; R_UNLESS(settings.contains(category) && settings[category].contains(name), ResultUnknown); - out_value = settings[category][name]; + ASSERT_MSG(out_value.size() >= settings[category][name].size(), + "Stored type is bigger than requested type"); + out_size = std::min<u64>(settings[category][name].size(), out_value.size()); + std::memcpy(out_value.data(), settings[category][name].data(), out_size); R_SUCCEED(); } diff --git a/src/core/hle/service/set/system_settings_server.h b/src/core/hle/service/set/system_settings_server.h index 46e06c8ea..993e5de7d 100644 --- a/src/core/hle/service/set/system_settings_server.h +++ b/src/core/hle/service/set/system_settings_server.h @@ -34,20 +34,17 @@ public: explicit ISystemSettingsServer(Core::System& system_); ~ISystemSettingsServer() override; - Result GetSettingsItemValueImpl(std::vector<u8>& out_value, const std::string& category, - const std::string& name); + Result GetSettingsItemValueImpl(std::span<u8> out_value, u64& out_size, + const std::string& category, const std::string& name); template <typename T> - Result GetSettingsItemValueImpl(T& value, const std::string& category, + Result GetSettingsItemValueImpl(T& out_value, const std::string& category, const std::string& name) { - std::vector<u8> data; - const auto result = GetSettingsItemValueImpl(data, category, name); - if (result.IsError()) { - return result; - } - ASSERT(data.size() >= sizeof(T)); - std::memcpy(&value, data.data(), sizeof(T)); - return result; + u64 data_size{}; + std::vector<u8> data(sizeof(T)); + R_TRY(GetSettingsItemValueImpl(data, data_size, category, name)); + std::memcpy(&out_value, data.data(), data_size); + R_SUCCEED(); } public: @@ -84,7 +81,7 @@ public: InLargeData<SettingItemName, BufferAttr_HipcPointer> setting_category_buffer, InLargeData<SettingItemName, BufferAttr_HipcPointer> setting_name_buf); Result GetSettingsItemValue( - OutBuffer<BufferAttr_HipcMapAlias> out_data, + Out<u64> out_size, OutBuffer<BufferAttr_HipcMapAlias> out_data, InLargeData<SettingItemName, BufferAttr_HipcPointer> setting_category_buffer, InLargeData<SettingItemName, BufferAttr_HipcPointer> setting_name_buffer); Result GetTvSettings(Out<TvSettings> out_tv_settings); @@ -152,6 +149,8 @@ public: Result GetHomeMenuScheme(Out<HomeMenuScheme> out_home_menu_scheme); Result GetHomeMenuSchemeModel(Out<u32> out_home_menu_scheme_model); Result GetTouchScreenMode(Out<TouchScreenMode> out_touch_screen_mode); + Result GetPlatformRegion(Out<PlatformRegion> out_platform_region); + Result SetPlatformRegion(PlatformRegion platform_region); Result SetTouchScreenMode(TouchScreenMode touch_screen_mode); Result GetFieldTestingFlag(Out<bool> out_field_testing_flag); Result GetPanelCrcMode(Out<s32> out_panel_crc_mode); diff --git a/src/core/hle/service/ssl/cert_store.cpp b/src/core/hle/service/ssl/cert_store.cpp new file mode 100644 index 000000000..b321e5d32 --- /dev/null +++ b/src/core/hle/service/ssl/cert_store.cpp @@ -0,0 +1,156 @@ +// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "common/alignment.h" +#include "core/core.h" +#include "core/file_sys/content_archive.h" +#include "core/file_sys/nca_metadata.h" +#include "core/file_sys/registered_cache.h" +#include "core/file_sys/romfs.h" +#include "core/hle/service/filesystem/filesystem.h" +#include "core/hle/service/ssl/cert_store.h" + +namespace Service::SSL { + +// https://switchbrew.org/wiki/SSL_services#CertStore + +CertStore::CertStore(Core::System& system) { + constexpr u64 CertStoreDataId = 0x0100000000000800ULL; + + auto& fsc = system.GetFileSystemController(); + + // Attempt to load certificate data from storage + const auto nca = + fsc.GetSystemNANDContents()->GetEntry(CertStoreDataId, FileSys::ContentRecordType::Data); + if (!nca) { + return; + } + const auto romfs = nca->GetRomFS(); + if (!romfs) { + return; + } + const auto extracted = FileSys::ExtractRomFS(romfs); + if (!extracted) { + LOG_ERROR(Service_SSL, "CertStore could not be extracted, corrupt RomFS?"); + return; + } + const auto cert_store_file = extracted->GetFile("ssl_TrustedCerts.bdf"); + if (!cert_store_file) { + LOG_ERROR(Service_SSL, "Failed to find trusted certificates in CertStore"); + return; + } + + // Read and verify the header. + CertStoreHeader header; + cert_store_file->ReadObject(std::addressof(header)); + + if (header.magic != Common::MakeMagic('s', 's', 'l', 'T')) { + LOG_ERROR(Service_SSL, "Invalid certificate store magic"); + return; + } + + // Ensure the file can contains the number of entries it says it does. + const u64 expected_size = sizeof(header) + sizeof(CertStoreEntry) * header.num_entries; + const u64 actual_size = cert_store_file->GetSize(); + if (actual_size < expected_size) { + LOG_ERROR(Service_SSL, "Size mismatch, expected at least {} bytes, got {}", expected_size, + actual_size); + return; + } + + // Read entries. + std::vector<CertStoreEntry> entries(header.num_entries); + cert_store_file->ReadArray(entries.data(), header.num_entries, sizeof(header)); + + // Insert into memory store. + for (const auto& entry : entries) { + m_certs.emplace(entry.certificate_id, + Certificate{ + .status = entry.certificate_status, + .der_data = cert_store_file->ReadBytes( + entry.der_size, entry.der_offset + sizeof(header)), + }); + } +} + +CertStore::~CertStore() = default; + +template <typename F> +void CertStore::ForEachCertificate(std::span<const CaCertificateId> certificate_ids, F&& f) { + if (certificate_ids.size() == 1 && certificate_ids.front() == CaCertificateId::All) { + for (const auto& entry : m_certs) { + f(entry); + } + } else { + for (const auto certificate_id : certificate_ids) { + const auto entry = m_certs.find(certificate_id); + if (entry == m_certs.end()) { + continue; + } + f(*entry); + } + } +} + +Result CertStore::GetCertificates(u32* out_num_entries, std::span<u8> out_data, + std::span<const CaCertificateId> certificate_ids) { + // Ensure the buffer is large enough to hold the output. + u32 required_size; + R_TRY(this->GetCertificateBufSize(std::addressof(required_size), out_num_entries, + certificate_ids)); + R_UNLESS(out_data.size_bytes() >= required_size, ResultUnknown); + + // Make parallel arrays. + std::vector<BuiltInCertificateInfo> cert_infos; + std::vector<u8> der_datas; + + const u32 der_data_offset = (*out_num_entries + 1) * sizeof(BuiltInCertificateInfo); + u32 cur_der_offset = der_data_offset; + + // Fill output. + this->ForEachCertificate(certificate_ids, [&](auto& entry) { + const auto& [status, cur_der_data] = entry.second; + BuiltInCertificateInfo cert_info{ + .cert_id = entry.first, + .status = status, + .der_size = cur_der_data.size(), + .der_offset = cur_der_offset, + }; + + cert_infos.push_back(cert_info); + der_datas.insert(der_datas.end(), cur_der_data.begin(), cur_der_data.end()); + cur_der_offset += static_cast<u32>(cur_der_data.size()); + }); + + // Append terminator entry. + cert_infos.push_back(BuiltInCertificateInfo{ + .cert_id = CaCertificateId::All, + .status = TrustedCertStatus::Invalid, + .der_size = 0, + .der_offset = 0, + }); + + // Write to output span. + std::memcpy(out_data.data(), cert_infos.data(), + cert_infos.size() * sizeof(BuiltInCertificateInfo)); + std::memcpy(out_data.data() + der_data_offset, der_datas.data(), der_datas.size()); + + R_SUCCEED(); +} + +Result CertStore::GetCertificateBufSize(u32* out_size, u32* out_num_entries, + std::span<const CaCertificateId> certificate_ids) { + // Output size is at least the size of the terminator entry. + *out_size = sizeof(BuiltInCertificateInfo); + *out_num_entries = 0; + + this->ForEachCertificate(certificate_ids, [&](auto& entry) { + *out_size += sizeof(BuiltInCertificateInfo); + *out_size += Common::AlignUp(static_cast<u32>(entry.second.der_data.size()), 4); + (*out_num_entries)++; + }); + + R_SUCCEED(); +} + +} // namespace Service::SSL diff --git a/src/core/hle/service/ssl/cert_store.h b/src/core/hle/service/ssl/cert_store.h new file mode 100644 index 000000000..613d7b02a --- /dev/null +++ b/src/core/hle/service/ssl/cert_store.h @@ -0,0 +1,42 @@ +// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include <map> +#include <span> +#include <vector> + +#include "core/hle/result.h" +#include "core/hle/service/ssl/ssl_types.h" + +namespace Core { +class System; +} + +namespace Service::SSL { + +class CertStore { +public: + explicit CertStore(Core::System& system); + ~CertStore(); + + Result GetCertificates(u32* out_num_entries, std::span<u8> out_data, + std::span<const CaCertificateId> certificate_ids); + Result GetCertificateBufSize(u32* out_size, u32* out_num_entries, + std::span<const CaCertificateId> certificate_ids); + +private: + template <typename F> + void ForEachCertificate(std::span<const CaCertificateId> certs, F&& f); + +private: + struct Certificate { + TrustedCertStatus status; + std::vector<u8> der_data; + }; + + std::map<CaCertificateId, Certificate> m_certs; +}; + +} // namespace Service::SSL diff --git a/src/core/hle/service/ssl/ssl.cpp b/src/core/hle/service/ssl/ssl.cpp index 0fbb43057..008ee4492 100644 --- a/src/core/hle/service/ssl/ssl.cpp +++ b/src/core/hle/service/ssl/ssl.cpp @@ -5,11 +5,13 @@ #include "core/core.h" #include "core/hle/result.h" +#include "core/hle/service/cmif_serialization.h" #include "core/hle/service/ipc_helpers.h" #include "core/hle/service/server_manager.h" #include "core/hle/service/service.h" #include "core/hle/service/sm/sm.h" #include "core/hle/service/sockets/bsd.h" +#include "core/hle/service/ssl/cert_store.h" #include "core/hle/service/ssl/ssl.h" #include "core/hle/service/ssl/ssl_backend.h" #include "core/internal_network/network.h" @@ -492,13 +494,14 @@ private: class ISslService final : public ServiceFramework<ISslService> { public: - explicit ISslService(Core::System& system_) : ServiceFramework{system_, "ssl"} { + explicit ISslService(Core::System& system_) + : ServiceFramework{system_, "ssl"}, cert_store{system} { // clang-format off static const FunctionInfo functions[] = { {0, &ISslService::CreateContext, "CreateContext"}, {1, nullptr, "GetContextCount"}, - {2, nullptr, "GetCertificates"}, - {3, nullptr, "GetCertificateBufSize"}, + {2, D<&ISslService::GetCertificates>, "GetCertificates"}, + {3, D<&ISslService::GetCertificateBufSize>, "GetCertificateBufSize"}, {4, nullptr, "DebugIoctl"}, {5, &ISslService::SetInterfaceVersion, "SetInterfaceVersion"}, {6, nullptr, "FlushSessionCache"}, @@ -540,6 +543,22 @@ private: IPC::ResponseBuilder rb{ctx, 2}; rb.Push(ResultSuccess); } + + Result GetCertificateBufSize( + Out<u32> out_size, InArray<CaCertificateId, BufferAttr_HipcMapAlias> certificate_ids) { + LOG_INFO(Service_SSL, "called"); + u32 num_entries; + R_RETURN(cert_store.GetCertificateBufSize(out_size, &num_entries, certificate_ids)); + } + + Result GetCertificates(Out<u32> out_num_entries, OutBuffer<BufferAttr_HipcMapAlias> out_buffer, + InArray<CaCertificateId, BufferAttr_HipcMapAlias> certificate_ids) { + LOG_INFO(Service_SSL, "called"); + R_RETURN(cert_store.GetCertificates(out_num_entries, out_buffer, certificate_ids)); + } + +private: + CertStore cert_store; }; void LoopProcess(Core::System& system) { diff --git a/src/core/hle/service/ssl/ssl_types.h b/src/core/hle/service/ssl/ssl_types.h new file mode 100644 index 000000000..dbc3dbf64 --- /dev/null +++ b/src/core/hle/service/ssl/ssl_types.h @@ -0,0 +1,107 @@ +// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include "common/common_types.h" + +namespace Service::SSL { + +enum class CaCertificateId : s32 { + All = -1, + NintendoCAG3 = 1, + NintendoClass2CAG3 = 2, + NintendoRootCAG4 = 3, + AmazonRootCA1 = 1000, + StarfieldServicesRootCertificateAuthorityG2 = 1001, + AddTrustExternalCARoot = 1002, + COMODOCertificationAuthority = 1003, + UTNDATACorpSGC = 1004, + UTNUSERFirstHardware = 1005, + BaltimoreCyberTrustRoot = 1006, + CybertrustGlobalRoot = 1007, + VerizonGlobalRootCA = 1008, + DigiCertAssuredIDRootCA = 1009, + DigiCertAssuredIDRootG2 = 1010, + DigiCertGlobalRootCA = 1011, + DigiCertGlobalRootG2 = 1012, + DigiCertHighAssuranceEVRootCA = 1013, + EntrustnetCertificationAuthority2048 = 1014, + EntrustRootCertificationAuthority = 1015, + EntrustRootCertificationAuthorityG2 = 1016, + GeoTrustGlobalCA2 = 1017, + GeoTrustGlobalCA = 1018, + GeoTrustPrimaryCertificationAuthorityG3 = 1019, + GeoTrustPrimaryCertificationAuthority = 1020, + GlobalSignRootCA = 1021, + GlobalSignRootCAR2 = 1022, + GlobalSignRootCAR3 = 1023, + GoDaddyClass2CertificationAuthority = 1024, + GoDaddyRootCertificateAuthorityG2 = 1025, + StarfieldClass2CertificationAuthority = 1026, + StarfieldRootCertificateAuthorityG2 = 1027, + thawtePrimaryRootCAG3 = 1028, + thawtePrimaryRootCA = 1029, + VeriSignClass3PublicPrimaryCertificationAuthorityG3 = 1030, + VeriSignClass3PublicPrimaryCertificationAuthorityG5 = 1031, + VeriSignUniversalRootCertificationAuthority = 1032, + DSTRootCAX3 = 1033, + USERTrustRsaCertificationAuthority = 1034, + ISRGRootX10 = 1035, + USERTrustEccCertificationAuthority = 1036, + COMODORsaCertificationAuthority = 1037, + COMODOEccCertificationAuthority = 1038, + AmazonRootCA2 = 1039, + AmazonRootCA3 = 1040, + AmazonRootCA4 = 1041, + DigiCertAssuredIDRootG3 = 1042, + DigiCertGlobalRootG3 = 1043, + DigiCertTrustedRootG4 = 1044, + EntrustRootCertificationAuthorityEC1 = 1045, + EntrustRootCertificationAuthorityG4 = 1046, + GlobalSignECCRootCAR4 = 1047, + GlobalSignECCRootCAR5 = 1048, + GlobalSignECCRootCAR6 = 1049, + GTSRootR1 = 1050, + GTSRootR2 = 1051, + GTSRootR3 = 1052, + GTSRootR4 = 1053, + SecurityCommunicationRootCA = 1054, + GlobalSignRootE4 = 1055, + GlobalSignRootR4 = 1056, + TTeleSecGlobalRootClass2 = 1057, + DigiCertTLSECCP384RootG5 = 1058, + DigiCertTLSRSA4096RootG5 = 1059, +}; + +enum class TrustedCertStatus : s32 { + Invalid = -1, + Removed = 0, + EnabledTrusted = 1, + EnabledNotTrusted = 2, + Revoked = 3, +}; + +struct BuiltInCertificateInfo { + CaCertificateId cert_id; + TrustedCertStatus status; + u64 der_size; + u64 der_offset; +}; +static_assert(sizeof(BuiltInCertificateInfo) == 0x18, "BuiltInCertificateInfo has incorrect size."); + +struct CertStoreHeader { + u32 magic; + u32 num_entries; +}; +static_assert(sizeof(CertStoreHeader) == 0x8, "CertStoreHeader has incorrect size."); + +struct CertStoreEntry { + CaCertificateId certificate_id; + TrustedCertStatus certificate_status; + u32 der_size; + u32 der_offset; +}; +static_assert(sizeof(CertStoreEntry) == 0x10, "CertStoreEntry has incorrect size."); + +} // namespace Service::SSL |