display titles
This commit is contained in:
@ -422,8 +422,17 @@ void IGeneralService::GetCurrentNetworkProfile(HLERequestContext& ctx) {
|
|||||||
void IGeneralService::EnumerateNetworkInterfaces(HLERequestContext& ctx) {
|
void IGeneralService::EnumerateNetworkInterfaces(HLERequestContext& ctx) {
|
||||||
LOG_ERROR(Service_NIFM, "(STUBBED) called");
|
LOG_ERROR(Service_NIFM, "(STUBBED) called");
|
||||||
|
|
||||||
IPC::ResponseBuilder rb{ctx, 2};
|
IPC::ResponseBuilder rb{ctx, 3};
|
||||||
rb.Push(ResultSuccess);
|
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);
|
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) {
|
void IGeneralService::GetCurrentAccessPoint(HLERequestContext& ctx) {
|
||||||
LOG_ERROR(Service_NIFM, "(STUBBED) called");
|
LOG_ERROR(Service_NIFM, "(STUBBED) called");
|
||||||
|
|
||||||
@ -600,7 +617,7 @@ IGeneralService::IGeneralService(Core::System& system_)
|
|||||||
{4, &IGeneralService::CreateRequest, "CreateRequest"},
|
{4, &IGeneralService::CreateRequest, "CreateRequest"},
|
||||||
{5, &IGeneralService::GetCurrentNetworkProfile, "GetCurrentNetworkProfile"},
|
{5, &IGeneralService::GetCurrentNetworkProfile, "GetCurrentNetworkProfile"},
|
||||||
{6, &IGeneralService::EnumerateNetworkInterfaces, "EnumerateNetworkInterfaces"},
|
{6, &IGeneralService::EnumerateNetworkInterfaces, "EnumerateNetworkInterfaces"},
|
||||||
{7, nullptr, "EnumerateNetworkProfiles"},
|
{7, &IGeneralService::EnumerateNetworkProfiles, "EnumerateNetworkProfiles"},
|
||||||
{8, nullptr, "GetNetworkProfile"},
|
{8, nullptr, "GetNetworkProfile"},
|
||||||
{9, nullptr, "SetNetworkProfile"},
|
{9, nullptr, "SetNetworkProfile"},
|
||||||
{10, &IGeneralService::RemoveNetworkProfile, "RemoveNetworkProfile"},
|
{10, &IGeneralService::RemoveNetworkProfile, "RemoveNetworkProfile"},
|
||||||
@ -626,7 +643,7 @@ IGeneralService::IGeneralService(Core::System& system_)
|
|||||||
{30, nullptr, "SetEthernetCommunicationEnabledForTest"},
|
{30, nullptr, "SetEthernetCommunicationEnabledForTest"},
|
||||||
{31, nullptr, "GetTelemetorySystemEventReadableHandle"},
|
{31, nullptr, "GetTelemetorySystemEventReadableHandle"},
|
||||||
{32, nullptr, "GetTelemetryInfo"},
|
{32, nullptr, "GetTelemetryInfo"},
|
||||||
{33, nullptr, "ConfirmSystemAvailability"},
|
{33, &IGeneralService::ConfirmSystemAvailability, "ConfirmSystemAvailability"},
|
||||||
{34, nullptr, "SetBackgroundRequestEnabled"},
|
{34, nullptr, "SetBackgroundRequestEnabled"},
|
||||||
{35, nullptr, "GetScanData"},
|
{35, nullptr, "GetScanData"},
|
||||||
{36, &IGeneralService::GetCurrentAccessPoint, "GetCurrentAccessPoint"},
|
{36, &IGeneralService::GetCurrentAccessPoint, "GetCurrentAccessPoint"},
|
||||||
|
@ -28,6 +28,7 @@ private:
|
|||||||
void CreateRequest(HLERequestContext& ctx);
|
void CreateRequest(HLERequestContext& ctx);
|
||||||
void GetCurrentNetworkProfile(HLERequestContext& ctx);
|
void GetCurrentNetworkProfile(HLERequestContext& ctx);
|
||||||
void EnumerateNetworkInterfaces(HLERequestContext& ctx);
|
void EnumerateNetworkInterfaces(HLERequestContext& ctx);
|
||||||
|
void EnumerateNetworkProfiles(HLERequestContext& ctx);
|
||||||
void RemoveNetworkProfile(HLERequestContext& ctx);
|
void RemoveNetworkProfile(HLERequestContext& ctx);
|
||||||
void GetCurrentIpAddress(HLERequestContext& ctx);
|
void GetCurrentIpAddress(HLERequestContext& ctx);
|
||||||
void CreateTemporaryNetworkProfile(HLERequestContext& ctx);
|
void CreateTemporaryNetworkProfile(HLERequestContext& ctx);
|
||||||
@ -38,6 +39,7 @@ private:
|
|||||||
void IsEthernetCommunicationEnabled(HLERequestContext& ctx);
|
void IsEthernetCommunicationEnabled(HLERequestContext& ctx);
|
||||||
void IsAnyInternetRequestAccepted(HLERequestContext& ctx);
|
void IsAnyInternetRequestAccepted(HLERequestContext& ctx);
|
||||||
void IsAnyForegroundRequestAccepted(HLERequestContext& ctx);
|
void IsAnyForegroundRequestAccepted(HLERequestContext& ctx);
|
||||||
|
void ConfirmSystemAvailability(HLERequestContext& ctx);
|
||||||
void GetCurrentAccessPoint(HLERequestContext& ctx);
|
void GetCurrentAccessPoint(HLERequestContext& ctx);
|
||||||
|
|
||||||
Network::RoomNetwork& network;
|
Network::RoomNetwork& network;
|
||||||
|
@ -5,8 +5,13 @@
|
|||||||
#include "common/settings.h"
|
#include "common/settings.h"
|
||||||
#include "core/arm/debug.h"
|
#include "core/arm/debug.h"
|
||||||
#include "core/core.h"
|
#include "core/core.h"
|
||||||
|
#include "core/file_sys/content_archive.h"
|
||||||
#include "core/file_sys/control_metadata.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/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/file_sys/vfs/vfs.h"
|
||||||
#include "core/hle/service/filesystem/filesystem.h"
|
#include "core/hle/service/filesystem/filesystem.h"
|
||||||
#include "core/hle/service/glue/glue_manager.h"
|
#include "core/hle/service/glue/glue_manager.h"
|
||||||
@ -198,7 +203,7 @@ IApplicationManagerInterface::IApplicationManagerInterface(Core::System& system_
|
|||||||
{1003, nullptr, "RequestVerifyApplication"},
|
{1003, nullptr, "RequestVerifyApplication"},
|
||||||
{1004, nullptr, "CorruptContentForDebug"},
|
{1004, nullptr, "CorruptContentForDebug"},
|
||||||
{1200, nullptr, "NeedsUpdateVulnerability"},
|
{1200, nullptr, "NeedsUpdateVulnerability"},
|
||||||
{1300, nullptr, "IsAnyApplicationEntityInstalled"},
|
{1300, &IApplicationManagerInterface::IsAnyApplicationEntityInstalled, "IsAnyApplicationEntityInstalled"},
|
||||||
{1301, nullptr, "DeleteApplicationContentEntities"},
|
{1301, nullptr, "DeleteApplicationContentEntities"},
|
||||||
{1302, nullptr, "CleanupUnrecordedApplicationEntity"},
|
{1302, nullptr, "CleanupUnrecordedApplicationEntity"},
|
||||||
{1303, nullptr, "CleanupAddOnContentsWithNoRights"},
|
{1303, nullptr, "CleanupAddOnContentsWithNoRights"},
|
||||||
@ -340,7 +345,7 @@ IApplicationManagerInterface::IApplicationManagerInterface(Core::System& system_
|
|||||||
service_context.CreateEvent("IApplicationManagerInterface::GamecardMountFailureEvent");
|
service_context.CreateEvent("IApplicationManagerInterface::GamecardMountFailureEvent");
|
||||||
}
|
}
|
||||||
|
|
||||||
IApplicationManagerInterface::~IApplicationManagerInterface(){
|
IApplicationManagerInterface::~IApplicationManagerInterface() {
|
||||||
service_context.CloseEvent(record_update_system_event);
|
service_context.CloseEvent(record_update_system_event);
|
||||||
service_context.CloseEvent(gamecard_update_detection_event);
|
service_context.CloseEvent(gamecard_update_detection_event);
|
||||||
service_context.CloseEvent(gamecard_mount_status_event);
|
service_context.CloseEvent(gamecard_mount_status_event);
|
||||||
@ -353,54 +358,39 @@ void IApplicationManagerInterface::ListApplicationRecord(HLERequestContext& ctx)
|
|||||||
const auto limit = ctx.GetWriteBufferNumElements<ApplicationRecord>();
|
const auto limit = ctx.GetWriteBufferNumElements<ApplicationRecord>();
|
||||||
|
|
||||||
LOG_ERROR(Service_NS, "(STUBBED) called");
|
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_records;
|
||||||
std::vector<ApplicationRecord> application_records2;
|
u8 ii{24};
|
||||||
|
for (const auto& [slot, game] : installed_games) {
|
||||||
application_records.push_back(ApplicationRecord{
|
if (application_records.size() >= limit) {
|
||||||
.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) {
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
if (game.title_id == 0 || game.title_id < 0x0100000000001FFFull) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
if (offset > 0) {
|
if (offset > 0) {
|
||||||
offset--;
|
offset--;
|
||||||
continue;
|
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()) {
|
if (!application_records.empty()) {
|
||||||
ctx.WriteBuffer(application_records2);
|
ctx.WriteBuffer(application_records);
|
||||||
}
|
}
|
||||||
|
|
||||||
IPC::ResponseBuilder rb{ctx, 3};
|
IPC::ResponseBuilder rb{ctx, 3};
|
||||||
rb.Push(ResultSuccess);
|
rb.Push(ResultSuccess);
|
||||||
rb.Push(application_records2.size());
|
rb.Push(application_records.size());
|
||||||
}
|
}
|
||||||
void IApplicationManagerInterface::GetApplicationRecordUpdateSystemEvent(HLERequestContext& ctx) {
|
void IApplicationManagerInterface::GetApplicationRecordUpdateSystemEvent(HLERequestContext& ctx) {
|
||||||
LOG_ERROR(Service_NS, "(STUBBED) called");
|
LOG_ERROR(Service_NS, "(STUBBED) called");
|
||||||
@ -478,6 +468,14 @@ void IApplicationManagerInterface::GetGameCardMountFailureEvent(HLERequestContex
|
|||||||
rb.PushCopyObjects(gamecard_mount_failure_event->GetReadableEvent());
|
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) {
|
void IApplicationManagerInterface::GetApplicationView(HLERequestContext& ctx) {
|
||||||
std::vector<u64> application_id(ctx.GetReadBufferNumElements<u64>());
|
std::vector<u64> application_id(ctx.GetReadBufferNumElements<u64>());
|
||||||
const auto app_buffer = ctx.ReadBuffer();
|
const auto app_buffer = ctx.ReadBuffer();
|
||||||
@ -485,10 +483,12 @@ void IApplicationManagerInterface::GetApplicationView(HLERequestContext& ctx) {
|
|||||||
|
|
||||||
std::vector<ApplicationView> app_view;
|
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) {
|
for (const u64& data : application_id) {
|
||||||
app_view.push_back(ApplicationView{
|
app_view.push_back(ApplicationView{
|
||||||
.application_id = data,
|
.application_id = data,
|
||||||
|
.unk = 0x70000,
|
||||||
|
.flags = 0x401f17,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -505,12 +505,14 @@ void IApplicationManagerInterface::GetApplicationViewWithPromotionInfo(HLEReques
|
|||||||
|
|
||||||
std::vector<ApplicationViewWithPromotionInfo> app_view;
|
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) {
|
for (const u64& data : application_id) {
|
||||||
app_view.push_back(ApplicationViewWithPromotionInfo{
|
app_view.push_back(ApplicationViewWithPromotionInfo{
|
||||||
.view{
|
.view{
|
||||||
.application_id = data,
|
.application_id = data,
|
||||||
|
.unk = 0x70000,
|
||||||
|
.flags = 0x401f17,
|
||||||
},
|
},
|
||||||
.promotion = {},
|
.promotion = {},
|
||||||
});
|
});
|
||||||
@ -672,7 +674,7 @@ IContentManagementInterface::IContentManagementInterface(Core::System& system_)
|
|||||||
: ServiceFramework{system_, "IContentManagementInterface"} {
|
: ServiceFramework{system_, "IContentManagementInterface"} {
|
||||||
// clang-format off
|
// clang-format off
|
||||||
static const FunctionInfo functions[] = {
|
static const FunctionInfo functions[] = {
|
||||||
{11, nullptr, "CalculateApplicationOccupiedSize"},
|
{11, &IContentManagementInterface::CalculateApplicationOccupiedSize, "CalculateApplicationOccupiedSize"},
|
||||||
{43, &IContentManagementInterface::CheckSdCardMountStatus, "CheckSdCardMountStatus"},
|
{43, &IContentManagementInterface::CheckSdCardMountStatus, "CheckSdCardMountStatus"},
|
||||||
{47, &IContentManagementInterface::GetTotalSpaceSize, "GetTotalSpaceSize"},
|
{47, &IContentManagementInterface::GetTotalSpaceSize, "GetTotalSpaceSize"},
|
||||||
{48, &IContentManagementInterface::GetFreeSpaceSize, "GetFreeSpaceSize"},
|
{48, &IContentManagementInterface::GetFreeSpaceSize, "GetFreeSpaceSize"},
|
||||||
@ -688,6 +690,37 @@ IContentManagementInterface::IContentManagementInterface(Core::System& system_)
|
|||||||
|
|
||||||
IContentManagementInterface::~IContentManagementInterface() = default;
|
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) {
|
void IContentManagementInterface::CheckSdCardMountStatus(HLERequestContext& ctx) {
|
||||||
LOG_ERROR(Service_NS, "(STUBBED) called");
|
LOG_ERROR(Service_NS, "(STUBBED) called");
|
||||||
|
|
||||||
@ -696,27 +729,63 @@ void IContentManagementInterface::CheckSdCardMountStatus(HLERequestContext& ctx)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void IContentManagementInterface::GetTotalSpaceSize(HLERequestContext& ctx) {
|
void IContentManagementInterface::GetTotalSpaceSize(HLERequestContext& ctx) {
|
||||||
IPC::RequestParser rp{ ctx };
|
IPC::RequestParser rp{ctx};
|
||||||
const auto storage{ rp.PopEnum<FileSys::StorageId>() };
|
const auto storage{rp.PopEnum<FileSys::StorageId>()};
|
||||||
|
|
||||||
LOG_INFO(Service_Capture, "called, storage={}", storage);
|
LOG_INFO(Service_Capture, "called, storage={}", storage);
|
||||||
|
|
||||||
IPC::ResponseBuilder rb{ ctx, 4 };
|
IPC::ResponseBuilder rb{ctx, 4};
|
||||||
rb.Push(ResultSuccess);
|
rb.Push(ResultSuccess);
|
||||||
rb.Push<u64>(system.GetFileSystemController().GetTotalSpaceSize(storage));
|
rb.Push<u64>(system.GetFileSystemController().GetTotalSpaceSize(storage));
|
||||||
}
|
}
|
||||||
|
|
||||||
void IContentManagementInterface::GetFreeSpaceSize(HLERequestContext& ctx) {
|
void IContentManagementInterface::GetFreeSpaceSize(HLERequestContext& ctx) {
|
||||||
IPC::RequestParser rp{ ctx };
|
IPC::RequestParser rp{ctx};
|
||||||
const auto storage{ rp.PopEnum<FileSys::StorageId>() };
|
const auto storage{rp.PopEnum<FileSys::StorageId>()};
|
||||||
|
|
||||||
LOG_INFO(Service_Capture, "called, storage={}", storage);
|
LOG_INFO(Service_Capture, "called, storage={}", storage);
|
||||||
|
|
||||||
IPC::ResponseBuilder rb{ ctx, 4 };
|
IPC::ResponseBuilder rb{ctx, 4};
|
||||||
rb.Push(ResultSuccess);
|
rb.Push(ResultSuccess);
|
||||||
rb.Push<u64>(system.GetFileSystemController().GetFreeSpaceSize(storage));
|
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_)
|
IDocumentInterface::IDocumentInterface(Core::System& system_)
|
||||||
: ServiceFramework{system_, "IDocumentInterface"} {
|
: ServiceFramework{system_, "IDocumentInterface"} {
|
||||||
// clang-format off
|
// clang-format off
|
||||||
@ -769,7 +838,7 @@ IDownloadTaskInterface::IDownloadTaskInterface(Core::System& system_)
|
|||||||
{705, nullptr, "RequestDownloadTaskListData"},
|
{705, nullptr, "RequestDownloadTaskListData"},
|
||||||
{706, nullptr, "TryCommitCurrentApplicationDownloadTask"},
|
{706, nullptr, "TryCommitCurrentApplicationDownloadTask"},
|
||||||
{707, &IDownloadTaskInterface::EnableAutoCommit, "EnableAutoCommit"},
|
{707, &IDownloadTaskInterface::EnableAutoCommit, "EnableAutoCommit"},
|
||||||
{708, nullptr, "DisableAutoCommit"},
|
{708, &IDownloadTaskInterface::DisableAutoCommit, "DisableAutoCommit"},
|
||||||
{709, nullptr, "TriggerDynamicCommitEvent"},
|
{709, nullptr, "TriggerDynamicCommitEvent"},
|
||||||
};
|
};
|
||||||
// clang-format on
|
// clang-format on
|
||||||
@ -784,6 +853,11 @@ void IDownloadTaskInterface::EnableAutoCommit(HLERequestContext& ctx) {
|
|||||||
IPC::ResponseBuilder rb{ctx, 2};
|
IPC::ResponseBuilder rb{ctx, 2};
|
||||||
rb.Push(ResultSuccess);
|
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_)
|
IECommerceInterface::IECommerceInterface(Core::System& system_)
|
||||||
: ServiceFramework{system_, "IECommerceInterface"} {
|
: ServiceFramework{system_, "IECommerceInterface"} {
|
||||||
@ -863,7 +937,7 @@ IReadOnlyApplicationControlDataInterface::IReadOnlyApplicationControlDataInterfa
|
|||||||
// clang-format off
|
// clang-format off
|
||||||
static const FunctionInfo functions[] = {
|
static const FunctionInfo functions[] = {
|
||||||
{0, &IReadOnlyApplicationControlDataInterface::GetApplicationControlData, "GetApplicationControlData"},
|
{0, &IReadOnlyApplicationControlDataInterface::GetApplicationControlData, "GetApplicationControlData"},
|
||||||
{1, nullptr, "GetApplicationDesiredLanguage"},
|
{1, &IReadOnlyApplicationControlDataInterface::GetApplicationDesiredLanguage, "GetApplicationDesiredLanguage"},
|
||||||
{2, nullptr, "ConvertApplicationLanguageToLanguageCode"},
|
{2, nullptr, "ConvertApplicationLanguageToLanguageCode"},
|
||||||
{3, nullptr, "ConvertLanguageCodeToApplicationLanguage"},
|
{3, nullptr, "ConvertLanguageCodeToApplicationLanguage"},
|
||||||
{4, nullptr, "SelectApplicationDesiredLanguage"},
|
{4, nullptr, "SelectApplicationDesiredLanguage"},
|
||||||
@ -876,36 +950,121 @@ IReadOnlyApplicationControlDataInterface::IReadOnlyApplicationControlDataInterfa
|
|||||||
IReadOnlyApplicationControlDataInterface::~IReadOnlyApplicationControlDataInterface() = default;
|
IReadOnlyApplicationControlDataInterface::~IReadOnlyApplicationControlDataInterface() = default;
|
||||||
|
|
||||||
void IReadOnlyApplicationControlDataInterface::GetApplicationControlData(HLERequestContext& ctx) {
|
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};
|
IPC::RequestParser rp{ctx};
|
||||||
std::vector<u8> nacp_data{};
|
const auto flag = rp.PopRaw<u64>();
|
||||||
const auto parameters{rp.PopRaw<RequestParameters>()};
|
const auto title_id = rp.PopRaw<u64>();
|
||||||
const auto result =
|
const auto size = ctx.GetWriteBufferSize();
|
||||||
system.GetARPManager().GetControlProperty(&nacp_data, parameters.application_id);
|
|
||||||
|
|
||||||
if (result == ResultSuccess) {
|
LOG_ERROR(Service_NS, "called with flag={:016X}, title_id={:016X}", flag, title_id);
|
||||||
ctx.WriteBuffer(nacp_data.data(), nacp_data.size());
|
|
||||||
|
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};
|
if (control.second != nullptr) {
|
||||||
rb.Push(result);
|
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} {
|
NS::NS(const char* name, Core::System& system_) : ServiceFramework{system_, name} {
|
||||||
// clang-format off
|
// clang-format off
|
||||||
static const FunctionInfo functions[] = {
|
static const FunctionInfo functions[] = {
|
||||||
{7988, nullptr, "GetDynamicRightsInterface"},
|
{7988, &NS::PushInterface<DynamicRightsInterface>, "GetDynamicRightsInterface"},
|
||||||
{7989, &NS::PushInterface<IReadOnlyApplicationControlDataInterface>, "GetReadOnlyApplicationControlDataInterface"},
|
{7989, &NS::PushInterface<IReadOnlyApplicationControlDataInterface>, "GetReadOnlyApplicationControlDataInterface"},
|
||||||
{7991, &NS::PushInterface<IReadOnlyApplicationRecordInterface>, "GetReadOnlyApplicationRecordInterface"},
|
{7991, &NS::PushInterface<IReadOnlyApplicationRecordInterface>, "GetReadOnlyApplicationRecordInterface"},
|
||||||
{7992, &NS::PushInterface<IECommerceInterface>, "GetECommerceInterface"},
|
{7992, &NS::PushInterface<IECommerceInterface>, "GetECommerceInterface"},
|
||||||
|
@ -34,19 +34,28 @@ public:
|
|||||||
u8 application_language);
|
u8 application_language);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
enum class ApplicationRecordType : u8 {
|
||||||
|
Installing = 2,
|
||||||
|
Installed = 3,
|
||||||
|
GameCardNotInserted = 5,
|
||||||
|
Archived = 0xB,
|
||||||
|
GameCard = 0x10,
|
||||||
|
};
|
||||||
|
|
||||||
struct ApplicationRecord {
|
struct ApplicationRecord {
|
||||||
u64 application_id;
|
u64 application_id;
|
||||||
u8 type;
|
ApplicationRecordType type;
|
||||||
u8 unknown;
|
u8 unknown;
|
||||||
INSERT_PADDING_BYTES(0x6);
|
INSERT_PADDING_BYTES(0x6);
|
||||||
u8 unknown2;
|
u8 unknown2;
|
||||||
INSERT_PADDING_BYTES(0x7);
|
INSERT_PADDING_BYTES(0x7);
|
||||||
};
|
};
|
||||||
|
static_assert(sizeof(ApplicationRecord) == 0x18, "ApplicationRecord is an invalid size");
|
||||||
|
|
||||||
/// ApplicationView
|
/// ApplicationView
|
||||||
struct ApplicationView {
|
struct ApplicationView {
|
||||||
u64 application_id; ///< ApplicationId.
|
u64 application_id; ///< ApplicationId.
|
||||||
u8 unk_x8[0x4]; ///< Unknown.
|
u32 unk; ///< Unknown.
|
||||||
u32 flags; ///< Flags.
|
u32 flags; ///< Flags.
|
||||||
u8 unk_x10[0x10]; ///< Unknown.
|
u8 unk_x10[0x10]; ///< Unknown.
|
||||||
u32 unk_x20; ///< Unknown.
|
u32 unk_x20; ///< Unknown.
|
||||||
@ -81,6 +90,7 @@ private:
|
|||||||
void GetApplicationRecordUpdateSystemEvent(HLERequestContext& ctx);
|
void GetApplicationRecordUpdateSystemEvent(HLERequestContext& ctx);
|
||||||
void GetApplicationControlData(HLERequestContext& ctx);
|
void GetApplicationControlData(HLERequestContext& ctx);
|
||||||
void GetGameCardMountFailureEvent(HLERequestContext& ctx);
|
void GetGameCardMountFailureEvent(HLERequestContext& ctx);
|
||||||
|
void IsAnyApplicationEntityInstalled(HLERequestContext& ctx);
|
||||||
void GetApplicationView(HLERequestContext& ctx);
|
void GetApplicationView(HLERequestContext& ctx);
|
||||||
void GetApplicationViewWithPromotionInfo(HLERequestContext& ctx);
|
void GetApplicationViewWithPromotionInfo(HLERequestContext& ctx);
|
||||||
void CheckSdCardMountStatus(HLERequestContext& ctx);
|
void CheckSdCardMountStatus(HLERequestContext& ctx);
|
||||||
@ -110,6 +120,7 @@ public:
|
|||||||
~IContentManagementInterface() override;
|
~IContentManagementInterface() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void CalculateApplicationOccupiedSize(HLERequestContext& ctx);
|
||||||
void CheckSdCardMountStatus(HLERequestContext& ctx);
|
void CheckSdCardMountStatus(HLERequestContext& ctx);
|
||||||
void GetTotalSpaceSize(HLERequestContext& ctx);
|
void GetTotalSpaceSize(HLERequestContext& ctx);
|
||||||
void GetFreeSpaceSize(HLERequestContext& ctx);
|
void GetFreeSpaceSize(HLERequestContext& ctx);
|
||||||
@ -125,6 +136,12 @@ private:
|
|||||||
void GetRunningApplicationProgramId(HLERequestContext& ctx);
|
void GetRunningApplicationProgramId(HLERequestContext& ctx);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class DynamicRightsInterface final : public ServiceFramework<DynamicRightsInterface> {
|
||||||
|
public:
|
||||||
|
explicit DynamicRightsInterface(Core::System& system_);
|
||||||
|
~DynamicRightsInterface() override;
|
||||||
|
};
|
||||||
|
|
||||||
class IDownloadTaskInterface final : public ServiceFramework<IDownloadTaskInterface> {
|
class IDownloadTaskInterface final : public ServiceFramework<IDownloadTaskInterface> {
|
||||||
public:
|
public:
|
||||||
explicit IDownloadTaskInterface(Core::System& system_);
|
explicit IDownloadTaskInterface(Core::System& system_);
|
||||||
@ -132,6 +149,7 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
void EnableAutoCommit(HLERequestContext& ctx);
|
void EnableAutoCommit(HLERequestContext& ctx);
|
||||||
|
void DisableAutoCommit(HLERequestContext& ctx);
|
||||||
};
|
};
|
||||||
|
|
||||||
class IECommerceInterface final : public ServiceFramework<IECommerceInterface> {
|
class IECommerceInterface final : public ServiceFramework<IECommerceInterface> {
|
||||||
@ -165,6 +183,8 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
void GetApplicationControlData(HLERequestContext& ctx);
|
void GetApplicationControlData(HLERequestContext& ctx);
|
||||||
|
void GetApplicationDesiredLanguage(HLERequestContext& ctx);
|
||||||
|
Result GetApplicationDesiredLanguage(u8* out_desired_language, u32 supported_languages);
|
||||||
};
|
};
|
||||||
|
|
||||||
class NS final : public ServiceFramework<NS> {
|
class NS final : public ServiceFramework<NS> {
|
||||||
|
Reference in New Issue
Block a user