early-access version 1255

This commit is contained in:
pineappleEA
2020-12-28 15:15:37 +00:00
parent 84b39492d1
commit 78b48028e1
6254 changed files with 1868140 additions and 0 deletions

View File

@@ -0,0 +1,12 @@
// Copyright 2019 yuzu emulator team
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#pragma once
#include "core/hle/result.h"
namespace Service::NS {
constexpr ResultCode ERR_APPLICATION_LANGUAGE_NOT_FOUND{ErrorModule::NS, 300};
}

View File

@@ -0,0 +1,392 @@
// Copyright 2019 yuzu emulator team
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#include "core/hle/service/ns/language.h"
#include "core/hle/service/set/set.h"
namespace Service::NS {
constexpr ApplicationLanguagePriorityList priority_list_american_english = {{
ApplicationLanguage::AmericanEnglish,
ApplicationLanguage::BritishEnglish,
ApplicationLanguage::LatinAmericanSpanish,
ApplicationLanguage::CanadianFrench,
ApplicationLanguage::French,
ApplicationLanguage::German,
ApplicationLanguage::Spanish,
ApplicationLanguage::Italian,
ApplicationLanguage::Dutch,
ApplicationLanguage::Portuguese,
ApplicationLanguage::Russian,
ApplicationLanguage::Japanese,
ApplicationLanguage::SimplifiedChinese,
ApplicationLanguage::TraditionalChinese,
ApplicationLanguage::Korean,
}};
constexpr ApplicationLanguagePriorityList priority_list_british_english = {{
ApplicationLanguage::BritishEnglish,
ApplicationLanguage::AmericanEnglish,
ApplicationLanguage::French,
ApplicationLanguage::German,
ApplicationLanguage::Spanish,
ApplicationLanguage::Italian,
ApplicationLanguage::Dutch,
ApplicationLanguage::Portuguese,
ApplicationLanguage::Russian,
ApplicationLanguage::LatinAmericanSpanish,
ApplicationLanguage::CanadianFrench,
ApplicationLanguage::Japanese,
ApplicationLanguage::SimplifiedChinese,
ApplicationLanguage::TraditionalChinese,
ApplicationLanguage::Korean,
}};
constexpr ApplicationLanguagePriorityList priority_list_japanese = {{
ApplicationLanguage::Japanese,
ApplicationLanguage::AmericanEnglish,
ApplicationLanguage::BritishEnglish,
ApplicationLanguage::LatinAmericanSpanish,
ApplicationLanguage::CanadianFrench,
ApplicationLanguage::French,
ApplicationLanguage::German,
ApplicationLanguage::Spanish,
ApplicationLanguage::Italian,
ApplicationLanguage::Dutch,
ApplicationLanguage::Portuguese,
ApplicationLanguage::Russian,
ApplicationLanguage::SimplifiedChinese,
ApplicationLanguage::TraditionalChinese,
ApplicationLanguage::Korean,
}};
constexpr ApplicationLanguagePriorityList priority_list_french = {{
ApplicationLanguage::French,
ApplicationLanguage::CanadianFrench,
ApplicationLanguage::BritishEnglish,
ApplicationLanguage::AmericanEnglish,
ApplicationLanguage::German,
ApplicationLanguage::Spanish,
ApplicationLanguage::Italian,
ApplicationLanguage::Dutch,
ApplicationLanguage::Portuguese,
ApplicationLanguage::Russian,
ApplicationLanguage::LatinAmericanSpanish,
ApplicationLanguage::Japanese,
ApplicationLanguage::SimplifiedChinese,
ApplicationLanguage::TraditionalChinese,
ApplicationLanguage::Korean,
}};
constexpr ApplicationLanguagePriorityList priority_list_german = {{
ApplicationLanguage::German,
ApplicationLanguage::BritishEnglish,
ApplicationLanguage::AmericanEnglish,
ApplicationLanguage::French,
ApplicationLanguage::Spanish,
ApplicationLanguage::Italian,
ApplicationLanguage::Dutch,
ApplicationLanguage::Portuguese,
ApplicationLanguage::Russian,
ApplicationLanguage::LatinAmericanSpanish,
ApplicationLanguage::CanadianFrench,
ApplicationLanguage::Japanese,
ApplicationLanguage::SimplifiedChinese,
ApplicationLanguage::TraditionalChinese,
ApplicationLanguage::Korean,
}};
constexpr ApplicationLanguagePriorityList priority_list_latin_american_spanish = {{
ApplicationLanguage::LatinAmericanSpanish,
ApplicationLanguage::Spanish,
ApplicationLanguage::AmericanEnglish,
ApplicationLanguage::BritishEnglish,
ApplicationLanguage::Portuguese,
ApplicationLanguage::CanadianFrench,
ApplicationLanguage::French,
ApplicationLanguage::Italian,
ApplicationLanguage::German,
ApplicationLanguage::Dutch,
ApplicationLanguage::Russian,
ApplicationLanguage::Japanese,
ApplicationLanguage::SimplifiedChinese,
ApplicationLanguage::TraditionalChinese,
ApplicationLanguage::Korean,
}};
constexpr ApplicationLanguagePriorityList priority_list_spanish = {{
ApplicationLanguage::Spanish,
ApplicationLanguage::LatinAmericanSpanish,
ApplicationLanguage::BritishEnglish,
ApplicationLanguage::AmericanEnglish,
ApplicationLanguage::French,
ApplicationLanguage::German,
ApplicationLanguage::Italian,
ApplicationLanguage::Dutch,
ApplicationLanguage::Portuguese,
ApplicationLanguage::Russian,
ApplicationLanguage::CanadianFrench,
ApplicationLanguage::Japanese,
ApplicationLanguage::SimplifiedChinese,
ApplicationLanguage::TraditionalChinese,
ApplicationLanguage::Korean,
}};
constexpr ApplicationLanguagePriorityList priority_list_italian = {{
ApplicationLanguage::Italian,
ApplicationLanguage::BritishEnglish,
ApplicationLanguage::AmericanEnglish,
ApplicationLanguage::French,
ApplicationLanguage::German,
ApplicationLanguage::Spanish,
ApplicationLanguage::Dutch,
ApplicationLanguage::Portuguese,
ApplicationLanguage::Russian,
ApplicationLanguage::LatinAmericanSpanish,
ApplicationLanguage::CanadianFrench,
ApplicationLanguage::Japanese,
ApplicationLanguage::SimplifiedChinese,
ApplicationLanguage::TraditionalChinese,
ApplicationLanguage::Korean,
}};
constexpr ApplicationLanguagePriorityList priority_list_dutch = {{
ApplicationLanguage::Dutch,
ApplicationLanguage::BritishEnglish,
ApplicationLanguage::AmericanEnglish,
ApplicationLanguage::French,
ApplicationLanguage::German,
ApplicationLanguage::Spanish,
ApplicationLanguage::Italian,
ApplicationLanguage::Portuguese,
ApplicationLanguage::Russian,
ApplicationLanguage::LatinAmericanSpanish,
ApplicationLanguage::CanadianFrench,
ApplicationLanguage::Japanese,
ApplicationLanguage::SimplifiedChinese,
ApplicationLanguage::TraditionalChinese,
ApplicationLanguage::Korean,
}};
constexpr ApplicationLanguagePriorityList priority_list_canadian_french = {{
ApplicationLanguage::CanadianFrench,
ApplicationLanguage::French,
ApplicationLanguage::AmericanEnglish,
ApplicationLanguage::BritishEnglish,
ApplicationLanguage::LatinAmericanSpanish,
ApplicationLanguage::Spanish,
ApplicationLanguage::German,
ApplicationLanguage::Italian,
ApplicationLanguage::Dutch,
ApplicationLanguage::Portuguese,
ApplicationLanguage::Russian,
ApplicationLanguage::Japanese,
ApplicationLanguage::SimplifiedChinese,
ApplicationLanguage::TraditionalChinese,
ApplicationLanguage::Korean,
}};
constexpr ApplicationLanguagePriorityList priority_list_portuguese = {{
ApplicationLanguage::Portuguese,
ApplicationLanguage::BritishEnglish,
ApplicationLanguage::AmericanEnglish,
ApplicationLanguage::French,
ApplicationLanguage::German,
ApplicationLanguage::Spanish,
ApplicationLanguage::Italian,
ApplicationLanguage::Dutch,
ApplicationLanguage::Russian,
ApplicationLanguage::LatinAmericanSpanish,
ApplicationLanguage::CanadianFrench,
ApplicationLanguage::Japanese,
ApplicationLanguage::SimplifiedChinese,
ApplicationLanguage::TraditionalChinese,
ApplicationLanguage::Korean,
}};
constexpr ApplicationLanguagePriorityList priority_list_russian = {{
ApplicationLanguage::Russian,
ApplicationLanguage::BritishEnglish,
ApplicationLanguage::AmericanEnglish,
ApplicationLanguage::French,
ApplicationLanguage::German,
ApplicationLanguage::Spanish,
ApplicationLanguage::Italian,
ApplicationLanguage::Dutch,
ApplicationLanguage::Portuguese,
ApplicationLanguage::LatinAmericanSpanish,
ApplicationLanguage::CanadianFrench,
ApplicationLanguage::Japanese,
ApplicationLanguage::SimplifiedChinese,
ApplicationLanguage::TraditionalChinese,
ApplicationLanguage::Korean,
}};
constexpr ApplicationLanguagePriorityList priority_list_korean = {{
ApplicationLanguage::Korean,
ApplicationLanguage::AmericanEnglish,
ApplicationLanguage::BritishEnglish,
ApplicationLanguage::LatinAmericanSpanish,
ApplicationLanguage::CanadianFrench,
ApplicationLanguage::French,
ApplicationLanguage::German,
ApplicationLanguage::Spanish,
ApplicationLanguage::Italian,
ApplicationLanguage::Dutch,
ApplicationLanguage::Portuguese,
ApplicationLanguage::Russian,
ApplicationLanguage::Japanese,
ApplicationLanguage::SimplifiedChinese,
ApplicationLanguage::TraditionalChinese,
}};
constexpr ApplicationLanguagePriorityList priority_list_traditional_chinese = {{
ApplicationLanguage::TraditionalChinese,
ApplicationLanguage::SimplifiedChinese,
ApplicationLanguage::AmericanEnglish,
ApplicationLanguage::BritishEnglish,
ApplicationLanguage::Japanese,
ApplicationLanguage::LatinAmericanSpanish,
ApplicationLanguage::CanadianFrench,
ApplicationLanguage::French,
ApplicationLanguage::German,
ApplicationLanguage::Spanish,
ApplicationLanguage::Italian,
ApplicationLanguage::Dutch,
ApplicationLanguage::Portuguese,
ApplicationLanguage::Russian,
ApplicationLanguage::Korean,
}};
constexpr ApplicationLanguagePriorityList priority_list_simplified_chinese = {{
ApplicationLanguage::SimplifiedChinese,
ApplicationLanguage::TraditionalChinese,
ApplicationLanguage::AmericanEnglish,
ApplicationLanguage::BritishEnglish,
ApplicationLanguage::Japanese,
ApplicationLanguage::LatinAmericanSpanish,
ApplicationLanguage::CanadianFrench,
ApplicationLanguage::French,
ApplicationLanguage::German,
ApplicationLanguage::Spanish,
ApplicationLanguage::Italian,
ApplicationLanguage::Dutch,
ApplicationLanguage::Portuguese,
ApplicationLanguage::Russian,
ApplicationLanguage::Korean,
}};
const ApplicationLanguagePriorityList* GetApplicationLanguagePriorityList(
const ApplicationLanguage lang) {
switch (lang) {
case ApplicationLanguage::AmericanEnglish:
return &priority_list_american_english;
case ApplicationLanguage::BritishEnglish:
return &priority_list_british_english;
case ApplicationLanguage::Japanese:
return &priority_list_japanese;
case ApplicationLanguage::French:
return &priority_list_french;
case ApplicationLanguage::German:
return &priority_list_german;
case ApplicationLanguage::LatinAmericanSpanish:
return &priority_list_latin_american_spanish;
case ApplicationLanguage::Spanish:
return &priority_list_spanish;
case ApplicationLanguage::Italian:
return &priority_list_italian;
case ApplicationLanguage::Dutch:
return &priority_list_dutch;
case ApplicationLanguage::CanadianFrench:
return &priority_list_canadian_french;
case ApplicationLanguage::Portuguese:
return &priority_list_portuguese;
case ApplicationLanguage::Russian:
return &priority_list_russian;
case ApplicationLanguage::Korean:
return &priority_list_korean;
case ApplicationLanguage::TraditionalChinese:
return &priority_list_traditional_chinese;
case ApplicationLanguage::SimplifiedChinese:
return &priority_list_simplified_chinese;
default:
return nullptr;
}
}
std::optional<ApplicationLanguage> ConvertToApplicationLanguage(
const Set::LanguageCode language_code) {
switch (language_code) {
case Set::LanguageCode::EN_US:
return ApplicationLanguage::AmericanEnglish;
case Set::LanguageCode::EN_GB:
return ApplicationLanguage::BritishEnglish;
case Set::LanguageCode::JA:
return ApplicationLanguage::Japanese;
case Set::LanguageCode::FR:
return ApplicationLanguage::French;
case Set::LanguageCode::DE:
return ApplicationLanguage::German;
case Set::LanguageCode::ES_419:
return ApplicationLanguage::LatinAmericanSpanish;
case Set::LanguageCode::ES:
return ApplicationLanguage::Spanish;
case Set::LanguageCode::IT:
return ApplicationLanguage::Italian;
case Set::LanguageCode::NL:
return ApplicationLanguage::Dutch;
case Set::LanguageCode::FR_CA:
return ApplicationLanguage::CanadianFrench;
case Set::LanguageCode::PT:
return ApplicationLanguage::Portuguese;
case Set::LanguageCode::RU:
return ApplicationLanguage::Russian;
case Set::LanguageCode::KO:
return ApplicationLanguage::Korean;
case Set::LanguageCode::ZH_HANT:
return ApplicationLanguage::TraditionalChinese;
case Set::LanguageCode::ZH_HANS:
return ApplicationLanguage::SimplifiedChinese;
default:
return std::nullopt;
}
}
std::optional<Set::LanguageCode> ConvertToLanguageCode(const ApplicationLanguage lang) {
switch (lang) {
case ApplicationLanguage::AmericanEnglish:
return Set::LanguageCode::EN_US;
case ApplicationLanguage::BritishEnglish:
return Set::LanguageCode::EN_GB;
case ApplicationLanguage::Japanese:
return Set::LanguageCode::JA;
case ApplicationLanguage::French:
return Set::LanguageCode::FR;
case ApplicationLanguage::German:
return Set::LanguageCode::DE;
case ApplicationLanguage::LatinAmericanSpanish:
return Set::LanguageCode::ES_419;
case ApplicationLanguage::Spanish:
return Set::LanguageCode::ES;
case ApplicationLanguage::Italian:
return Set::LanguageCode::IT;
case ApplicationLanguage::Dutch:
return Set::LanguageCode::NL;
case ApplicationLanguage::CanadianFrench:
return Set::LanguageCode::FR_CA;
case ApplicationLanguage::Portuguese:
return Set::LanguageCode::PT;
case ApplicationLanguage::Russian:
return Set::LanguageCode::RU;
case ApplicationLanguage::Korean:
return Set::LanguageCode::KO;
case ApplicationLanguage::TraditionalChinese:
return Set::LanguageCode::ZH_HANT;
case ApplicationLanguage::SimplifiedChinese:
return Set::LanguageCode::ZH_HANS;
default:
return std::nullopt;
}
}
} // namespace Service::NS

View File

@@ -0,0 +1,45 @@
// Copyright 2019 yuzu emulator team
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#pragma once
#include <optional>
#include <string>
#include "common/common_types.h"
namespace Service::Set {
enum class LanguageCode : u64;
}
namespace Service::NS {
/// This is nn::ns::detail::ApplicationLanguage
enum class ApplicationLanguage : u8 {
AmericanEnglish = 0,
BritishEnglish,
Japanese,
French,
German,
LatinAmericanSpanish,
Spanish,
Italian,
Dutch,
CanadianFrench,
Portuguese,
Russian,
Korean,
TraditionalChinese,
SimplifiedChinese,
Count
};
using ApplicationLanguagePriorityList =
const std::array<ApplicationLanguage, static_cast<std::size_t>(ApplicationLanguage::Count)>;
constexpr u32 GetSupportedLanguageFlag(const ApplicationLanguage lang) {
return 1U << static_cast<u32>(lang);
}
const ApplicationLanguagePriorityList* GetApplicationLanguagePriorityList(ApplicationLanguage lang);
std::optional<ApplicationLanguage> ConvertToApplicationLanguage(Set::LanguageCode language_code);
std::optional<Set::LanguageCode> ConvertToLanguageCode(ApplicationLanguage lang);
} // namespace Service::NS

710
src/core/hle/service/ns/ns.cpp Executable file
View File

@@ -0,0 +1,710 @@
// Copyright 2018 yuzu emulator team
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#include "common/logging/log.h"
#include "core/core.h"
#include "core/file_sys/control_metadata.h"
#include "core/file_sys/patch_manager.h"
#include "core/file_sys/vfs.h"
#include "core/hle/ipc_helpers.h"
#include "core/hle/kernel/hle_ipc.h"
#include "core/hle/service/ns/errors.h"
#include "core/hle/service/ns/language.h"
#include "core/hle/service/ns/ns.h"
#include "core/hle/service/ns/pl_u.h"
#include "core/hle/service/set/set.h"
#include "core/settings.h"
namespace Service::NS {
IAccountProxyInterface::IAccountProxyInterface(Core::System& system_)
: ServiceFramework{system_, "IAccountProxyInterface"} {
// clang-format off
static const FunctionInfo functions[] = {
{0, nullptr, "CreateUserAccount"},
};
// clang-format on
RegisterHandlers(functions);
}
IAccountProxyInterface::~IAccountProxyInterface() = default;
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"},
{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"},
{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"},
{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"},
{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"},
{1800, nullptr, "IsNotificationSetupCompleted"},
{1801, nullptr, "GetLastNotificationInfoCount"},
{1802, nullptr, "ListLastNotificationInfo"},
{1803, nullptr, "ListNotificationTask"},
{1900, nullptr, "IsActiveAccount"},
{1901, nullptr, "RequestDownloadApplicationPrepurchasedRights"},
{1902, nullptr, "GetApplicationTicketInfo"},
{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"},
{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"},
{2800, nullptr, "GetApplicationIdOfPreomia"},
{9999, nullptr, "GetApplicationCertificate"},
};
// clang-format on
RegisterHandlers(functions);
}
IApplicationManagerInterface::~IApplicationManagerInterface() = default;
void IApplicationManagerInterface::GetApplicationControlData(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
const auto flag = rp.PopRaw<u64>();
LOG_DEBUG(Service_NS, "called with flag={:016X}", flag);
const auto title_id = rp.PopRaw<u64>();
const auto size = ctx.GetWriteBufferSize();
const FileSys::PatchManager pm{title_id, system.GetFileSystemController(),
system.GetContentProvider()};
const auto control = pm.GetControlMetadata();
std::vector<u8> 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(RESULT_UNKNOWN);
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<u64>(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(RESULT_UNKNOWN);
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(RESULT_SUCCESS);
rb.Push<u32>(static_cast<u32>(out.size()));
}
void IApplicationManagerInterface::GetApplicationDesiredLanguage(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
const auto supported_languages = rp.Pop<u32>();
const auto res = GetApplicationDesiredLanguage(supported_languages);
if (res.Succeeded()) {
IPC::ResponseBuilder rb{ctx, 3};
rb.Push(RESULT_SUCCESS);
rb.Push<u32>(*res);
} else {
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(res.Code());
}
}
ResultVal<u8> IApplicationManagerInterface::GetApplicationDesiredLanguage(
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(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 ERR_APPLICATION_LANGUAGE_NOT_FOUND;
}
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 ERR_APPLICATION_LANGUAGE_NOT_FOUND;
}
// 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) {
return MakeResult(static_cast<u8>(lang));
}
}
LOG_ERROR(Service_NS, "Could not find a valid language! supported_languages={:08X}",
supported_languages);
return ERR_APPLICATION_LANGUAGE_NOT_FOUND;
}
void IApplicationManagerInterface::ConvertApplicationLanguageToLanguageCode(
Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
const auto application_language = rp.Pop<u8>();
const auto res = ConvertApplicationLanguageToLanguageCode(application_language);
if (res.Succeeded()) {
IPC::ResponseBuilder rb{ctx, 4};
rb.Push(RESULT_SUCCESS);
rb.Push(*res);
} else {
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(res.Code());
}
}
ResultVal<u64> IApplicationManagerInterface::ConvertApplicationLanguageToLanguageCode(
u8 application_language) {
const auto language_code =
ConvertToLanguageCode(static_cast<ApplicationLanguage>(application_language));
if (language_code == std::nullopt) {
LOG_ERROR(Service_NS, "Language not found! application_language={}", application_language);
return ERR_APPLICATION_LANGUAGE_NOT_FOUND;
}
return MakeResult(static_cast<u64>(*language_code));
}
IApplicationVersionInterface::IApplicationVersionInterface(Core::System& system_)
: ServiceFramework{system_, "IApplicationVersionInterface"} {
// clang-format off
static const FunctionInfo functions[] = {
{0, nullptr, "GetLaunchRequiredVersion"},
{1, nullptr, "UpgradeLaunchRequiredVersion"},
{35, nullptr, "UpdateVersionList"},
{36, nullptr, "PushLaunchVersion"},
{37, nullptr, "ListRequiredVersion"},
{800, nullptr, "RequestVersionList"},
{801, nullptr, "ListVersionList"},
{802, nullptr, "RequestVersionListData"},
{1000, nullptr, "PerformAutoUpdate"},
};
// clang-format on
RegisterHandlers(functions);
}
IApplicationVersionInterface::~IApplicationVersionInterface() = default;
IContentManagementInterface::IContentManagementInterface(Core::System& system_)
: ServiceFramework{system_, "IContentManagementInterface"} {
// clang-format off
static const FunctionInfo functions[] = {
{11, nullptr, "CalculateApplicationOccupiedSize"},
{43, nullptr, "CheckSdCardMountStatus"},
{47, nullptr, "GetTotalSpaceSize"},
{48, nullptr, "GetFreeSpaceSize"},
{600, nullptr, "CountApplicationContentMeta"},
{601, nullptr, "ListApplicationContentMetaStatus"},
{605, nullptr, "ListApplicationContentMetaStatusWithRightsCheck"},
{607, nullptr, "IsAnyApplicationRunning"},
};
// clang-format on
RegisterHandlers(functions);
}
IContentManagementInterface::~IContentManagementInterface() = default;
IDocumentInterface::IDocumentInterface(Core::System& system_)
: ServiceFramework{system_, "IDocumentInterface"} {
// clang-format off
static const FunctionInfo functions[] = {
{21, nullptr, "GetApplicationContentPath"},
{23, nullptr, "ResolveApplicationContentPath"},
{93, nullptr, "GetRunningApplicationProgramId"},
};
// clang-format on
RegisterHandlers(functions);
}
IDocumentInterface::~IDocumentInterface() = default;
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;
IECommerceInterface::IECommerceInterface(Core::System& system_)
: ServiceFramework{system_, "IECommerceInterface"} {
// clang-format off
static const FunctionInfo functions[] = {
{0, nullptr, "RequestLinkDevice"},
{1, nullptr, "RequestCleanupAllPreInstalledApplications"},
{2, nullptr, "RequestCleanupPreInstalledApplication"},
{3, nullptr, "RequestSyncRights"},
{4, nullptr, "RequestUnlinkDevice"},
{5, nullptr, "RequestRevokeAllELicense"},
{6, nullptr, "RequestSyncRightsBasedOnAssignedELicenses"},
};
// clang-format on
RegisterHandlers(functions);
}
IECommerceInterface::~IECommerceInterface() = default;
IFactoryResetInterface::IFactoryResetInterface(Core::System& system_)
: ServiceFramework{system_, "IFactoryResetInterface"} {
// clang-format off
static const FunctionInfo functions[] = {
{100, nullptr, "ResetToFactorySettings"},
{101, nullptr, "ResetToFactorySettingsWithoutUserSaveData"},
{102, nullptr, "ResetToFactorySettingsForRefurbishment"},
{103, nullptr, "ResetToFactorySettingsWithPlatformRegion"},
{104, nullptr, "ResetToFactorySettingsWithPlatformRegionAuthentication"},
{105, nullptr, "RequestResetToFactorySettingsSecurely"},
{106, nullptr, "RequestResetToFactorySettingsWithPlatformRegionAuthenticationSecurely"},
};
// clang-format on
RegisterHandlers(functions);
}
IFactoryResetInterface::~IFactoryResetInterface() = default;
NS::NS(const char* name, Core::System& system_) : ServiceFramework{system_, name} {
// clang-format off
static const FunctionInfo functions[] = {
{7992, &NS::PushInterface<IECommerceInterface>, "GetECommerceInterface"},
{7993, &NS::PushInterface<IApplicationVersionInterface>, "GetApplicationVersionInterface"},
{7994, &NS::PushInterface<IFactoryResetInterface>, "GetFactoryResetInterface"},
{7995, &NS::PushInterface<IAccountProxyInterface>, "GetAccountProxyInterface"},
{7996, &NS::PushIApplicationManagerInterface, "GetApplicationManagerInterface"},
{7997, &NS::PushInterface<IDownloadTaskInterface>, "GetDownloadTaskInterface"},
{7998, &NS::PushInterface<IContentManagementInterface>, "GetContentManagementInterface"},
{7999, &NS::PushInterface<IDocumentInterface>, "GetDocumentInterface"},
};
// clang-format on
RegisterHandlers(functions);
}
NS::~NS() = default;
std::shared_ptr<IApplicationManagerInterface> NS::GetApplicationManagerInterface() const {
return GetInterface<IApplicationManagerInterface>(system);
}
class NS_DEV final : public ServiceFramework<NS_DEV> {
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, "GetShellEventHandle"},
{5, nullptr, "GetShellEventInfo"},
{6, nullptr, "TerminateApplication"},
{7, nullptr, "PrepareLaunchProgramFromHost"},
{8, nullptr, "LaunchApplication"},
{9, nullptr, "LaunchApplicationWithStorageIdForDevelop"},
{10, nullptr, "IsSystemMemoryResourceLimitBoosted"},
{11, nullptr, "GetRunningApplicationProcessIdForDevelop"},
{12, nullptr, "SetCurrentApplicationRightsEnvironmentCanBeActive"},
{13, nullptr, "CreateApplicationResourceForDevelop"},
{14, nullptr, "IsPreomiaForDevelop"},
{15, nullptr, "GetApplicationProgramIdFromHost"},
};
// clang-format on
RegisterHandlers(functions);
}
};
class ISystemUpdateControl final : public ServiceFramework<ISystemUpdateControl> {
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<NS_SU> {
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(Kernel::HLERequestContext& ctx) {
LOG_DEBUG(Service_NS, "called");
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
rb.Push(RESULT_SUCCESS);
rb.PushIpcInterface<ISystemUpdateControl>(system);
}
};
class NS_VM final : public ServiceFramework<NS_VM> {
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(Kernel::HLERequestContext& ctx) {
LOG_WARNING(Service_NS, "(STUBBED) called");
IPC::ResponseBuilder rb{ctx, 3};
rb.Push(RESULT_SUCCESS);
rb.Push(false);
}
};
void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system) {
std::make_shared<NS>("ns:am2", system)->InstallAsService(service_manager);
std::make_shared<NS>("ns:ec", system)->InstallAsService(service_manager);
std::make_shared<NS>("ns:rid", system)->InstallAsService(service_manager);
std::make_shared<NS>("ns:rt", system)->InstallAsService(service_manager);
std::make_shared<NS>("ns:web", system)->InstallAsService(service_manager);
std::make_shared<NS_DEV>(system)->InstallAsService(service_manager);
std::make_shared<NS_SU>(system)->InstallAsService(service_manager);
std::make_shared<NS_VM>(system)->InstallAsService(service_manager);
std::make_shared<PL_U>(system)->InstallAsService(service_manager);
}
} // namespace Service::NS

115
src/core/hle/service/ns/ns.h Executable file
View File

@@ -0,0 +1,115 @@
// Copyright 2018 yuzu emulator team
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#pragma once
#include "core/hle/service/service.h"
namespace Core {
class System;
}
namespace Service {
namespace FileSystem {
class FileSystemController;
} // namespace FileSystem
namespace NS {
class IAccountProxyInterface final : public ServiceFramework<IAccountProxyInterface> {
public:
explicit IAccountProxyInterface(Core::System& system_);
~IAccountProxyInterface() override;
};
class IApplicationManagerInterface final : public ServiceFramework<IApplicationManagerInterface> {
public:
explicit IApplicationManagerInterface(Core::System& system_);
~IApplicationManagerInterface() override;
ResultVal<u8> GetApplicationDesiredLanguage(u32 supported_languages);
ResultVal<u64> ConvertApplicationLanguageToLanguageCode(u8 application_language);
private:
void GetApplicationControlData(Kernel::HLERequestContext& ctx);
void GetApplicationDesiredLanguage(Kernel::HLERequestContext& ctx);
void ConvertApplicationLanguageToLanguageCode(Kernel::HLERequestContext& ctx);
};
class IApplicationVersionInterface final : public ServiceFramework<IApplicationVersionInterface> {
public:
explicit IApplicationVersionInterface(Core::System& system_);
~IApplicationVersionInterface() override;
};
class IContentManagementInterface final : public ServiceFramework<IContentManagementInterface> {
public:
explicit IContentManagementInterface(Core::System& system_);
~IContentManagementInterface() override;
};
class IDocumentInterface final : public ServiceFramework<IDocumentInterface> {
public:
explicit IDocumentInterface(Core::System& system_);
~IDocumentInterface() override;
};
class IDownloadTaskInterface final : public ServiceFramework<IDownloadTaskInterface> {
public:
explicit IDownloadTaskInterface(Core::System& system_);
~IDownloadTaskInterface() override;
};
class IECommerceInterface final : public ServiceFramework<IECommerceInterface> {
public:
explicit IECommerceInterface(Core::System& system_);
~IECommerceInterface() override;
};
class IFactoryResetInterface final : public ServiceFramework<IFactoryResetInterface> {
public:
explicit IFactoryResetInterface(Core::System& system_);
~IFactoryResetInterface() override;
};
class NS final : public ServiceFramework<NS> {
public:
explicit NS(const char* name, Core::System& system_);
~NS() override;
std::shared_ptr<IApplicationManagerInterface> GetApplicationManagerInterface() const;
private:
template <typename T, typename... Args>
void PushInterface(Kernel::HLERequestContext& ctx) {
LOG_DEBUG(Service_NS, "called");
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
rb.Push(RESULT_SUCCESS);
rb.PushIpcInterface<T>(system);
}
void PushIApplicationManagerInterface(Kernel::HLERequestContext& ctx) {
LOG_DEBUG(Service_NS, "called");
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
rb.Push(RESULT_SUCCESS);
rb.PushIpcInterface<IApplicationManagerInterface>(system);
}
template <typename T, typename... Args>
std::shared_ptr<T> GetInterface(Args&&... args) const {
static_assert(std::is_base_of_v<Kernel::SessionRequestHandler, T>,
"Not a base of ServiceFrameworkBase");
return std::make_shared<T>(std::forward<Args>(args)...);
}
};
/// Registers all NS services with the specified service manager.
void InstallInterfaces(SM::ServiceManager& service_manager, Core::System& system);
} // namespace NS
} // namespace Service

View File

@@ -0,0 +1,42 @@
// Copyright 2019 yuzu emulator team
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#pragma once
#include <optional>
#include <string>
#include "common/common_types.h"
#include "core/hle/service/set/set.h"
namespace Service::NS {
/// This is nn::ns::detail::ApplicationLanguage
enum class ApplicationLanguage : u8 {
AmericanEnglish = 0,
BritishEnglish,
Japanese,
French,
German,
LatinAmericanSpanish,
Spanish,
Italian,
Dutch,
CanadianFrench,
Portuguese,
Russian,
Korean,
TraditionalChinese,
SimplifiedChinese,
Count
};
using ApplicationLanguagePriorityList =
const std::array<ApplicationLanguage, static_cast<std::size_t>(ApplicationLanguage::Count)>;
constexpr u32 GetSupportedLanguageFlag(const ApplicationLanguage lang) {
return 1U << static_cast<u32>(lang);
}
const ApplicationLanguagePriorityList* GetApplicationLanguagePriorityList(ApplicationLanguage lang);
std::optional<ApplicationLanguage> ConvertToApplicationLanguage(
Service::Set::LanguageCode language_code);
std::optional<Service::Set::LanguageCode> ConvertToLanguageCode(ApplicationLanguage lang);
} // namespace Service::NS

299
src/core/hle/service/ns/pl_u.cpp Executable file
View File

@@ -0,0 +1,299 @@
// Copyright 2018 yuzu emulator team
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#include <algorithm>
#include <cstring>
#include <vector>
#include "common/assert.h"
#include "common/common_paths.h"
#include "common/common_types.h"
#include "common/file_util.h"
#include "common/logging/log.h"
#include "common/swap.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/file_sys/system_archive/system_archive.h"
#include "core/hle/ipc_helpers.h"
#include "core/hle/kernel/kernel.h"
#include "core/hle/kernel/physical_memory.h"
#include "core/hle/kernel/shared_memory.h"
#include "core/hle/service/filesystem/filesystem.h"
#include "core/hle/service/ns/pl_u.h"
namespace Service::NS {
struct FontRegion {
u32 offset;
u32 size;
};
// The below data is specific to shared font data dumped from Switch on f/w 2.2
// Virtual address and offsets/sizes likely will vary by dump
[[maybe_unused]] constexpr VAddr SHARED_FONT_MEM_VADDR{0x00000009d3016000ULL};
constexpr u32 EXPECTED_RESULT{0x7f9a0218}; // What we expect the decrypted bfttf first 4 bytes to be
constexpr u32 EXPECTED_MAGIC{0x36f81a1e}; // What we expect the encrypted bfttf first 4 bytes to be
constexpr u64 SHARED_FONT_MEM_SIZE{0x1100000};
constexpr FontRegion EMPTY_REGION{0, 0};
enum class LoadState : u32 {
Loading = 0,
Done = 1,
};
static void DecryptSharedFont(const std::vector<u32>& input, Kernel::PhysicalMemory& output,
std::size_t& offset) {
ASSERT_MSG(offset + (input.size() * sizeof(u32)) < SHARED_FONT_MEM_SIZE,
"Shared fonts exceeds 17mb!");
ASSERT_MSG(input[0] == EXPECTED_MAGIC, "Failed to derive key, unexpected magic number");
const u32 KEY = input[0] ^ EXPECTED_RESULT; // Derive key using an inverse xor
std::vector<u32> transformed_font(input.size());
// TODO(ogniK): Figure out a better way to do this
std::transform(input.begin(), input.end(), transformed_font.begin(),
[&KEY](u32 font_data) { return Common::swap32(font_data ^ KEY); });
transformed_font[1] = Common::swap32(transformed_font[1]) ^ KEY; // "re-encrypt" the size
std::memcpy(output.data() + offset, transformed_font.data(),
transformed_font.size() * sizeof(u32));
offset += transformed_font.size() * sizeof(u32);
}
void DecryptSharedFontToTTF(const std::vector<u32>& input, std::vector<u8>& output) {
ASSERT_MSG(input[0] == EXPECTED_MAGIC, "Failed to derive key, unexpected magic number");
const u32 KEY = input[0] ^ EXPECTED_RESULT; // Derive key using an inverse xor
std::vector<u32> transformed_font(input.size());
// TODO(ogniK): Figure out a better way to do this
std::transform(input.begin(), input.end(), transformed_font.begin(),
[&KEY](u32 font_data) { return Common::swap32(font_data ^ KEY); });
transformed_font[1] = Common::swap32(transformed_font[1]) ^ KEY; // "re-encrypt" the size
std::memcpy(output.data(), transformed_font.data() + 2, transformed_font.size() * sizeof(u32));
}
void EncryptSharedFont(const std::vector<u32>& input, std::vector<u8>& output,
std::size_t& offset) {
ASSERT_MSG(offset + (input.size() * sizeof(u32)) < SHARED_FONT_MEM_SIZE,
"Shared fonts exceeds 17mb!");
const auto key = Common::swap32(EXPECTED_RESULT ^ EXPECTED_MAGIC);
std::vector<u32> transformed_font(input.size() + 2);
transformed_font[0] = Common::swap32(EXPECTED_MAGIC);
transformed_font[1] = Common::swap32(static_cast<u32>(input.size() * sizeof(u32))) ^ key;
std::transform(input.begin(), input.end(), transformed_font.begin() + 2,
[key](u32 in) { return in ^ key; });
std::memcpy(output.data() + offset, transformed_font.data(),
transformed_font.size() * sizeof(u32));
offset += transformed_font.size() * sizeof(u32);
}
// Helper function to make BuildSharedFontsRawRegions a bit nicer
static u32 GetU32Swapped(const u8* data) {
u32 value;
std::memcpy(&value, data, sizeof(value));
return Common::swap32(value);
}
struct PL_U::Impl {
const FontRegion& GetSharedFontRegion(std::size_t index) const {
if (index >= shared_font_regions.size() || shared_font_regions.empty()) {
// No font fallback
return EMPTY_REGION;
}
return shared_font_regions.at(index);
}
void BuildSharedFontsRawRegions(const Kernel::PhysicalMemory& input) {
// As we can derive the xor key we can just populate the offsets
// based on the shared memory dump
unsigned cur_offset = 0;
for (std::size_t i = 0; i < SHARED_FONTS.size(); i++) {
// Out of shared fonts/invalid font
if (GetU32Swapped(input.data() + cur_offset) != EXPECTED_RESULT) {
break;
}
// Derive key withing inverse xor
const u32 KEY = GetU32Swapped(input.data() + cur_offset) ^ EXPECTED_MAGIC;
const u32 SIZE = GetU32Swapped(input.data() + cur_offset + 4) ^ KEY;
shared_font_regions.push_back(FontRegion{cur_offset + 8, SIZE});
cur_offset += SIZE + 8;
}
}
/// Handle to shared memory region designated for a shared font
std::shared_ptr<Kernel::SharedMemory> shared_font_mem;
/// Backing memory for the shared font data
std::shared_ptr<Kernel::PhysicalMemory> shared_font;
// Automatically populated based on shared_fonts dump or system archives.
std::vector<FontRegion> shared_font_regions;
};
PL_U::PL_U(Core::System& system_)
: ServiceFramework{system_, "pl:u"}, impl{std::make_unique<Impl>()} {
// clang-format off
static const FunctionInfo functions[] = {
{0, &PL_U::RequestLoad, "RequestLoad"},
{1, &PL_U::GetLoadState, "GetLoadState"},
{2, &PL_U::GetSize, "GetSize"},
{3, &PL_U::GetSharedMemoryAddressOffset, "GetSharedMemoryAddressOffset"},
{4, &PL_U::GetSharedMemoryNativeHandle, "GetSharedMemoryNativeHandle"},
{5, &PL_U::GetSharedFontInOrderOfPriority, "GetSharedFontInOrderOfPriority"},
{6, nullptr, "GetSharedFontInOrderOfPriorityForSystem"},
{100, nullptr, "RequestApplicationFunctionAuthorization"},
{101, nullptr, "RequestApplicationFunctionAuthorizationByProcessId"},
{102, nullptr, "RequestApplicationFunctionAuthorizationByApplicationId"},
{1000, nullptr, "LoadNgWordDataForPlatformRegionChina"},
{1001, nullptr, "GetNgWordDataSizeForPlatformRegionChina"},
};
// clang-format on
RegisterHandlers(functions);
auto& fsc = system.GetFileSystemController();
// Attempt to load shared font data from disk
const auto* nand = fsc.GetSystemNANDContents();
std::size_t offset = 0;
// Rebuild shared fonts from data ncas or synthesize
impl->shared_font = std::make_shared<Kernel::PhysicalMemory>(SHARED_FONT_MEM_SIZE);
for (auto font : SHARED_FONTS) {
FileSys::VirtualFile romfs;
const auto nca =
nand->GetEntry(static_cast<u64>(font.first), FileSys::ContentRecordType::Data);
if (nca) {
romfs = nca->GetRomFS();
}
if (!romfs) {
romfs = FileSys::SystemArchive::SynthesizeSystemArchive(static_cast<u64>(font.first));
}
if (!romfs) {
LOG_ERROR(Service_NS, "Failed to find or synthesize {:016X}! Skipping", font.first);
continue;
}
const auto extracted_romfs = FileSys::ExtractRomFS(romfs);
if (!extracted_romfs) {
LOG_ERROR(Service_NS, "Failed to extract RomFS for {:016X}! Skipping", font.first);
continue;
}
const auto font_fp = extracted_romfs->GetFile(font.second);
if (!font_fp) {
LOG_ERROR(Service_NS, "{:016X} has no file \"{}\"! Skipping", font.first, font.second);
continue;
}
std::vector<u32> font_data_u32(font_fp->GetSize() / sizeof(u32));
font_fp->ReadBytes<u32>(font_data_u32.data(), font_fp->GetSize());
// We need to be BigEndian as u32s for the xor encryption
std::transform(font_data_u32.begin(), font_data_u32.end(), font_data_u32.begin(),
Common::swap32);
// Font offset and size do not account for the header
const FontRegion region{static_cast<u32>(offset + 8),
static_cast<u32>((font_data_u32.size() * sizeof(u32)) - 8)};
DecryptSharedFont(font_data_u32, *impl->shared_font, offset);
impl->shared_font_regions.push_back(region);
}
}
PL_U::~PL_U() = default;
void PL_U::RequestLoad(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
const u32 shared_font_type{rp.Pop<u32>()};
// Games don't call this so all fonts should be loaded
LOG_DEBUG(Service_NS, "called, shared_font_type={}", shared_font_type);
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(RESULT_SUCCESS);
}
void PL_U::GetLoadState(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
const u32 font_id{rp.Pop<u32>()};
LOG_DEBUG(Service_NS, "called, font_id={}", font_id);
IPC::ResponseBuilder rb{ctx, 3};
rb.Push(RESULT_SUCCESS);
rb.Push<u32>(static_cast<u32>(LoadState::Done));
}
void PL_U::GetSize(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
const u32 font_id{rp.Pop<u32>()};
LOG_DEBUG(Service_NS, "called, font_id={}", font_id);
IPC::ResponseBuilder rb{ctx, 3};
rb.Push(RESULT_SUCCESS);
rb.Push<u32>(impl->GetSharedFontRegion(font_id).size);
}
void PL_U::GetSharedMemoryAddressOffset(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
const u32 font_id{rp.Pop<u32>()};
LOG_DEBUG(Service_NS, "called, font_id={}", font_id);
IPC::ResponseBuilder rb{ctx, 3};
rb.Push(RESULT_SUCCESS);
rb.Push<u32>(impl->GetSharedFontRegion(font_id).offset);
}
void PL_U::GetSharedMemoryNativeHandle(Kernel::HLERequestContext& ctx) {
// Map backing memory for the font data
LOG_DEBUG(Service_NS, "called");
// Create shared font memory object
auto& kernel = system.Kernel();
impl->shared_font_mem = SharedFrom(&kernel.GetFontSharedMem());
std::memcpy(impl->shared_font_mem->GetPointer(), impl->shared_font->data(),
impl->shared_font->size());
IPC::ResponseBuilder rb{ctx, 2, 1};
rb.Push(RESULT_SUCCESS);
rb.PushCopyObjects(impl->shared_font_mem);
}
void PL_U::GetSharedFontInOrderOfPriority(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
const u64 language_code{rp.Pop<u64>()}; // TODO(ogniK): Find out what this is used for
LOG_DEBUG(Service_NS, "called, language_code={:X}", language_code);
IPC::ResponseBuilder rb{ctx, 4};
std::vector<u32> font_codes;
std::vector<u32> font_offsets;
std::vector<u32> font_sizes;
// TODO(ogniK): Have actual priority order
for (std::size_t i = 0; i < impl->shared_font_regions.size(); i++) {
font_codes.push_back(static_cast<u32>(i));
auto region = impl->GetSharedFontRegion(i);
font_offsets.push_back(region.offset);
font_sizes.push_back(region.size);
}
// Resize buffers if game requests smaller size output.
font_codes.resize(
std::min<std::size_t>(font_codes.size(), ctx.GetWriteBufferSize(0) / sizeof(u32)));
font_offsets.resize(
std::min<std::size_t>(font_offsets.size(), ctx.GetWriteBufferSize(1) / sizeof(u32)));
font_sizes.resize(
std::min<std::size_t>(font_sizes.size(), ctx.GetWriteBufferSize(2) / sizeof(u32)));
ctx.WriteBuffer(font_codes, 0);
ctx.WriteBuffer(font_offsets, 1);
ctx.WriteBuffer(font_sizes, 2);
rb.Push(RESULT_SUCCESS);
rb.Push<u8>(static_cast<u8>(LoadState::Done)); // Fonts Loaded
rb.Push<u32>(static_cast<u32>(font_codes.size()));
}
} // namespace Service::NS

59
src/core/hle/service/ns/pl_u.h Executable file
View File

@@ -0,0 +1,59 @@
// Copyright 2018 yuzu emulator team
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#pragma once
#include <memory>
#include <vector>
#include "core/hle/service/service.h"
namespace Service {
namespace FileSystem {
class FileSystemController;
} // namespace FileSystem
namespace NS {
enum class FontArchives : u64 {
Extension = 0x0100000000000810,
Standard = 0x0100000000000811,
Korean = 0x0100000000000812,
ChineseTraditional = 0x0100000000000813,
ChineseSimple = 0x0100000000000814,
};
constexpr std::array<std::pair<FontArchives, const char*>, 7> SHARED_FONTS{
std::make_pair(FontArchives::Standard, "nintendo_udsg-r_std_003.bfttf"),
std::make_pair(FontArchives::ChineseSimple, "nintendo_udsg-r_org_zh-cn_003.bfttf"),
std::make_pair(FontArchives::ChineseSimple, "nintendo_udsg-r_ext_zh-cn_003.bfttf"),
std::make_pair(FontArchives::ChineseTraditional, "nintendo_udjxh-db_zh-tw_003.bfttf"),
std::make_pair(FontArchives::Korean, "nintendo_udsg-r_ko_003.bfttf"),
std::make_pair(FontArchives::Extension, "nintendo_ext_003.bfttf"),
std::make_pair(FontArchives::Extension, "nintendo_ext2_003.bfttf"),
};
void DecryptSharedFontToTTF(const std::vector<u32>& input, std::vector<u8>& output);
void EncryptSharedFont(const std::vector<u32>& input, std::vector<u8>& output, std::size_t& offset);
class PL_U final : public ServiceFramework<PL_U> {
public:
explicit PL_U(Core::System& system_);
~PL_U() override;
private:
void RequestLoad(Kernel::HLERequestContext& ctx);
void GetLoadState(Kernel::HLERequestContext& ctx);
void GetSize(Kernel::HLERequestContext& ctx);
void GetSharedMemoryAddressOffset(Kernel::HLERequestContext& ctx);
void GetSharedMemoryNativeHandle(Kernel::HLERequestContext& ctx);
void GetSharedFontInOrderOfPriority(Kernel::HLERequestContext& ctx);
struct Impl;
std::unique_ptr<Impl> impl;
};
} // namespace NS
} // namespace Service