display titles

This commit is contained in:
german77
2024-01-27 23:58:16 -06:00
parent e58881cb9c
commit 09ababeaad
4 changed files with 270 additions and 72 deletions

View File

@ -422,8 +422,17 @@ void IGeneralService::GetCurrentNetworkProfile(HLERequestContext& ctx) {
void IGeneralService::EnumerateNetworkInterfaces(HLERequestContext& ctx) {
LOG_ERROR(Service_NIFM, "(STUBBED) called");
IPC::ResponseBuilder rb{ctx, 2};
IPC::ResponseBuilder rb{ctx, 3};
rb.Push(ResultSuccess);
rb.Push(0);
}
void IGeneralService::EnumerateNetworkProfiles(HLERequestContext& ctx) {
LOG_ERROR(Service_NIFM, "(STUBBED) called");
IPC::ResponseBuilder rb{ctx, 3};
rb.Push(ResultSuccess);
rb.Push(0);
}
@ -584,6 +593,14 @@ void IGeneralService::IsAnyForegroundRequestAccepted(HLERequestContext& ctx) {
rb.Push<u8>(is_accepted);
}
void IGeneralService::ConfirmSystemAvailability(HLERequestContext& ctx) {
LOG_ERROR(Service_NIFM, "(STUBBED) called");
IPC::ResponseBuilder rb{ctx, 3};
rb.Push(ResultSuccess);
rb.Push(true);
}
void IGeneralService::GetCurrentAccessPoint(HLERequestContext& ctx) {
LOG_ERROR(Service_NIFM, "(STUBBED) called");
@ -600,7 +617,7 @@ IGeneralService::IGeneralService(Core::System& system_)
{4, &IGeneralService::CreateRequest, "CreateRequest"},
{5, &IGeneralService::GetCurrentNetworkProfile, "GetCurrentNetworkProfile"},
{6, &IGeneralService::EnumerateNetworkInterfaces, "EnumerateNetworkInterfaces"},
{7, nullptr, "EnumerateNetworkProfiles"},
{7, &IGeneralService::EnumerateNetworkProfiles, "EnumerateNetworkProfiles"},
{8, nullptr, "GetNetworkProfile"},
{9, nullptr, "SetNetworkProfile"},
{10, &IGeneralService::RemoveNetworkProfile, "RemoveNetworkProfile"},
@ -626,7 +643,7 @@ IGeneralService::IGeneralService(Core::System& system_)
{30, nullptr, "SetEthernetCommunicationEnabledForTest"},
{31, nullptr, "GetTelemetorySystemEventReadableHandle"},
{32, nullptr, "GetTelemetryInfo"},
{33, nullptr, "ConfirmSystemAvailability"},
{33, &IGeneralService::ConfirmSystemAvailability, "ConfirmSystemAvailability"},
{34, nullptr, "SetBackgroundRequestEnabled"},
{35, nullptr, "GetScanData"},
{36, &IGeneralService::GetCurrentAccessPoint, "GetCurrentAccessPoint"},

View File

@ -28,6 +28,7 @@ private:
void CreateRequest(HLERequestContext& ctx);
void GetCurrentNetworkProfile(HLERequestContext& ctx);
void EnumerateNetworkInterfaces(HLERequestContext& ctx);
void EnumerateNetworkProfiles(HLERequestContext& ctx);
void RemoveNetworkProfile(HLERequestContext& ctx);
void GetCurrentIpAddress(HLERequestContext& ctx);
void CreateTemporaryNetworkProfile(HLERequestContext& ctx);
@ -38,6 +39,7 @@ private:
void IsEthernetCommunicationEnabled(HLERequestContext& ctx);
void IsAnyInternetRequestAccepted(HLERequestContext& ctx);
void IsAnyForegroundRequestAccepted(HLERequestContext& ctx);
void ConfirmSystemAvailability(HLERequestContext& ctx);
void GetCurrentAccessPoint(HLERequestContext& ctx);
Network::RoomNetwork& network;

View File

@ -5,8 +5,13 @@
#include "common/settings.h"
#include "core/arm/debug.h"
#include "core/core.h"
#include "core/file_sys/content_archive.h"
#include "core/file_sys/control_metadata.h"
#include "core/file_sys/fs_filesystem.h"
#include "core/file_sys/nca_metadata.h"
#include "core/file_sys/patch_manager.h"
#include "core/file_sys/registered_cache.h"
#include "core/file_sys/submission_package.h"
#include "core/file_sys/vfs/vfs.h"
#include "core/hle/service/filesystem/filesystem.h"
#include "core/hle/service/glue/glue_manager.h"
@ -198,7 +203,7 @@ IApplicationManagerInterface::IApplicationManagerInterface(Core::System& system_
{1003, nullptr, "RequestVerifyApplication"},
{1004, nullptr, "CorruptContentForDebug"},
{1200, nullptr, "NeedsUpdateVulnerability"},
{1300, nullptr, "IsAnyApplicationEntityInstalled"},
{1300, &IApplicationManagerInterface::IsAnyApplicationEntityInstalled, "IsAnyApplicationEntityInstalled"},
{1301, nullptr, "DeleteApplicationContentEntities"},
{1302, nullptr, "CleanupUnrecordedApplicationEntity"},
{1303, nullptr, "CleanupAddOnContentsWithNoRights"},
@ -340,7 +345,7 @@ IApplicationManagerInterface::IApplicationManagerInterface(Core::System& system_
service_context.CreateEvent("IApplicationManagerInterface::GamecardMountFailureEvent");
}
IApplicationManagerInterface::~IApplicationManagerInterface(){
IApplicationManagerInterface::~IApplicationManagerInterface() {
service_context.CloseEvent(record_update_system_event);
service_context.CloseEvent(gamecard_update_detection_event);
service_context.CloseEvent(gamecard_mount_status_event);
@ -353,54 +358,39 @@ void IApplicationManagerInterface::ListApplicationRecord(HLERequestContext& ctx)
const auto limit = ctx.GetWriteBufferNumElements<ApplicationRecord>();
LOG_ERROR(Service_NS, "(STUBBED) called");
const auto& cache = system.GetContentProviderUnion();
const auto installed_games = cache.ListEntriesFilterOrigin(
std::nullopt, FileSys::TitleType::Application, FileSys::ContentRecordType::Program);
std::vector<ApplicationRecord> application_records;
std::vector<ApplicationRecord> application_records2;
application_records.push_back(ApplicationRecord{
.application_id = 0x010074F013262000,
.type = 3,
.unknown = 2,
.unknown2 = 0,
});
application_records.push_back(ApplicationRecord{
.application_id = 0x01000F0002BB6000,
.type = 2,
.unknown = 2,
.unknown2 = 1,
});
application_records.push_back(ApplicationRecord{
.application_id = 0x0100A7F002830000,
.type = 1,
.unknown = 2,
.unknown2 = 2,
});
application_records.push_back(ApplicationRecord{
.application_id = 0x01008DF012A7A000,
.type = 3,
.unknown = 2,
.unknown2 = 3,
});
for (const auto& data : application_records) {
if (application_records2.size() >= limit) {
u8 ii{24};
for (const auto& [slot, game] : installed_games) {
if (application_records.size() >= limit) {
break;
}
if (game.title_id == 0 || game.title_id < 0x0100000000001FFFull) {
continue;
}
if (offset > 0) {
offset--;
continue;
}
application_records2.push_back(data);
application_records.push_back(ApplicationRecord{
.application_id = game.title_id,
.type = ApplicationRecordType::Installed,
.unknown = 0, // 2 = needs update
.unknown2 = ii++,
});
}
if (!application_records2.empty()) {
ctx.WriteBuffer(application_records2);
if (!application_records.empty()) {
ctx.WriteBuffer(application_records);
}
IPC::ResponseBuilder rb{ctx, 3};
rb.Push(ResultSuccess);
rb.Push(application_records2.size());
rb.Push(application_records.size());
}
void IApplicationManagerInterface::GetApplicationRecordUpdateSystemEvent(HLERequestContext& ctx) {
LOG_ERROR(Service_NS, "(STUBBED) called");
@ -478,6 +468,14 @@ void IApplicationManagerInterface::GetGameCardMountFailureEvent(HLERequestContex
rb.PushCopyObjects(gamecard_mount_failure_event->GetReadableEvent());
}
void IApplicationManagerInterface::IsAnyApplicationEntityInstalled(HLERequestContext& ctx) {
LOG_ERROR(Service_NS, "(STUBBED) called");
IPC::ResponseBuilder rb{ctx, 3};
rb.Push(ResultSuccess);
rb.Push<u8>(true);
}
void IApplicationManagerInterface::GetApplicationView(HLERequestContext& ctx) {
std::vector<u64> application_id(ctx.GetReadBufferNumElements<u64>());
const auto app_buffer = ctx.ReadBuffer();
@ -485,10 +483,12 @@ void IApplicationManagerInterface::GetApplicationView(HLERequestContext& ctx) {
std::vector<ApplicationView> app_view;
LOG_DEBUG(Service_NS, "(STUBBED) called, size={}", application_id.size());
LOG_ERROR(Service_NS, "(STUBBED) called, size={}", application_id.size());
for (const u64& data : application_id) {
app_view.push_back(ApplicationView{
.application_id = data,
.unk = 0x70000,
.flags = 0x401f17,
});
}
@ -505,12 +505,14 @@ void IApplicationManagerInterface::GetApplicationViewWithPromotionInfo(HLEReques
std::vector<ApplicationViewWithPromotionInfo> app_view;
LOG_DEBUG(Service_NS, "(STUBBED) called, size={}", application_id.size());
LOG_ERROR(Service_NS, "(STUBBED) called, size={}", application_id.size());
for (const u64& data : application_id) {
app_view.push_back(ApplicationViewWithPromotionInfo{
.view{
.application_id = data,
.unk = 0x70000,
.flags = 0x401f17,
},
.promotion = {},
});
@ -672,7 +674,7 @@ IContentManagementInterface::IContentManagementInterface(Core::System& system_)
: ServiceFramework{system_, "IContentManagementInterface"} {
// clang-format off
static const FunctionInfo functions[] = {
{11, nullptr, "CalculateApplicationOccupiedSize"},
{11, &IContentManagementInterface::CalculateApplicationOccupiedSize, "CalculateApplicationOccupiedSize"},
{43, &IContentManagementInterface::CheckSdCardMountStatus, "CheckSdCardMountStatus"},
{47, &IContentManagementInterface::GetTotalSpaceSize, "GetTotalSpaceSize"},
{48, &IContentManagementInterface::GetFreeSpaceSize, "GetFreeSpaceSize"},
@ -688,6 +690,37 @@ IContentManagementInterface::IContentManagementInterface(Core::System& system_)
IContentManagementInterface::~IContentManagementInterface() = default;
void IContentManagementInterface::CalculateApplicationOccupiedSize(HLERequestContext& ctx) {
struct ApplicationOccupiedSizeEntity {
u8 storage;
INSERT_PADDING_BYTES(0x7);
u64 app_size;
u64 patch_size;
u64 aoc_size;
};
struct ApplicationOccupiedSize {
ApplicationOccupiedSizeEntity a;
ApplicationOccupiedSizeEntity b;
ApplicationOccupiedSizeEntity c;
ApplicationOccupiedSizeEntity d;
};
ApplicationOccupiedSizeEntity dat{
.storage = 5,
.app_size = 8ULL * 1024ULL * 1024ULL * 1024ULL,
.patch_size = 2ULL * 1024ULL * 1024ULL * 1024ULL,
.aoc_size = 12ULL * 1024ULL * 1024ULL,
};
ApplicationOccupiedSize oout{dat, dat, dat, dat};
LOG_ERROR(Service_NS, "(STUBBED) called");
IPC::ResponseBuilder rb{ctx, 34};
rb.Push(ResultSuccess);
rb.PushRaw(oout);
}
void IContentManagementInterface::CheckSdCardMountStatus(HLERequestContext& ctx) {
LOG_ERROR(Service_NS, "(STUBBED) called");
@ -696,27 +729,63 @@ void IContentManagementInterface::CheckSdCardMountStatus(HLERequestContext& ctx)
}
void IContentManagementInterface::GetTotalSpaceSize(HLERequestContext& ctx) {
IPC::RequestParser rp{ ctx };
const auto storage{ rp.PopEnum<FileSys::StorageId>() };
IPC::RequestParser rp{ctx};
const auto storage{rp.PopEnum<FileSys::StorageId>()};
LOG_INFO(Service_Capture, "called, storage={}", storage);
IPC::ResponseBuilder rb{ ctx, 4 };
IPC::ResponseBuilder rb{ctx, 4};
rb.Push(ResultSuccess);
rb.Push<u64>(system.GetFileSystemController().GetTotalSpaceSize(storage));
}
void IContentManagementInterface::GetFreeSpaceSize(HLERequestContext& ctx) {
IPC::RequestParser rp{ ctx };
const auto storage{ rp.PopEnum<FileSys::StorageId>() };
IPC::RequestParser rp{ctx};
const auto storage{rp.PopEnum<FileSys::StorageId>()};
LOG_INFO(Service_Capture, "called, storage={}", storage);
IPC::ResponseBuilder rb{ ctx, 4 };
IPC::ResponseBuilder rb{ctx, 4};
rb.Push(ResultSuccess);
rb.Push<u64>(system.GetFileSystemController().GetFreeSpaceSize(storage));
}
DynamicRightsInterface::DynamicRightsInterface(Core::System& system_)
: ServiceFramework{system_, "DynamicRightsInterface"} {
// clang-format off
static const FunctionInfo functions[] = {
{0, nullptr, "RequestApplicationRightsOnServer"},
{1, nullptr, "RequestAssignRights"},
{4, nullptr, "DeprecatedRequestAssignRightsToResume"},
{5, nullptr, "VerifyActivatedRightsOwners"},
{6, nullptr, "DeprecatedGetApplicationRightsStatus"},
{7, nullptr, "RequestPrefetchForDynamicRights"},
{8, nullptr, "GetDynamicRightsState"},
{9, nullptr, "RequestApplicationRightsOnServerToResume"},
{10, nullptr, "RequestAssignRightsToResume"},
{11, nullptr, "GetActivatedRightsUsers"},
{12, nullptr, "GetApplicationRightsStatus"},
{13, nullptr, "GetRunningApplicationStatus"},
{14, nullptr, "SelectApplicationLicense"},
{15, nullptr, "RequestContentsAuthorizationToken"},
{16, nullptr, "QualifyUser"},
{17, nullptr, "QualifyUserWithProcessId"},
{18, nullptr, "NotifyApplicationRightsCheckStart"},
{19, nullptr, "UpdateUserList"},
{20, nullptr, "IsRightsLostUser"},
{21, nullptr, "SetRequiredAddOnContentsOnContentsAvailabilityTransition"},
{22, nullptr, "GetLimitedApplicationLicense"},
{23, nullptr, "GetLimitedApplicationLicenseUpgradableEvent"},
{24, nullptr, "NotifyLimitedApplicationLicenseUpgradableEventForDebug"},
{25, nullptr, "RequestProceedDynamicRightsState"},
};
// clang-format on
RegisterHandlers(functions);
}
DynamicRightsInterface::~DynamicRightsInterface() = default;
IDocumentInterface::IDocumentInterface(Core::System& system_)
: ServiceFramework{system_, "IDocumentInterface"} {
// clang-format off
@ -769,7 +838,7 @@ IDownloadTaskInterface::IDownloadTaskInterface(Core::System& system_)
{705, nullptr, "RequestDownloadTaskListData"},
{706, nullptr, "TryCommitCurrentApplicationDownloadTask"},
{707, &IDownloadTaskInterface::EnableAutoCommit, "EnableAutoCommit"},
{708, nullptr, "DisableAutoCommit"},
{708, &IDownloadTaskInterface::DisableAutoCommit, "DisableAutoCommit"},
{709, nullptr, "TriggerDynamicCommitEvent"},
};
// clang-format on
@ -784,6 +853,11 @@ void IDownloadTaskInterface::EnableAutoCommit(HLERequestContext& ctx) {
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(ResultSuccess);
}
void IDownloadTaskInterface::DisableAutoCommit(HLERequestContext& ctx) {
LOG_ERROR(Service_SET, "called");
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(ResultSuccess);
}
IECommerceInterface::IECommerceInterface(Core::System& system_)
: ServiceFramework{system_, "IECommerceInterface"} {
@ -863,7 +937,7 @@ IReadOnlyApplicationControlDataInterface::IReadOnlyApplicationControlDataInterfa
// clang-format off
static const FunctionInfo functions[] = {
{0, &IReadOnlyApplicationControlDataInterface::GetApplicationControlData, "GetApplicationControlData"},
{1, nullptr, "GetApplicationDesiredLanguage"},
{1, &IReadOnlyApplicationControlDataInterface::GetApplicationDesiredLanguage, "GetApplicationDesiredLanguage"},
{2, nullptr, "ConvertApplicationLanguageToLanguageCode"},
{3, nullptr, "ConvertLanguageCodeToApplicationLanguage"},
{4, nullptr, "SelectApplicationDesiredLanguage"},
@ -876,36 +950,121 @@ IReadOnlyApplicationControlDataInterface::IReadOnlyApplicationControlDataInterfa
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<u8> nacp_data{};
const auto parameters{rp.PopRaw<RequestParameters>()};
const auto result =
system.GetARPManager().GetControlProperty(&nacp_data, parameters.application_id);
const auto flag = rp.PopRaw<u64>();
const auto title_id = rp.PopRaw<u64>();
const auto size = ctx.GetWriteBufferSize();
if (result == ResultSuccess) {
ctx.WriteBuffer(nacp_data.data(), nacp_data.size());
LOG_ERROR(Service_NS, "called with flag={:016X}, title_id={:016X}", flag, title_id);
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(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<u64>(0x4000, size));
}
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(result);
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<u32>(static_cast<u32>(out.size()));
}
void IReadOnlyApplicationControlDataInterface::GetApplicationDesiredLanguage(
HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
const auto supported_languages = rp.Pop<u32>();
u8 desired_language{};
const auto res = GetApplicationDesiredLanguage(&desired_language, supported_languages);
if (res == ResultSuccess) {
IPC::ResponseBuilder rb{ctx, 3};
rb.Push(ResultSuccess);
rb.Push<u32>(desired_language);
} else {
IPC::ResponseBuilder rb{ctx, 2};
rb.Push(res);
}
}
Result IReadOnlyApplicationControlDataInterface::GetApplicationDesiredLanguage(
u8* out_desired_language, const u32 supported_languages) {
LOG_ERROR(Service_NS, "called with supported_languages={:08X}", supported_languages);
// Get language code from settings
const auto language_code =
Set::GetLanguageCodeFromIndex(static_cast<s32>(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<u8>(lang);
return ResultSuccess;
}
}
LOG_ERROR(Service_NS, "Could not find a valid language! supported_languages={:08X}",
supported_languages);
return Service::NS::ResultApplicationLanguageNotFound;
}
NS::NS(const char* name, Core::System& system_) : ServiceFramework{system_, name} {
// clang-format off
static const FunctionInfo functions[] = {
{7988, nullptr, "GetDynamicRightsInterface"},
{7988, &NS::PushInterface<DynamicRightsInterface>, "GetDynamicRightsInterface"},
{7989, &NS::PushInterface<IReadOnlyApplicationControlDataInterface>, "GetReadOnlyApplicationControlDataInterface"},
{7991, &NS::PushInterface<IReadOnlyApplicationRecordInterface>, "GetReadOnlyApplicationRecordInterface"},
{7992, &NS::PushInterface<IECommerceInterface>, "GetECommerceInterface"},

View File

@ -34,19 +34,28 @@ public:
u8 application_language);
private:
enum class ApplicationRecordType : u8 {
Installing = 2,
Installed = 3,
GameCardNotInserted = 5,
Archived = 0xB,
GameCard = 0x10,
};
struct ApplicationRecord {
u64 application_id;
u8 type;
ApplicationRecordType type;
u8 unknown;
INSERT_PADDING_BYTES(0x6);
u8 unknown2;
INSERT_PADDING_BYTES(0x7);
};
static_assert(sizeof(ApplicationRecord) == 0x18, "ApplicationRecord is an invalid size");
/// ApplicationView
struct ApplicationView {
u64 application_id; ///< ApplicationId.
u8 unk_x8[0x4]; ///< Unknown.
u32 unk; ///< Unknown.
u32 flags; ///< Flags.
u8 unk_x10[0x10]; ///< Unknown.
u32 unk_x20; ///< Unknown.
@ -81,6 +90,7 @@ private:
void GetApplicationRecordUpdateSystemEvent(HLERequestContext& ctx);
void GetApplicationControlData(HLERequestContext& ctx);
void GetGameCardMountFailureEvent(HLERequestContext& ctx);
void IsAnyApplicationEntityInstalled(HLERequestContext& ctx);
void GetApplicationView(HLERequestContext& ctx);
void GetApplicationViewWithPromotionInfo(HLERequestContext& ctx);
void CheckSdCardMountStatus(HLERequestContext& ctx);
@ -110,6 +120,7 @@ public:
~IContentManagementInterface() override;
private:
void CalculateApplicationOccupiedSize(HLERequestContext& ctx);
void CheckSdCardMountStatus(HLERequestContext& ctx);
void GetTotalSpaceSize(HLERequestContext& ctx);
void GetFreeSpaceSize(HLERequestContext& ctx);
@ -125,6 +136,12 @@ private:
void GetRunningApplicationProgramId(HLERequestContext& ctx);
};
class DynamicRightsInterface final : public ServiceFramework<DynamicRightsInterface> {
public:
explicit DynamicRightsInterface(Core::System& system_);
~DynamicRightsInterface() override;
};
class IDownloadTaskInterface final : public ServiceFramework<IDownloadTaskInterface> {
public:
explicit IDownloadTaskInterface(Core::System& system_);
@ -132,6 +149,7 @@ public:
private:
void EnableAutoCommit(HLERequestContext& ctx);
void DisableAutoCommit(HLERequestContext& ctx);
};
class IECommerceInterface final : public ServiceFramework<IECommerceInterface> {
@ -165,6 +183,8 @@ public:
private:
void GetApplicationControlData(HLERequestContext& ctx);
void GetApplicationDesiredLanguage(HLERequestContext& ctx);
Result GetApplicationDesiredLanguage(u8* out_desired_language, u32 supported_languages);
};
class NS final : public ServiceFramework<NS> {