// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later #include "common/logging/log.h" #include "common/settings.h" #include "core/arm/debug.h" #include "core/core.h" #include "core/file_sys/control_metadata.h" #include "core/file_sys/patch_manager.h" #include "core/file_sys/vfs/vfs.h" #include "core/hle/service/filesystem/filesystem.h" #include "core/hle/service/glue/glue_manager.h" #include "core/hle/service/ipc_helpers.h" #include "core/hle/service/ns/account_proxy_interface.h" #include "core/hle/service/ns/application_version_interface.h" #include "core/hle/service/ns/content_management_interface.h" #include "core/hle/service/ns/ecommerce_interface.h" #include "core/hle/service/ns/factory_reset_interface.h" #include "core/hle/service/ns/language.h" #include "core/hle/service/ns/ns.h" #include "core/hle/service/ns/ns_results.h" #include "core/hle/service/ns/pdm_qry.h" #include "core/hle/service/ns/platform_service_manager.h" #include "core/hle/service/server_manager.h" #include "core/hle/service/set/settings_server.h" namespace Service::NS { IApplicationManagerInterface::IApplicationManagerInterface(Core::System& system_) : ServiceFramework{system_, "IApplicationManagerInterface"} { // clang-format off static const FunctionInfo functions[] = { {0, nullptr, "ListApplicationRecord"}, {1, nullptr, "GenerateApplicationRecordCount"}, {2, nullptr, "GetApplicationRecordUpdateSystemEvent"}, {3, nullptr, "GetApplicationViewDeprecated"}, {4, nullptr, "DeleteApplicationEntity"}, {5, nullptr, "DeleteApplicationCompletely"}, {6, nullptr, "IsAnyApplicationEntityRedundant"}, {7, nullptr, "DeleteRedundantApplicationEntity"}, {8, nullptr, "IsApplicationEntityMovable"}, {9, nullptr, "MoveApplicationEntity"}, {11, nullptr, "CalculateApplicationOccupiedSize"}, {16, nullptr, "PushApplicationRecord"}, {17, nullptr, "ListApplicationRecordContentMeta"}, {19, nullptr, "LaunchApplicationOld"}, {21, nullptr, "GetApplicationContentPath"}, {22, nullptr, "TerminateApplication"}, {23, nullptr, "ResolveApplicationContentPath"}, {26, nullptr, "BeginInstallApplication"}, {27, nullptr, "DeleteApplicationRecord"}, {30, nullptr, "RequestApplicationUpdateInfo"}, {31, nullptr, "Unknown31"}, {32, nullptr, "CancelApplicationDownload"}, {33, nullptr, "ResumeApplicationDownload"}, {35, nullptr, "UpdateVersionList"}, {36, nullptr, "PushLaunchVersion"}, {37, nullptr, "ListRequiredVersion"}, {38, nullptr, "CheckApplicationLaunchVersion"}, {39, nullptr, "CheckApplicationLaunchRights"}, {40, nullptr, "GetApplicationLogoData"}, {41, nullptr, "CalculateApplicationDownloadRequiredSize"}, {42, nullptr, "CleanupSdCard"}, {43, nullptr, "CheckSdCardMountStatus"}, {44, nullptr, "GetSdCardMountStatusChangedEvent"}, {45, nullptr, "GetGameCardAttachmentEvent"}, {46, nullptr, "GetGameCardAttachmentInfo"}, {47, nullptr, "GetTotalSpaceSize"}, {48, nullptr, "GetFreeSpaceSize"}, {49, nullptr, "GetSdCardRemovedEvent"}, {52, nullptr, "GetGameCardUpdateDetectionEvent"}, {53, nullptr, "DisableApplicationAutoDelete"}, {54, nullptr, "EnableApplicationAutoDelete"}, {55, &IApplicationManagerInterface::GetApplicationDesiredLanguage, "GetApplicationDesiredLanguage"}, {56, nullptr, "SetApplicationTerminateResult"}, {57, nullptr, "ClearApplicationTerminateResult"}, {58, nullptr, "GetLastSdCardMountUnexpectedResult"}, {59, &IApplicationManagerInterface::ConvertApplicationLanguageToLanguageCode, "ConvertApplicationLanguageToLanguageCode"}, {60, nullptr, "ConvertLanguageCodeToApplicationLanguage"}, {61, nullptr, "GetBackgroundDownloadStressTaskInfo"}, {62, nullptr, "GetGameCardStopper"}, {63, nullptr, "IsSystemProgramInstalled"}, {64, nullptr, "StartApplyDeltaTask"}, {65, nullptr, "GetRequestServerStopper"}, {66, nullptr, "GetBackgroundApplyDeltaStressTaskInfo"}, {67, nullptr, "CancelApplicationApplyDelta"}, {68, nullptr, "ResumeApplicationApplyDelta"}, {69, nullptr, "CalculateApplicationApplyDeltaRequiredSize"}, {70, nullptr, "ResumeAll"}, {71, nullptr, "GetStorageSize"}, {80, nullptr, "RequestDownloadApplication"}, {81, nullptr, "RequestDownloadAddOnContent"}, {82, nullptr, "DownloadApplication"}, {83, nullptr, "CheckApplicationResumeRights"}, {84, nullptr, "GetDynamicCommitEvent"}, {85, nullptr, "RequestUpdateApplication2"}, {86, nullptr, "EnableApplicationCrashReport"}, {87, nullptr, "IsApplicationCrashReportEnabled"}, {90, nullptr, "BoostSystemMemoryResourceLimit"}, {91, nullptr, "DeprecatedLaunchApplication"}, {92, nullptr, "GetRunningApplicationProgramId"}, {93, nullptr, "GetMainApplicationProgramIndex"}, {94, nullptr, "LaunchApplication"}, {95, nullptr, "GetApplicationLaunchInfo"}, {96, nullptr, "AcquireApplicationLaunchInfo"}, {97, nullptr, "GetMainApplicationProgramIndexByApplicationLaunchInfo"}, {98, nullptr, "EnableApplicationAllThreadDumpOnCrash"}, {99, nullptr, "LaunchDevMenu"}, {100, nullptr, "ResetToFactorySettings"}, {101, nullptr, "ResetToFactorySettingsWithoutUserSaveData"}, {102, nullptr, "ResetToFactorySettingsForRefurbishment"}, {103, nullptr, "ResetToFactorySettingsWithPlatformRegion"}, {104, nullptr, "ResetToFactorySettingsWithPlatformRegionAuthentication"}, {105, nullptr, "RequestResetToFactorySettingsSecurely"}, {106, nullptr, "RequestResetToFactorySettingsWithPlatformRegionAuthenticationSecurely"}, {200, nullptr, "CalculateUserSaveDataStatistics"}, {201, nullptr, "DeleteUserSaveDataAll"}, {210, nullptr, "DeleteUserSystemSaveData"}, {211, nullptr, "DeleteSaveData"}, {220, nullptr, "UnregisterNetworkServiceAccount"}, {221, nullptr, "UnregisterNetworkServiceAccountWithUserSaveDataDeletion"}, {300, nullptr, "GetApplicationShellEvent"}, {301, nullptr, "PopApplicationShellEventInfo"}, {302, nullptr, "LaunchLibraryApplet"}, {303, nullptr, "TerminateLibraryApplet"}, {304, nullptr, "LaunchSystemApplet"}, {305, nullptr, "TerminateSystemApplet"}, {306, nullptr, "LaunchOverlayApplet"}, {307, nullptr, "TerminateOverlayApplet"}, {400, &IApplicationManagerInterface::GetApplicationControlData, "GetApplicationControlData"}, {401, nullptr, "InvalidateAllApplicationControlCache"}, {402, nullptr, "RequestDownloadApplicationControlData"}, {403, nullptr, "GetMaxApplicationControlCacheCount"}, {404, nullptr, "InvalidateApplicationControlCache"}, {405, nullptr, "ListApplicationControlCacheEntryInfo"}, {406, nullptr, "GetApplicationControlProperty"}, {407, nullptr, "ListApplicationTitle"}, {408, nullptr, "ListApplicationIcon"}, {502, nullptr, "RequestCheckGameCardRegistration"}, {503, nullptr, "RequestGameCardRegistrationGoldPoint"}, {504, nullptr, "RequestRegisterGameCard"}, {505, nullptr, "GetGameCardMountFailureEvent"}, {506, nullptr, "IsGameCardInserted"}, {507, nullptr, "EnsureGameCardAccess"}, {508, nullptr, "GetLastGameCardMountFailureResult"}, {509, nullptr, "ListApplicationIdOnGameCard"}, {510, nullptr, "GetGameCardPlatformRegion"}, {600, nullptr, "CountApplicationContentMeta"}, {601, nullptr, "ListApplicationContentMetaStatus"}, {602, nullptr, "ListAvailableAddOnContent"}, {603, nullptr, "GetOwnedApplicationContentMetaStatus"}, {604, nullptr, "RegisterContentsExternalKey"}, {605, nullptr, "ListApplicationContentMetaStatusWithRightsCheck"}, {606, nullptr, "GetContentMetaStorage"}, {607, nullptr, "ListAvailableAddOnContent"}, {609, nullptr, "ListAvailabilityAssuredAddOnContent"}, {610, nullptr, "GetInstalledContentMetaStorage"}, {611, nullptr, "PrepareAddOnContent"}, {700, nullptr, "PushDownloadTaskList"}, {701, nullptr, "ClearTaskStatusList"}, {702, nullptr, "RequestDownloadTaskList"}, {703, nullptr, "RequestEnsureDownloadTask"}, {704, nullptr, "ListDownloadTaskStatus"}, {705, nullptr, "RequestDownloadTaskListData"}, {800, nullptr, "RequestVersionList"}, {801, nullptr, "ListVersionList"}, {802, nullptr, "RequestVersionListData"}, {900, nullptr, "GetApplicationRecord"}, {901, nullptr, "GetApplicationRecordProperty"}, {902, nullptr, "EnableApplicationAutoUpdate"}, {903, nullptr, "DisableApplicationAutoUpdate"}, {904, nullptr, "TouchApplication"}, {905, nullptr, "RequestApplicationUpdate"}, {906, nullptr, "IsApplicationUpdateRequested"}, {907, nullptr, "WithdrawApplicationUpdateRequest"}, {908, nullptr, "ListApplicationRecordInstalledContentMeta"}, {909, nullptr, "WithdrawCleanupAddOnContentsWithNoRightsRecommendation"}, {910, nullptr, "HasApplicationRecord"}, {911, nullptr, "SetPreInstalledApplication"}, {912, nullptr, "ClearPreInstalledApplicationFlag"}, {913, nullptr, "ListAllApplicationRecord"}, {914, nullptr, "HideApplicationRecord"}, {915, nullptr, "ShowApplicationRecord"}, {916, nullptr, "IsApplicationAutoDeleteDisabled"}, {1000, nullptr, "RequestVerifyApplicationDeprecated"}, {1001, nullptr, "CorruptApplicationForDebug"}, {1002, nullptr, "RequestVerifyAddOnContentsRights"}, {1003, nullptr, "RequestVerifyApplication"}, {1004, nullptr, "CorruptContentForDebug"}, {1200, nullptr, "NeedsUpdateVulnerability"}, {1300, nullptr, "IsAnyApplicationEntityInstalled"}, {1301, nullptr, "DeleteApplicationContentEntities"}, {1302, nullptr, "CleanupUnrecordedApplicationEntity"}, {1303, nullptr, "CleanupAddOnContentsWithNoRights"}, {1304, nullptr, "DeleteApplicationContentEntity"}, {1305, nullptr, "TryDeleteRunningApplicationEntity"}, {1306, nullptr, "TryDeleteRunningApplicationCompletely"}, {1307, nullptr, "TryDeleteRunningApplicationContentEntities"}, {1308, nullptr, "DeleteApplicationCompletelyForDebug"}, {1309, nullptr, "CleanupUnavailableAddOnContents"}, {1310, nullptr, "RequestMoveApplicationEntity"}, {1311, nullptr, "EstimateSizeToMove"}, {1312, nullptr, "HasMovableEntity"}, {1313, nullptr, "CleanupOrphanContents"}, {1314, nullptr, "CheckPreconditionSatisfiedToMove"}, {1400, nullptr, "PrepareShutdown"}, {1500, nullptr, "FormatSdCard"}, {1501, nullptr, "NeedsSystemUpdateToFormatSdCard"}, {1502, nullptr, "GetLastSdCardFormatUnexpectedResult"}, {1504, nullptr, "InsertSdCard"}, {1505, nullptr, "RemoveSdCard"}, {1506, nullptr, "GetSdCardStartupStatus"}, {1600, nullptr, "GetSystemSeedForPseudoDeviceId"}, {1601, nullptr, "ResetSystemSeedForPseudoDeviceId"}, {1700, nullptr, "ListApplicationDownloadingContentMeta"}, {1701, nullptr, "GetApplicationView"}, {1702, nullptr, "GetApplicationDownloadTaskStatus"}, {1703, nullptr, "GetApplicationViewDownloadErrorContext"}, {1704, nullptr, "GetApplicationViewWithPromotionInfo"}, {1705, nullptr, "IsPatchAutoDeletableApplication"}, {1800, nullptr, "IsNotificationSetupCompleted"}, {1801, nullptr, "GetLastNotificationInfoCount"}, {1802, nullptr, "ListLastNotificationInfo"}, {1803, nullptr, "ListNotificationTask"}, {1900, nullptr, "IsActiveAccount"}, {1901, nullptr, "RequestDownloadApplicationPrepurchasedRights"}, {1902, nullptr, "GetApplicationTicketInfo"}, {1903, nullptr, "RequestDownloadApplicationPrepurchasedRightsForAccount"}, {2000, nullptr, "GetSystemDeliveryInfo"}, {2001, nullptr, "SelectLatestSystemDeliveryInfo"}, {2002, nullptr, "VerifyDeliveryProtocolVersion"}, {2003, nullptr, "GetApplicationDeliveryInfo"}, {2004, nullptr, "HasAllContentsToDeliver"}, {2005, nullptr, "CompareApplicationDeliveryInfo"}, {2006, nullptr, "CanDeliverApplication"}, {2007, nullptr, "ListContentMetaKeyToDeliverApplication"}, {2008, nullptr, "NeedsSystemUpdateToDeliverApplication"}, {2009, nullptr, "EstimateRequiredSize"}, {2010, nullptr, "RequestReceiveApplication"}, {2011, nullptr, "CommitReceiveApplication"}, {2012, nullptr, "GetReceiveApplicationProgress"}, {2013, nullptr, "RequestSendApplication"}, {2014, nullptr, "GetSendApplicationProgress"}, {2015, nullptr, "CompareSystemDeliveryInfo"}, {2016, nullptr, "ListNotCommittedContentMeta"}, {2017, nullptr, "CreateDownloadTask"}, {2018, nullptr, "GetApplicationDeliveryInfoHash"}, {2050, nullptr, "GetApplicationRightsOnClient"}, {2051, nullptr, "InvalidateRightsIdCache"}, {2100, nullptr, "GetApplicationTerminateResult"}, {2101, nullptr, "GetRawApplicationTerminateResult"}, {2150, nullptr, "CreateRightsEnvironment"}, {2151, nullptr, "DestroyRightsEnvironment"}, {2152, nullptr, "ActivateRightsEnvironment"}, {2153, nullptr, "DeactivateRightsEnvironment"}, {2154, nullptr, "ForceActivateRightsContextForExit"}, {2155, nullptr, "UpdateRightsEnvironmentStatus"}, {2156, nullptr, "CreateRightsEnvironmentForMicroApplication"}, {2160, nullptr, "AddTargetApplicationToRightsEnvironment"}, {2161, nullptr, "SetUsersToRightsEnvironment"}, {2170, nullptr, "GetRightsEnvironmentStatus"}, {2171, nullptr, "GetRightsEnvironmentStatusChangedEvent"}, {2180, nullptr, "RequestExtendRightsInRightsEnvironment"}, {2181, nullptr, "GetResultOfExtendRightsInRightsEnvironment"}, {2182, nullptr, "SetActiveRightsContextUsingStateToRightsEnvironment"}, {2190, nullptr, "GetRightsEnvironmentHandleForApplication"}, {2199, nullptr, "GetRightsEnvironmentCountForDebug"}, {2200, nullptr, "GetGameCardApplicationCopyIdentifier"}, {2201, nullptr, "GetInstalledApplicationCopyIdentifier"}, {2250, nullptr, "RequestReportActiveELicence"}, {2300, nullptr, "ListEventLog"}, {2350, nullptr, "PerformAutoUpdateByApplicationId"}, {2351, nullptr, "RequestNoDownloadRightsErrorResolution"}, {2352, nullptr, "RequestResolveNoDownloadRightsError"}, {2353, nullptr, "GetApplicationDownloadTaskInfo"}, {2354, nullptr, "PrioritizeApplicationBackgroundTask"}, {2355, nullptr, "PreferStorageEfficientUpdate"}, {2356, nullptr, "RequestStorageEfficientUpdatePreferable"}, {2357, nullptr, "EnableMultiCoreDownload"}, {2358, nullptr, "DisableMultiCoreDownload"}, {2359, nullptr, "IsMultiCoreDownloadEnabled"}, {2400, nullptr, "GetPromotionInfo"}, {2401, nullptr, "CountPromotionInfo"}, {2402, nullptr, "ListPromotionInfo"}, {2403, nullptr, "ImportPromotionJsonForDebug"}, {2404, nullptr, "ClearPromotionInfoForDebug"}, {2500, nullptr, "ConfirmAvailableTime"}, {2510, nullptr, "CreateApplicationResource"}, {2511, nullptr, "GetApplicationResource"}, {2513, nullptr, "LaunchMicroApplication"}, {2514, nullptr, "ClearTaskOfAsyncTaskManager"}, {2515, nullptr, "CleanupAllPlaceHolderAndFragmentsIfNoTask"}, {2516, nullptr, "EnsureApplicationCertificate"}, {2517, nullptr, "CreateApplicationInstance"}, {2518, nullptr, "UpdateQualificationForDebug"}, {2519, nullptr, "IsQualificationTransitionSupported"}, {2520, nullptr, "IsQualificationTransitionSupportedByProcessId"}, {2521, nullptr, "GetRightsUserChangedEvent"}, {2522, nullptr, "IsRomRedirectionAvailable"}, {2800, nullptr, "GetApplicationIdOfPreomia"}, {3000, nullptr, "RegisterDeviceLockKey"}, {3001, nullptr, "UnregisterDeviceLockKey"}, {3002, nullptr, "VerifyDeviceLockKey"}, {3003, nullptr, "HideApplicationIcon"}, {3004, nullptr, "ShowApplicationIcon"}, {3005, nullptr, "HideApplicationTitle"}, {3006, nullptr, "ShowApplicationTitle"}, {3007, nullptr, "EnableGameCard"}, {3008, nullptr, "DisableGameCard"}, {3009, nullptr, "EnableLocalContentShare"}, {3010, nullptr, "DisableLocalContentShare"}, {3011, nullptr, "IsApplicationIconHidden"}, {3012, nullptr, "IsApplicationTitleHidden"}, {3013, nullptr, "IsGameCardEnabled"}, {3014, nullptr, "IsLocalContentShareEnabled"}, {3050, nullptr, "ListAssignELicenseTaskResult"}, {9999, nullptr, "GetApplicationCertificate"}, }; // clang-format on RegisterHandlers(functions); } IApplicationManagerInterface::~IApplicationManagerInterface() = default; void IApplicationManagerInterface::GetApplicationControlData(HLERequestContext& ctx) { IPC::RequestParser rp{ctx}; const auto flag = rp.PopRaw(); LOG_DEBUG(Service_NS, "called with flag={:016X}", flag); const auto title_id = rp.PopRaw(); const auto size = ctx.GetWriteBufferSize(); const FileSys::PatchManager pm{title_id, system.GetFileSystemController(), system.GetContentProvider()}; const auto control = pm.GetControlMetadata(); std::vector out; if (control.first != nullptr) { if (size < 0x4000) { LOG_ERROR(Service_NS, "output buffer is too small! (actual={:016X}, expected_min=0x4000)", size); IPC::ResponseBuilder rb{ctx, 2}; // TODO(DarkLordZach): Find a better error code for this. rb.Push(ResultUnknown); return; } out.resize(0x4000); const auto bytes = control.first->GetRawBytes(); std::memcpy(out.data(), bytes.data(), bytes.size()); } else { LOG_WARNING(Service_NS, "missing NACP data for title_id={:016X}, defaulting to zeros.", title_id); out.resize(std::min(0x4000, size)); } if (control.second != nullptr) { if (size < 0x4000 + control.second->GetSize()) { LOG_ERROR(Service_NS, "output buffer is too small! (actual={:016X}, expected_min={:016X})", size, 0x4000 + control.second->GetSize()); IPC::ResponseBuilder rb{ctx, 2}; // TODO(DarkLordZach): Find a better error code for this. rb.Push(ResultUnknown); return; } out.resize(0x4000 + control.second->GetSize()); control.second->Read(out.data() + 0x4000, control.second->GetSize()); } else { LOG_WARNING(Service_NS, "missing icon data for title_id={:016X}, defaulting to zeros.", title_id); } ctx.WriteBuffer(out); IPC::ResponseBuilder rb{ctx, 3}; rb.Push(ResultSuccess); rb.Push(static_cast(out.size())); } void IApplicationManagerInterface::GetApplicationDesiredLanguage(HLERequestContext& ctx) { IPC::RequestParser rp{ctx}; const auto supported_languages = rp.Pop(); u8 desired_language{}; const auto res = GetApplicationDesiredLanguage(&desired_language, supported_languages); if (res == ResultSuccess) { IPC::ResponseBuilder rb{ctx, 3}; rb.Push(ResultSuccess); rb.Push(desired_language); } else { IPC::ResponseBuilder rb{ctx, 2}; rb.Push(res); } } Result IApplicationManagerInterface::GetApplicationDesiredLanguage(u8* out_desired_language, const u32 supported_languages) { LOG_DEBUG(Service_NS, "called with supported_languages={:08X}", supported_languages); // Get language code from settings const auto language_code = Set::GetLanguageCodeFromIndex(static_cast(Settings::values.language_index.GetValue())); // Convert to application language, get priority list const auto application_language = ConvertToApplicationLanguage(language_code); if (application_language == std::nullopt) { LOG_ERROR(Service_NS, "Could not convert application language! language_code={}", language_code); return Service::NS::ResultApplicationLanguageNotFound; } const auto priority_list = GetApplicationLanguagePriorityList(*application_language); if (!priority_list) { LOG_ERROR(Service_NS, "Could not find application language priorities! application_language={}", *application_language); return Service::NS::ResultApplicationLanguageNotFound; } // Try to find a valid language. for (const auto lang : *priority_list) { const auto supported_flag = GetSupportedLanguageFlag(lang); if (supported_languages == 0 || (supported_languages & supported_flag) == supported_flag) { *out_desired_language = static_cast(lang); return ResultSuccess; } } LOG_ERROR(Service_NS, "Could not find a valid language! supported_languages={:08X}", supported_languages); return Service::NS::ResultApplicationLanguageNotFound; } void IApplicationManagerInterface::ConvertApplicationLanguageToLanguageCode( HLERequestContext& ctx) { IPC::RequestParser rp{ctx}; const auto application_language = rp.Pop(); u64 language_code{}; const auto res = ConvertApplicationLanguageToLanguageCode(&language_code, application_language); if (res == ResultSuccess) { IPC::ResponseBuilder rb{ctx, 4}; rb.Push(ResultSuccess); rb.Push(language_code); } else { IPC::ResponseBuilder rb{ctx, 2}; rb.Push(res); } } Result IApplicationManagerInterface::ConvertApplicationLanguageToLanguageCode( u64* out_language_code, u8 application_language) { const auto language_code = ConvertToLanguageCode(static_cast(application_language)); if (language_code == std::nullopt) { LOG_ERROR(Service_NS, "Language not found! application_language={}", application_language); return Service::NS::ResultApplicationLanguageNotFound; } *out_language_code = static_cast(*language_code); return ResultSuccess; } IDocumentInterface::IDocumentInterface(Core::System& system_) : ServiceFramework{system_, "IDocumentInterface"} { // clang-format off static const FunctionInfo functions[] = { {21, nullptr, "GetApplicationContentPath"}, {23, &IDocumentInterface::ResolveApplicationContentPath, "ResolveApplicationContentPath"}, {92, &IDocumentInterface::GetRunningApplicationProgramId, "GetRunningApplicationProgramId"}, }; // clang-format on RegisterHandlers(functions); } IDocumentInterface::~IDocumentInterface() = default; void IDocumentInterface::ResolveApplicationContentPath(HLERequestContext& ctx) { struct ContentPath { u8 file_system_proxy_type; u64 program_id; }; static_assert(sizeof(ContentPath) == 0x10, "ContentPath has wrong size"); IPC::RequestParser rp{ctx}; auto content_path = rp.PopRaw(); LOG_WARNING(Service_NS, "(STUBBED) called, file_system_proxy_type={}, program_id={:016X}", content_path.file_system_proxy_type, content_path.program_id); IPC::ResponseBuilder rb{ctx, 2}; rb.Push(ResultSuccess); } void IDocumentInterface::GetRunningApplicationProgramId(HLERequestContext& ctx) { IPC::RequestParser rp{ctx}; const auto caller_program_id = rp.PopRaw(); LOG_WARNING(Service_NS, "(STUBBED) called, caller_program_id={:016X}", caller_program_id); IPC::ResponseBuilder rb{ctx, 4}; rb.Push(ResultSuccess); rb.Push(system.GetApplicationProcessProgramID()); } IDownloadTaskInterface::IDownloadTaskInterface(Core::System& system_) : ServiceFramework{system_, "IDownloadTaskInterface"} { // clang-format off static const FunctionInfo functions[] = { {701, nullptr, "ClearTaskStatusList"}, {702, nullptr, "RequestDownloadTaskList"}, {703, nullptr, "RequestEnsureDownloadTask"}, {704, nullptr, "ListDownloadTaskStatus"}, {705, nullptr, "RequestDownloadTaskListData"}, {706, nullptr, "TryCommitCurrentApplicationDownloadTask"}, {707, nullptr, "EnableAutoCommit"}, {708, nullptr, "DisableAutoCommit"}, {709, nullptr, "TriggerDynamicCommitEvent"}, }; // clang-format on RegisterHandlers(functions); } IDownloadTaskInterface::~IDownloadTaskInterface() = default; IReadOnlyApplicationRecordInterface::IReadOnlyApplicationRecordInterface(Core::System& system_) : ServiceFramework{system_, "IReadOnlyApplicationRecordInterface"} { static const FunctionInfo functions[] = { {0, &IReadOnlyApplicationRecordInterface::HasApplicationRecord, "HasApplicationRecord"}, {1, nullptr, "NotifyApplicationFailure"}, {2, &IReadOnlyApplicationRecordInterface::IsDataCorruptedResult, "IsDataCorruptedResult"}, }; // clang-format on RegisterHandlers(functions); } IReadOnlyApplicationRecordInterface::~IReadOnlyApplicationRecordInterface() = default; void IReadOnlyApplicationRecordInterface::HasApplicationRecord(HLERequestContext& ctx) { IPC::RequestParser rp{ctx}; const u64 program_id = rp.PopRaw(); LOG_WARNING(Service_NS, "(STUBBED) called, program_id={:X}", program_id); IPC::ResponseBuilder rb{ctx, 3}; rb.Push(ResultSuccess); rb.Push(1); } void IReadOnlyApplicationRecordInterface::IsDataCorruptedResult(HLERequestContext& ctx) { IPC::RequestParser rp{ctx}; const auto result = rp.PopRaw(); LOG_WARNING(Service_NS, "(STUBBED) called, result={:#x}", result.GetInnerValue()); IPC::ResponseBuilder rb{ctx, 3}; rb.Push(ResultSuccess); rb.Push(0); } IReadOnlyApplicationControlDataInterface::IReadOnlyApplicationControlDataInterface( Core::System& system_) : ServiceFramework{system_, "IReadOnlyApplicationControlDataInterface"} { // clang-format off static const FunctionInfo functions[] = { {0, &IReadOnlyApplicationControlDataInterface::GetApplicationControlData, "GetApplicationControlData"}, {1, nullptr, "GetApplicationDesiredLanguage"}, {2, nullptr, "ConvertApplicationLanguageToLanguageCode"}, {3, nullptr, "ConvertLanguageCodeToApplicationLanguage"}, {4, nullptr, "SelectApplicationDesiredLanguage"}, }; // clang-format on RegisterHandlers(functions); } IReadOnlyApplicationControlDataInterface::~IReadOnlyApplicationControlDataInterface() = default; void IReadOnlyApplicationControlDataInterface::GetApplicationControlData(HLERequestContext& ctx) { enum class ApplicationControlSource : u8 { CacheOnly, Storage, StorageOnly, }; struct RequestParameters { ApplicationControlSource source; u64 application_id; }; static_assert(sizeof(RequestParameters) == 0x10, "RequestParameters has incorrect size."); IPC::RequestParser rp{ctx}; std::vector nacp_data{}; const auto parameters{rp.PopRaw()}; const auto result = system.GetARPManager().GetControlProperty(&nacp_data, parameters.application_id); if (result == ResultSuccess) { ctx.WriteBuffer(nacp_data.data(), nacp_data.size()); } IPC::ResponseBuilder rb{ctx, 2}; rb.Push(result); } NS::NS(const char* name, Core::System& system_) : ServiceFramework{system_, name} { // clang-format off static const FunctionInfo functions[] = { {7988, nullptr, "GetDynamicRightsInterface"}, {7989, &NS::PushInterface, "GetReadOnlyApplicationControlDataInterface"}, {7991, &NS::PushInterface, "GetReadOnlyApplicationRecordInterface"}, {7992, &NS::PushInterface, "GetECommerceInterface"}, {7993, &NS::PushInterface, "GetApplicationVersionInterface"}, {7994, &NS::PushInterface, "GetFactoryResetInterface"}, {7995, &NS::PushInterface, "GetAccountProxyInterface"}, {7996, &NS::PushIApplicationManagerInterface, "GetApplicationManagerInterface"}, {7997, &NS::PushInterface, "GetDownloadTaskInterface"}, {7998, &NS::PushInterface, "GetContentManagementInterface"}, {7999, &NS::PushInterface, "GetDocumentInterface"}, }; // clang-format on RegisterHandlers(functions); } NS::~NS() = default; std::shared_ptr NS::GetApplicationManagerInterface() const { return GetInterface(system); } class NS_DEV final : public ServiceFramework { public: explicit NS_DEV(Core::System& system_) : ServiceFramework{system_, "ns:dev"} { // clang-format off static const FunctionInfo functions[] = { {0, nullptr, "LaunchProgram"}, {1, nullptr, "TerminateProcess"}, {2, nullptr, "TerminateProgram"}, {4, nullptr, "GetShellEvent"}, {5, nullptr, "GetShellEventInfo"}, {6, nullptr, "TerminateApplication"}, {7, nullptr, "PrepareLaunchProgramFromHost"}, {8, nullptr, "LaunchApplicationFromHost"}, {9, nullptr, "LaunchApplicationWithStorageIdForDevelop"}, {10, nullptr, "IsSystemMemoryResourceLimitBoosted"}, {11, nullptr, "GetRunningApplicationProcessIdForDevelop"}, {12, nullptr, "SetCurrentApplicationRightsEnvironmentCanBeActiveForDevelop"}, {13, nullptr, "CreateApplicationResourceForDevelop"}, {14, nullptr, "IsPreomiaForDevelop"}, {15, nullptr, "GetApplicationProgramIdFromHost"}, {16, nullptr, "RefreshCachedDebugValues"}, {17, nullptr, "PrepareLaunchApplicationFromHost"}, {18, nullptr, "GetLaunchEvent"}, {19, nullptr, "GetLaunchResult"}, }; // clang-format on RegisterHandlers(functions); } }; class ISystemUpdateControl final : public ServiceFramework { public: explicit ISystemUpdateControl(Core::System& system_) : ServiceFramework{system_, "ISystemUpdateControl"} { // clang-format off static const FunctionInfo functions[] = { {0, nullptr, "HasDownloaded"}, {1, nullptr, "RequestCheckLatestUpdate"}, {2, nullptr, "RequestDownloadLatestUpdate"}, {3, nullptr, "GetDownloadProgress"}, {4, nullptr, "ApplyDownloadedUpdate"}, {5, nullptr, "RequestPrepareCardUpdate"}, {6, nullptr, "GetPrepareCardUpdateProgress"}, {7, nullptr, "HasPreparedCardUpdate"}, {8, nullptr, "ApplyCardUpdate"}, {9, nullptr, "GetDownloadedEulaDataSize"}, {10, nullptr, "GetDownloadedEulaData"}, {11, nullptr, "SetupCardUpdate"}, {12, nullptr, "GetPreparedCardUpdateEulaDataSize"}, {13, nullptr, "GetPreparedCardUpdateEulaData"}, {14, nullptr, "SetupCardUpdateViaSystemUpdater"}, {15, nullptr, "HasReceived"}, {16, nullptr, "RequestReceiveSystemUpdate"}, {17, nullptr, "GetReceiveProgress"}, {18, nullptr, "ApplyReceivedUpdate"}, {19, nullptr, "GetReceivedEulaDataSize"}, {20, nullptr, "GetReceivedEulaData"}, {21, nullptr, "SetupToReceiveSystemUpdate"}, {22, nullptr, "RequestCheckLatestUpdateIncludesRebootlessUpdate"}, }; // clang-format on RegisterHandlers(functions); } }; class NS_SU final : public ServiceFramework { public: explicit NS_SU(Core::System& system_) : ServiceFramework{system_, "ns:su"} { // clang-format off static const FunctionInfo functions[] = { {0, nullptr, "GetBackgroundNetworkUpdateState"}, {1, &NS_SU::OpenSystemUpdateControl, "OpenSystemUpdateControl"}, {2, nullptr, "NotifyExFatDriverRequired"}, {3, nullptr, "ClearExFatDriverStatusForDebug"}, {4, nullptr, "RequestBackgroundNetworkUpdate"}, {5, nullptr, "NotifyBackgroundNetworkUpdate"}, {6, nullptr, "NotifyExFatDriverDownloadedForDebug"}, {9, nullptr, "GetSystemUpdateNotificationEventForContentDelivery"}, {10, nullptr, "NotifySystemUpdateForContentDelivery"}, {11, nullptr, "PrepareShutdown"}, {12, nullptr, "Unknown12"}, {13, nullptr, "Unknown13"}, {14, nullptr, "Unknown14"}, {15, nullptr, "Unknown15"}, {16, nullptr, "DestroySystemUpdateTask"}, {17, nullptr, "RequestSendSystemUpdate"}, {18, nullptr, "GetSendSystemUpdateProgress"}, }; // clang-format on RegisterHandlers(functions); } private: void OpenSystemUpdateControl(HLERequestContext& ctx) { LOG_DEBUG(Service_NS, "called"); IPC::ResponseBuilder rb{ctx, 2, 0, 1}; rb.Push(ResultSuccess); rb.PushIpcInterface(system); } }; class NS_VM final : public ServiceFramework { public: explicit NS_VM(Core::System& system_) : ServiceFramework{system_, "ns:vm"} { // clang-format off static const FunctionInfo functions[] = { {1200, &NS_VM::NeedsUpdateVulnerability, "NeedsUpdateVulnerability"}, {1201, nullptr, "UpdateSafeSystemVersionForDebug"}, {1202, nullptr, "GetSafeSystemVersion"}, }; // clang-format on RegisterHandlers(functions); } private: void NeedsUpdateVulnerability(HLERequestContext& ctx) { LOG_WARNING(Service_NS, "(STUBBED) called"); IPC::ResponseBuilder rb{ctx, 3}; rb.Push(ResultSuccess); rb.Push(false); } }; void LoopProcess(Core::System& system) { auto server_manager = std::make_unique(system); server_manager->RegisterNamedService("ns:am2", std::make_shared("ns:am2", system)); server_manager->RegisterNamedService("ns:ec", std::make_shared("ns:ec", system)); server_manager->RegisterNamedService("ns:rid", std::make_shared("ns:rid", system)); server_manager->RegisterNamedService("ns:rt", std::make_shared("ns:rt", system)); server_manager->RegisterNamedService("ns:web", std::make_shared("ns:web", system)); server_manager->RegisterNamedService("ns:ro", std::make_shared("ns:ro", system)); server_manager->RegisterNamedService("ns:dev", std::make_shared(system)); server_manager->RegisterNamedService("ns:su", std::make_shared(system)); server_manager->RegisterNamedService("ns:vm", std::make_shared(system)); server_manager->RegisterNamedService("pdm:qry", std::make_shared(system)); server_manager->RegisterNamedService("pl:s", std::make_shared(system, "pl:s")); server_manager->RegisterNamedService("pl:u", std::make_shared(system, "pl:u")); ServerManager::RunServer(std::move(server_manager)); } } // namespace Service::NS