citra-emu
/
citra-canary
Archived
1
0
Fork 0

nim: Fully stub nim:u service. (#6290)

This commit is contained in:
Steveice10 2023-02-17 10:30:47 -08:00 committed by GitHub
parent bf73cb57ca
commit cda358443f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 1215 additions and 26 deletions

View File

@ -3,9 +3,9 @@
// Refer to the license.txt file included.
#include "common/archives.h"
#include "common/string_util.h"
#include "core/core.h"
#include "core/hle/ipc_helpers.h"
#include "core/hle/kernel/event.h"
#include "core/hle/service/nim/nim_u.h"
SERVICE_CONSTRUCT_IMPL(Service::NIM::NIM_U)
@ -13,37 +13,736 @@ SERIALIZE_EXPORT_IMPL(Service::NIM::NIM_U)
namespace Service::NIM {
enum class SystemUpdateState : u32 {
NotInitialized,
StartingSystemUpdate,
FetchingHashAndAccountStatus,
InstallingNewTickets,
InstallingTitles,
UpdateComplete,
SystemUpdatesDisabled,
Unknown7,
Unknown8,
};
struct SystemUpdateProgress {
SystemUpdateState state;
u32 last_operation_result;
u64 current_title_downloaded_bytes;
u64 current_title_total_bytes;
u64 titles_downloaded;
u64 titles_total;
};
static_assert(sizeof(SystemUpdateProgress) == 0x28, "SystemUpdateProgress structure size is wrong");
enum class TitleDownloadState : u32 {
NotInitialized,
StartingTitleDownload,
InstallingTmd,
CommittingTmd,
InstallingContents,
ContentsInstalled,
CommittingTitles,
Finished,
Unknown8,
Unknown9,
BackgroundDownloadFailed,
};
struct TitleDownloadProgress {
TitleDownloadState state;
u32 last_operation_result;
u64 downloaded_bytes;
u64 total_bytes;
};
static_assert(sizeof(TitleDownloadProgress) == 0x18,
"TitleDownloadProgress structure size is wrong");
struct TitleDownloadConfig {
u64 title_id;
u32 title_version;
u32 unknown_1;
u8 age_rating;
u8 media_type;
INSERT_PADDING_BYTES(2);
u32 unknown_2;
};
static_assert(sizeof(TitleDownloadConfig) == 0x18, "TitleDownloadConfig structure size is wrong");
#pragma pack(1)
struct BackgroundTitleDownloadConfig {
TitleDownloadConfig base_config;
u8 unknown_1;
u8 unknown_2;
INSERT_PADDING_BYTES(6);
u64 requester_title_id;
std::array<u16, 0x48> title_name;
u16 title_name_terminator;
std::array<u16, 0x24> developer_name;
u16 developer_name_terminator;
};
static_assert(sizeof(BackgroundTitleDownloadConfig) == 0x104,
"BackgroundTitleDownloadConfig structure size is wrong");
struct BackgroundTitleDownloadTaskInfo {
BackgroundTitleDownloadConfig config;
INSERT_PADDING_BYTES(4);
TitleDownloadProgress progress;
};
static_assert(sizeof(BackgroundTitleDownloadTaskInfo) == 0x120,
"BackgroundTitleDownloadTaskInfo structure size is wrong");
struct AutoTitleDownloadTaskInfo {
u64 task_id;
u64 title_id;
u32 title_version;
u8 unknown_4[0x14];
u64 required_size;
u32 last_operation_result_code;
u32 last_operation_customer_support_code;
std::array<u16, 0x48> title_name;
u16 title_name_terminator;
std::array<u16, 0x24> developer_name;
u16 developer_name_terminator;
u8 unknown_5[0x24];
};
static_assert(sizeof(AutoTitleDownloadTaskInfo) == 0x138,
"AutoTitleDownloadTaskInfo structure size is wrong");
struct AutoDbgDat {
u8 unknown_1[0x4];
u32 num_auto_download_tasks;
u8 unknown_2[0x100];
};
static_assert(sizeof(AutoDbgDat) == 0x108, "AutoDbgDat structure size is wrong");
NIM_U::NIM_U(Core::System& system) : ServiceFramework("nim:u", 2) {
const FunctionInfo functions[] = {
{0x00010000, nullptr, "StartSysUpdate"},
{0x00020000, nullptr, "GetUpdateDownloadProgress"},
{0x00040000, nullptr, "FinishTitlesInstall"},
{0x00050000, &NIM_U::CheckForSysUpdateEvent, "CheckForSysUpdateEvent"},
{0x00090000, &NIM_U::CheckSysUpdateAvailable, "CheckSysUpdateAvailable"},
{0x000A0000, nullptr, "GetState"},
{0x000B0000, nullptr, "GetSystemTitleHash"},
{0x00010000, &NIM_U::StartNetworkUpdate, "StartNetworkUpdate"},
{0x00020000, &NIM_U::GetProgress, "GetProgress"},
{0x00030000, &NIM_U::Cancel, "Cancel"},
{0x00040000, &NIM_U::CommitSystemTitles, "CommitSystemTitles"},
{0x00050000, &NIM_U::GetBackgroundEventForMenu, "GetBackgroundEventForMenu"},
{0x00060000, &NIM_U::GetBackgroundEventForNews, "GetBackgroundEventForNews"},
{0x00070000, &NIM_U::FormatSaveData, "FormatSaveData"},
{0x00080000, &NIM_U::GetCustomerSupportCode, "GetCustomerSupportCode"},
{0x00090000, &NIM_U::IsCommittableAllSystemTitles, "IsCommittableAllSystemTitles"},
{0x000A0000, &NIM_U::GetBackgroundProgress, "GetBackgroundProgress"},
{0x000B0000, &NIM_U::GetSavedHash, "GetSavedHash"},
{0x000C0082, &NIM_U::UnregisterTask, "UnregisterTask"},
{0x000D0080, &NIM_U::IsRegistered, "IsRegistered"},
{0x000E0080, &NIM_U::FindTaskInfo, "FindTaskInfo"},
{0x000F0042, &NIM_U::GetTaskInfos, "GetTaskInfos"},
{0x00100000, &NIM_U::DeleteUnmanagedContexts, "DeleteUnmanagedContexts"},
{0x00110000, &NIM_U::UpdateAutoTitleDownloadTasksAsync,
"UpdateAutoTitleDownloadTasksAsync"},
{0x00120000, &NIM_U::StartPendingAutoTitleDownloadTasksAsync,
"StartPendingAutoTitleDownloadTasksAsync"},
{0x00130000, &NIM_U::GetAsyncResult, "GetAsyncResult"},
{0x00140000, &NIM_U::CancelAsyncCall, "CancelAsyncCall"},
{0x00150000, &NIM_U::IsPendingAutoTitleDownloadTasks, "IsPendingAutoTitleDownloadTasks"},
{0x00160000, &NIM_U::GetNumAutoTitleDownloadTasks, "GetNumAutoTitleDownloadTasks"},
{0x00170042, &NIM_U::GetAutoTitleDownloadTaskInfos, "GetAutoTitleDownloadTaskInfos"},
{0x00180080, &NIM_U::CancelAutoTitleDownloadTask, "CancelAutoTitleDownloadTask"},
{0x00190002, &NIM_U::SetAutoDbgDat, "SetAutoDbgDat"},
{0x001A0002, &NIM_U::GetAutoDbgDat, "GetAutoDbgDat"},
{0x001B0042, &NIM_U::SetDbgTasks, "SetDbgTasks"},
{0x001C0042, &NIM_U::GetDbgTasks, "GetDbgTasks"},
{0x001D0000, &NIM_U::DeleteDbgData, "DeleteDbgData"},
{0x001E0042, &NIM_U::SetTslXml, "SetTslXml"},
{0x001F0000, &NIM_U::GetTslXmlSize, "GetTslXmlSize"},
{0x00200042, &NIM_U::GetTslXml, "GetTslXml"},
{0x00210000, &NIM_U::DeleteTslXml, "DeleteTslXml"},
{0x00220042, &NIM_U::SetDtlXml, "SetDtlXml"},
{0x00230000, &NIM_U::GetDtlXmlSize, "GetDtlXmlSize"},
{0x00240042, &NIM_U::GetDtlXml, "GetDtlXml"},
{0x00250000, &NIM_U::UpdateAccountStatus, "UpdateAccountStatus"},
{0x00260180, &NIM_U::StartTitleDownload, "StartTitleDownload"},
{0x00270000, &NIM_U::StopTitleDownload, "StopTitleDownload"},
{0x00280000, &NIM_U::GetTitleDownloadProgress, "GetTitleDownloadProgress"},
{0x00290246, &NIM_U::RegisterTask, "RegisterTask"},
{0x002A0000, &NIM_U::IsSystemUpdateAvailable, "IsSystemUpdateAvailable"},
{0x002B0000, &NIM_U::Unknown2B, "Unknown2B"},
{0x002C0000, &NIM_U::UpdateTickets, "UpdateTickets"},
{0x002D00C0, &NIM_U::DownloadTitleSeedAsync, "DownloadTitleSeedAsync"},
{0x002E0000, &NIM_U::DownloadMissingTitleSeedsAsync, "DownloadMissingTitleSeedsAsync"},
};
RegisterHandlers(functions);
nim_system_update_event =
system.Kernel().CreateEvent(Kernel::ResetType::OneShot, "NIM System Update Event");
nim_system_update_event_for_menu =
system.Kernel().CreateEvent(Kernel::ResetType::OneShot, "NIM System Update Event (Menu)");
nim_system_update_event_for_news =
system.Kernel().CreateEvent(Kernel::ResetType::OneShot, "NIM System Update Event (News)");
nim_async_completion_event =
system.Kernel().CreateEvent(Kernel::ResetType::OneShot, "NIM Async Completion Event");
}
NIM_U::~NIM_U() = default;
void NIM_U::CheckForSysUpdateEvent(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp(ctx, 0x5, 0, 0); // 0x50000
IPC::RequestBuilder rb = rp.MakeBuilder(1, 2);
void NIM_U::StartNetworkUpdate(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp(ctx, 0x1, 0, 0); // 0x10000
IPC::RequestBuilder rb = rp.MakeBuilder(1, 0);
rb.Push(RESULT_SUCCESS);
rb.PushCopyObjects(nim_system_update_event);
LOG_TRACE(Service_NIM, "called");
LOG_WARNING(Service_NIM, "(STUBBED) called");
}
void NIM_U::CheckSysUpdateAvailable(Kernel::HLERequestContext& ctx) {
void NIM_U::GetProgress(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp(ctx, 0x2, 0, 0); // 0x20000
SystemUpdateProgress progress{};
std::memset(&progress, 0, sizeof(progress));
IPC::RequestBuilder rb = rp.MakeBuilder(13, 0);
rb.Push(RESULT_SUCCESS);
rb.PushRaw(progress);
rb.Push(0);
rb.Push(0);
LOG_WARNING(Service_NIM, "(STUBBED) called");
}
void NIM_U::Cancel(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp(ctx, 0x3, 0, 0); // 0x30000
IPC::RequestBuilder rb = rp.MakeBuilder(1, 0);
rb.Push(RESULT_SUCCESS);
LOG_WARNING(Service_NIM, "(STUBBED) called");
}
void NIM_U::CommitSystemTitles(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp(ctx, 0x4, 0, 0); // 0x40000
IPC::RequestBuilder rb = rp.MakeBuilder(1, 0);
rb.Push(RESULT_SUCCESS);
LOG_WARNING(Service_NIM, "(STUBBED) called");
}
void NIM_U::GetBackgroundEventForMenu(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp(ctx, 0x5, 0, 0); // 0x50000
IPC::RequestBuilder rb = rp.MakeBuilder(1, 2);
rb.Push(RESULT_SUCCESS);
rb.PushCopyObjects(nim_system_update_event_for_menu);
LOG_WARNING(Service_NIM, "(STUBBED) called");
}
void NIM_U::GetBackgroundEventForNews(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp(ctx, 0x6, 0, 0); // 0x60000
IPC::RequestBuilder rb = rp.MakeBuilder(1, 2);
rb.Push(RESULT_SUCCESS);
rb.PushCopyObjects(nim_system_update_event_for_news);
LOG_WARNING(Service_NIM, "(STUBBED) called");
}
void NIM_U::FormatSaveData(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp(ctx, 0x7, 0, 0); // 0x70000
IPC::RequestBuilder rb = rp.MakeBuilder(1, 0);
rb.Push(RESULT_SUCCESS);
LOG_WARNING(Service_NIM, "(STUBBED) called");
}
void NIM_U::GetCustomerSupportCode(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp(ctx, 0x8, 0, 0); // 0x80000
IPC::RequestBuilder rb = rp.MakeBuilder(2, 0);
rb.Push(RESULT_SUCCESS);
rb.Push(0); // Customer support code
LOG_WARNING(Service_NIM, "(STUBBED) called");
}
void NIM_U::IsCommittableAllSystemTitles(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp(ctx, 0x9, 0, 0); // 0x90000
IPC::RequestBuilder rb = rp.MakeBuilder(2, 0);
rb.Push(RESULT_SUCCESS);
rb.Push(false); // No update available
rb.Push(false);
LOG_WARNING(Service_NIM, "(STUBBED) called");
}
void NIM_U::GetBackgroundProgress(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp(ctx, 0xA, 0, 0); // 0xA0000
SystemUpdateProgress progress{};
std::memset(&progress, 0, sizeof(progress));
IPC::RequestBuilder rb = rp.MakeBuilder(13, 0);
rb.Push(RESULT_SUCCESS);
rb.PushRaw(progress);
rb.Push(0);
rb.Push(0);
LOG_WARNING(Service_NIM, "(STUBBED) called");
}
void NIM_U::GetSavedHash(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp(ctx, 0xB, 0, 0); // 0xB0000
std::array<char, 0x24> hash{};
std::memset(&hash, 0, sizeof(hash));
IPC::RequestBuilder rb = rp.MakeBuilder(10, 0);
rb.Push(RESULT_SUCCESS);
rb.PushRaw(hash);
LOG_WARNING(Service_NIM, "(STUBBED) called");
}
void NIM_U::UnregisterTask(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp(ctx, 0xC, 2, 2); // 0xC0082
const u64 title_id = rp.Pop<u64>();
const u32 process_id = rp.PopPID();
IPC::RequestBuilder rb = rp.MakeBuilder(1, 0);
rb.Push(ResultCode(ErrorDescription::NotFound, ErrorModule::NIM, ErrorSummary::NotFound,
ErrorLevel::Status));
LOG_WARNING(Service_NIM, "(STUBBED) called title_id={:016X}, process_id={:08X}", title_id,
process_id);
}
void NIM_U::IsRegistered(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp(ctx, 0xD, 2, 0); // 0xD0080
const u64 title_id = rp.Pop<u64>();
IPC::RequestBuilder rb = rp.MakeBuilder(2, 0);
rb.Push(RESULT_SUCCESS);
rb.Push(false);
LOG_WARNING(Service_NIM, "(STUBBED) called title_id={:016X}", title_id);
}
void NIM_U::FindTaskInfo(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp(ctx, 0xE, 2, 0); // 0xE0080
const u64 title_id = rp.Pop<u64>();
std::vector<u8> buffer(0x120, 0);
IPC::RequestBuilder rb = rp.MakeBuilder(1, 2);
rb.Push(ResultCode(ErrorDescription::NotFound, ErrorModule::NIM, ErrorSummary::NotFound,
ErrorLevel::Status));
rb.PushStaticBuffer(std::move(buffer), 0);
LOG_WARNING(Service_NIM, "(STUBBED) called title_id={:016X}", title_id);
}
void NIM_U::GetTaskInfos(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp(ctx, 0xF, 1, 2); // 0xF0042
const u64 max_task_infos = rp.Pop<u32>();
auto& task_infos_buffer = rp.PopMappedBuffer();
IPC::RequestBuilder rb = rp.MakeBuilder(2, 2);
rb.Push(RESULT_SUCCESS);
rb.Push(0);
rb.PushMappedBuffer(task_infos_buffer);
LOG_WARNING(Service_NIM, "(STUBBED) called max_task_infos={:08X}, task_infos_buffer=0x{:08X}",
max_task_infos, task_infos_buffer.GetId());
}
void NIM_U::DeleteUnmanagedContexts(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp(ctx, 0x10, 0, 0); // 0x100000
IPC::RequestBuilder rb = rp.MakeBuilder(1, 0);
rb.Push(RESULT_SUCCESS);
LOG_WARNING(Service_NIM, "(STUBBED) called");
}
void NIM_U::UpdateAutoTitleDownloadTasksAsync(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp(ctx, 0x11, 0, 0); // 0x110000
// Since this is a stub, signal the completion event so the caller won't get stuck waiting.
nim_async_completion_event->Signal();
IPC::RequestBuilder rb = rp.MakeBuilder(1, 2);
rb.Push(RESULT_SUCCESS);
rb.PushCopyObjects(nim_async_completion_event);
LOG_WARNING(Service_NIM, "(STUBBED) called");
}
void NIM_U::StartPendingAutoTitleDownloadTasksAsync(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp(ctx, 0x11, 0, 0); // 0x120000
// Since this is a stub, signal the completion event so the caller won't get stuck waiting.
nim_async_completion_event->Signal();
IPC::RequestBuilder rb = rp.MakeBuilder(1, 2);
rb.Push(RESULT_SUCCESS);
rb.PushCopyObjects(nim_async_completion_event);
LOG_WARNING(Service_NIM, "(STUBBED) called");
}
void NIM_U::GetAsyncResult(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp(ctx, 0x13, 0, 0); // 0x130000
IPC::RequestBuilder rb = rp.MakeBuilder(3, 0);
rb.Push(RESULT_SUCCESS);
rb.Push(RESULT_SUCCESS);
rb.Push(0);
LOG_WARNING(Service_NIM, "(STUBBED) called");
}
void NIM_U::CancelAsyncCall(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp(ctx, 0x14, 0, 0); // 0x140000
IPC::RequestBuilder rb = rp.MakeBuilder(1, 0);
rb.Push(RESULT_SUCCESS);
LOG_WARNING(Service_NIM, "(STUBBED) called");
}
void NIM_U::IsPendingAutoTitleDownloadTasks(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp(ctx, 0x15, 0, 0); // 0x150000
IPC::RequestBuilder rb = rp.MakeBuilder(2, 0);
rb.Push(RESULT_SUCCESS);
rb.Push(false);
LOG_WARNING(Service_NIM, "(STUBBED) called");
}
void NIM_U::GetNumAutoTitleDownloadTasks(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp(ctx, 0x16, 0, 0); // 0x160000
IPC::RequestBuilder rb = rp.MakeBuilder(2, 0);
rb.Push(RESULT_SUCCESS);
rb.Push(0);
LOG_WARNING(Service_NIM, "(STUBBED) called");
}
void NIM_U::GetAutoTitleDownloadTaskInfos(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp(ctx, 0x17, 1, 2); // 0x170042
const u64 max_task_infos = rp.Pop<u32>();
auto& task_infos_buffer = rp.PopMappedBuffer();
IPC::RequestBuilder rb = rp.MakeBuilder(2, 2);
rb.Push(RESULT_SUCCESS);
rb.Push(0);
rb.PushMappedBuffer(task_infos_buffer);
LOG_WARNING(Service_NIM, "(STUBBED) called max_task_infos={:08X}, task_infos_buffer=0x{:08X}",
max_task_infos, task_infos_buffer.GetId());
}
void NIM_U::CancelAutoTitleDownloadTask(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp(ctx, 0x18, 2, 0); // 0x180080
const u64 task_id = rp.Pop<u64>();
IPC::RequestBuilder rb = rp.MakeBuilder(1, 0);
rb.Push(RESULT_SUCCESS);
LOG_WARNING(Service_NIM, "(STUBBED) called task_id={:016X}", task_id);
}
void NIM_U::SetAutoDbgDat(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp(ctx, 0x19, 0, 2); // 0x190002
auto& auto_dbg_dat_buffer = rp.PopMappedBuffer();
IPC::RequestBuilder rb = rp.MakeBuilder(1, 2);
rb.Push(RESULT_SUCCESS);
rb.PushMappedBuffer(auto_dbg_dat_buffer);
LOG_WARNING(Service_NIM, "(STUBBED) called auto_dbg_dat_buffer=0x{:08X}",
auto_dbg_dat_buffer.GetId());
}
void NIM_U::GetAutoDbgDat(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp(ctx, 0x1A, 0, 2); // 0x1A0002
auto& auto_dbg_dat_buffer = rp.PopMappedBuffer();
IPC::RequestBuilder rb = rp.MakeBuilder(1, 2);
rb.Push(RESULT_SUCCESS);
rb.PushMappedBuffer(auto_dbg_dat_buffer);
LOG_WARNING(Service_NIM, "(STUBBED) called auto_dbg_dat_buffer=0x{:08X}",
auto_dbg_dat_buffer.GetId());
}
void NIM_U::SetDbgTasks(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp(ctx, 0x1B, 1, 2); // 0x1B0042
const u64 max_task_infos = rp.Pop<u32>();
auto& task_infos_buffer = rp.PopMappedBuffer();
IPC::RequestBuilder rb = rp.MakeBuilder(1, 2);
rb.Push(RESULT_SUCCESS);
rb.PushMappedBuffer(task_infos_buffer);
LOG_WARNING(Service_NIM, "(STUBBED) called max_task_infos={:08X}, task_infos_buffer=0x{:08X}",
max_task_infos, task_infos_buffer.GetId());
}
void NIM_U::GetDbgTasks(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp(ctx, 0x1C, 1, 2); // 0x1C0042
const u64 max_task_infos = rp.Pop<u32>();
auto& task_infos_buffer = rp.PopMappedBuffer();
IPC::RequestBuilder rb = rp.MakeBuilder(2, 2);
rb.Push(RESULT_SUCCESS);
rb.Push(0);
rb.PushMappedBuffer(task_infos_buffer);
LOG_WARNING(Service_NIM, "(STUBBED) called max_task_infos={:08X}, task_infos_buffer=0x{:08X}",
max_task_infos, task_infos_buffer.GetId());
}
void NIM_U::DeleteDbgData(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp(ctx, 0x1D, 0, 0); // 0x1D0000
IPC::RequestBuilder rb = rp.MakeBuilder(1, 0);
rb.Push(RESULT_SUCCESS);
LOG_WARNING(Service_NIM, "(STUBBED) called");
}
void NIM_U::SetTslXml(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp(ctx, 0x1E, 1, 2); // 0x1E0042
const u32 buffer_size = rp.Pop<u32>();
auto& xml_buffer = rp.PopMappedBuffer();
IPC::RequestBuilder rb = rp.MakeBuilder(1, 2);
rb.Push(RESULT_SUCCESS);
rb.PushMappedBuffer(xml_buffer);
LOG_WARNING(Service_NIM, "(STUBBED) called buffer_size={:08X}, xml_buffer=0x{:08X}",
buffer_size, xml_buffer.GetId());
}
void NIM_U::GetTslXmlSize(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp(ctx, 0x1F, 0, 0); // 0x1F0000
IPC::RequestBuilder rb = rp.MakeBuilder(3, 0);
rb.Push(RESULT_SUCCESS);
rb.Push<u64>(0);
LOG_WARNING(Service_NIM, "(STUBBED) called");
}
void NIM_U::GetTslXml(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp(ctx, 0x20, 1, 2); // 0x200042
const u32 buffer_capacity = rp.Pop<u32>();
auto& xml_buffer = rp.PopMappedBuffer();
IPC::RequestBuilder rb = rp.MakeBuilder(1, 2);
rb.Push(RESULT_SUCCESS);
rb.PushMappedBuffer(xml_buffer);
LOG_WARNING(Service_NIM, "(STUBBED) called buffer_capacity={:08X}, xml_buffer=0x{:08X}",
buffer_capacity, xml_buffer.GetId());
}
void NIM_U::DeleteTslXml(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp(ctx, 0x21, 0, 0); // 0x210000
IPC::RequestBuilder rb = rp.MakeBuilder(1, 0);
rb.Push(RESULT_SUCCESS);
LOG_WARNING(Service_NIM, "(STUBBED) called");
}
void NIM_U::SetDtlXml(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp(ctx, 0x22, 1, 2); // 0x220042
const u32 buffer_size = rp.Pop<u32>();
auto& xml_buffer = rp.PopMappedBuffer();
IPC::RequestBuilder rb = rp.MakeBuilder(1, 2);
rb.Push(RESULT_SUCCESS);
rb.PushMappedBuffer(xml_buffer);
LOG_WARNING(Service_NIM, "(STUBBED) called buffer_size={:08X}, xml_buffer=0x{:08X}",
buffer_size, xml_buffer.GetId());
}
void NIM_U::GetDtlXmlSize(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp(ctx, 0x23, 0, 0); // 0x230000
IPC::RequestBuilder rb = rp.MakeBuilder(3, 0);
rb.Push(RESULT_SUCCESS);
rb.Push<u64>(0);
LOG_WARNING(Service_NIM, "(STUBBED) called");
}
void NIM_U::GetDtlXml(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp(ctx, 0x24, 1, 2); // 0x240042
const u32 buffer_capacity = rp.Pop<u32>();
auto& xml_buffer = rp.PopMappedBuffer();
IPC::RequestBuilder rb = rp.MakeBuilder(1, 2);
rb.Push(RESULT_SUCCESS);
rb.PushMappedBuffer(xml_buffer);
LOG_WARNING(Service_NIM, "(STUBBED) called buffer_capacity={:08X}, xml_buffer=0x{:08X}",
buffer_capacity, xml_buffer.GetId());
}
void NIM_U::UpdateAccountStatus(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp(ctx, 0x25, 0, 0); // 0x250000
IPC::RequestBuilder rb = rp.MakeBuilder(3, 0);
rb.Push(RESULT_SUCCESS);
rb.Push(RESULT_SUCCESS);
rb.Push(0);
LOG_WARNING(Service_NIM, "(STUBBED) called");
}
void NIM_U::StartTitleDownload(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp(ctx, 0x26, 6, 0); // 0x260180
const auto& download_config = rp.PopRaw<TitleDownloadConfig>();
IPC::RequestBuilder rb = rp.MakeBuilder(1, 0);
rb.Push(RESULT_SUCCESS);
LOG_WARNING(Service_NIM, "(STUBBED) called title_id={:016X}", download_config.title_id);
}
void NIM_U::StopTitleDownload(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp(ctx, 0x27, 0, 0); // 0x270000
IPC::RequestBuilder rb = rp.MakeBuilder(1, 0);
rb.Push(RESULT_SUCCESS);
LOG_WARNING(Service_NIM, "(STUBBED) called");
}
void NIM_U::GetTitleDownloadProgress(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp(ctx, 0x28, 0, 0); // 0x280000
TitleDownloadProgress progress{};
std::memset(&progress, 0, sizeof(progress));
IPC::RequestBuilder rb = rp.MakeBuilder(9, 0);
rb.Push(RESULT_SUCCESS);
rb.PushRaw(progress);
rb.Push(0);
rb.Push(0);
LOG_WARNING(Service_NIM, "(STUBBED) called");
}
void NIM_U::RegisterTask(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp(ctx, 0x29, 9, 6); // 0x290246
const auto& download_config = rp.PopRaw<TitleDownloadConfig>();
const u32 unknown_1 = rp.Pop<u32>();
const u32 unknown_2 = rp.Pop<u32>();
const u32 unknown_3 = rp.Pop<u32>();
const u32 pid = rp.PopPID();
const auto& title_name = rp.PopStaticBuffer();
const auto& developer_name = rp.PopStaticBuffer();
IPC::RequestBuilder rb = rp.MakeBuilder(1, 0);
rb.Push(RESULT_SUCCESS);
const auto title_name_end = std::find(title_name.begin(), title_name.end(), u'\0');
const auto title_name_utf8 =
Common::UTF16ToUTF8(std::u16string{title_name.begin(), title_name_end});
const auto developer_name_end = std::find(developer_name.begin(), developer_name.end(), u'\0');
const auto developer_name_utf8 =
Common::UTF16ToUTF8(std::u16string{developer_name.begin(), developer_name_end});
LOG_WARNING(Service_NIM,
"(STUBBED) called title_id={:016X}, unknown_1={:08X}, unknown_2={:08X}, "
"unknown_3={:08X}, pid={:08X}, title_name='{}', developer_name='{}'",
download_config.title_id, unknown_1, unknown_2, unknown_3, pid, title_name_utf8,
developer_name_utf8);
}
void NIM_U::IsSystemUpdateAvailable(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp(ctx, 0x2A, 0, 0); // 0x2A0000
IPC::RequestBuilder rb = rp.MakeBuilder(4, 0);
rb.Push(RESULT_SUCCESS);
rb.Push(RESULT_SUCCESS);
rb.Push(0);
rb.Push(false);
LOG_WARNING(Service_NIM, "(STUBBED) called");
}
void NIM_U::Unknown2B(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp(ctx, 0x2B, 0, 0); // 0x2B0000
IPC::RequestBuilder rb = rp.MakeBuilder(1, 0);
rb.Push(RESULT_SUCCESS);
LOG_WARNING(Service_NIM, "(STUBBED) called");
}
void NIM_U::UpdateTickets(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp(ctx, 0x2C, 0, 0); // 0x2C0000
IPC::RequestBuilder rb = rp.MakeBuilder(3, 0);
rb.Push(RESULT_SUCCESS);
rb.Push(RESULT_SUCCESS);
rb.Push(0);
LOG_WARNING(Service_NIM, "(STUBBED) called");
}
void NIM_U::DownloadTitleSeedAsync(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp(ctx, 0x2D, 3, 0); // 0x2D00C0
const u64 title_id = rp.Pop<u64>();
const u16 country_code = rp.Pop<u16>();
// Since this is a stub, signal the completion event so the caller won't get stuck waiting.
nim_async_completion_event->Signal();
IPC::RequestBuilder rb = rp.MakeBuilder(1, 2);
rb.Push(RESULT_SUCCESS);
rb.PushCopyObjects(nim_async_completion_event);
LOG_WARNING(Service_NIM, "(STUBBED) called title_id={:016X}, country_code={:04X}", title_id,
country_code);
}
void NIM_U::DownloadMissingTitleSeedsAsync(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp(ctx, 0x2E, 0, 0); // 0x2E0000
// Since this is a stub, signal the completion event so the caller won't get stuck waiting.
nim_async_completion_event->Signal();
IPC::RequestBuilder rb = rp.MakeBuilder(1, 2);
rb.Push(RESULT_SUCCESS);
rb.PushCopyObjects(nim_async_completion_event);
LOG_WARNING(Service_NIM, "(STUBBED) called");
}

View File

@ -20,32 +20,522 @@ public:
private:
/**
* NIM::CheckForSysUpdateEvent service function
* NIM::StartNetworkUpdate service function
* Inputs:
* 1 : None
* Outputs:
* 1 : Result of function, 0 on success, otherwise error code
* 2 : Copy handle descriptor
* 3 : System Update event handle
*/
void CheckForSysUpdateEvent(Kernel::HLERequestContext& ctx);
void StartNetworkUpdate(Kernel::HLERequestContext& ctx);
/**
* NIM::CheckSysUpdateAvailable service function
* NIM::GetProgress service function
* Inputs:
* 1 : None
* Outputs:
* 1 : Result of function, 0 on success, otherwise error code
* 2 : u8 flag, 0 = no system update available, 1 = system update available.
* 2-11 : SystemUpdateProgress structure for the foreground system update
* 12: ?
* 13: ?
*/
void CheckSysUpdateAvailable(Kernel::HLERequestContext& ctx);
void GetProgress(Kernel::HLERequestContext& ctx);
std::shared_ptr<Kernel::Event> nim_system_update_event;
/**
* NIM::Cancel service function
* Inputs:
* 1 : None
* Outputs:
* 1 : Result of function, 0 on success, otherwise error code
*/
void Cancel(Kernel::HLERequestContext& ctx);
/**
* NIM::CommitSystemTitles service function
* Inputs:
* 1 : None
* Outputs:
* 1 : Result of function, 0 on success, otherwise error code
*/
void CommitSystemTitles(Kernel::HLERequestContext& ctx);
/**
* NIM::GetBackgroundEventForMenu service function
* Inputs:
* 1 : None
* Outputs:
* 1 : Result of function, 0 on success, otherwise error code
* 2 : Copy handle IPC header
* 3 : System update ready event handle for home menu
*/
void GetBackgroundEventForMenu(Kernel::HLERequestContext& ctx);
/**
* NIM::GetBackgroundEventForNews service function
* Inputs:
* 1 : None
* Outputs:
* 1 : Result of function, 0 on success, otherwise error code
* 2 : Copy handle IPC header
* 3 : System update ready event handle for news module
*/
void GetBackgroundEventForNews(Kernel::HLERequestContext& ctx);
/**
* NIM::FormatSaveData service function
* Inputs:
* 1 : None
* Outputs:
* 1 : Result of function, 0 on success, otherwise error code
*/
void FormatSaveData(Kernel::HLERequestContext& ctx);
/**
* NIM::GetCustomerSupportCode service function
* Inputs:
* 1 : None
* Outputs:
* 1 : Result of function, 0 on success, otherwise error code
* 2 : Customer support code for the last system update error
*/
void GetCustomerSupportCode(Kernel::HLERequestContext& ctx);
/**
* NIM::IsCommittableAllSystemTitles service function
* Inputs:
* 1 : None
* Outputs:
* 1 : Result of function, 0 on success, otherwise error code
* 2 : Boolean indicating whether system titles are ready to commit
*/
void IsCommittableAllSystemTitles(Kernel::HLERequestContext& ctx);
/**
* NIM::GetBackgroundProgress service function
* Inputs:
* 1 : None
* Outputs:
* 1 : Result of function, 0 on success, otherwise error code
* 2-11 : SystemUpdateProgress structure for the background system update
* 12: ?
* 13: ?
*/
void GetBackgroundProgress(Kernel::HLERequestContext& ctx);
/**
* NIM::GetSavedHash service function
* Inputs:
* 1 : None
* Outputs:
* 1 : Result of function, 0 on success, otherwise error code
* 2-10 : NUL-terminated saved system update hash
*/
void GetSavedHash(Kernel::HLERequestContext& ctx);
/**
* NIM::UnregisterTask service function
* Inputs:
* 1-2 : Title ID
* 3 : Process ID IPC Header
* 4 : Process ID (Auto-filled by kernel)
* Outputs:
* 1 : Result of function, 0 on success, otherwise error code
*/
void UnregisterTask(Kernel::HLERequestContext& ctx);
/**
* NIM::IsRegistered service function
* Inputs:
* 1-2 : Title ID
* Outputs:
* 1 : Result of function, 0 on success, otherwise error code
* 2 : Boolean indicating whether a download task is registered for the title ID
*/
void IsRegistered(Kernel::HLERequestContext& ctx);
/**
* NIM::FindTaskInfo service function
* Inputs:
* 1-2 : Title ID
* Outputs:
* 1 : Result of function, 0 on success, otherwise error code
* 2 : Static Buffer IPC Header (ID = 0, Size = 0x120)
* 3 : BackgroundTitleDownloadTaskInfo structure pointer
*/
void FindTaskInfo(Kernel::HLERequestContext& ctx);
/**
* NIM::GetTaskInfos service function
* Inputs:
* 1 : Maximum Number of BackgroundTitleDownloadTaskInfos
* 2 : Mapped Output Buffer IPC Header
* 3 : BackgroundTitleDownloadTaskInfos Output Buffer Pointer
* Outputs:
* 1 : Result of function, 0 on success, otherwise error code
* 2 : Number of BackgroundTitleDownloadTaskInfos Read
* 3 : Mapped Output Buffer IPC Header
* 4 : BackgroundTitleDownloadTaskInfos Output Buffer Pointer
*/
void GetTaskInfos(Kernel::HLERequestContext& ctx);
/**
* NIM::DeleteUnmanagedContexts service function
* Inputs:
* 1 : None
* Outputs:
* 1 : Result of function, 0 on success, otherwise error code
*/
void DeleteUnmanagedContexts(Kernel::HLERequestContext& ctx);
/**
* NIM::UpdateAutoTitleDownloadTasksAsync service function
* Inputs:
* 1 : None
* Outputs:
* 1 : Result of function, 0 on success, otherwise error code
* 2 : Copy Handle IPC Header
* 3 : Event handle signaled when the operation completes
*/
void UpdateAutoTitleDownloadTasksAsync(Kernel::HLERequestContext& ctx);
/**
* NIM::StartPendingAutoTitleDownloadTasksAsync service function
* Inputs:
* 1 : None
* Outputs:
* 1 : Result of function, 0 on success, otherwise error code
* 2 : Copy Handle IPC Header
* 3 : Event handle signaled when the operation completes
*/
void StartPendingAutoTitleDownloadTasksAsync(Kernel::HLERequestContext& ctx);
/**
* NIM::GetAsyncResult service function
* Inputs:
* 1 : None
* Outputs:
* 1 : Result of function, 0 on success, otherwise error code
* 2 : Async operation result code
* 3 : Async operation customer support code
*/
void GetAsyncResult(Kernel::HLERequestContext& ctx);
/**
* NIM::CancelAsyncCall service function
* Inputs:
* 1 : None
* Outputs:
* 1 : Result of function, 0 on success, otherwise error code
*/
void CancelAsyncCall(Kernel::HLERequestContext& ctx);
/**
* NIM::IsPendingAutoTitleDownloadTasks service function
* Inputs:
* 1 : None
* Outputs:
* 1 : Result of function, 0 on success, otherwise error code
* 2 : Boolean indicating whether there are auto title downloads ready to start
*/
void IsPendingAutoTitleDownloadTasks(Kernel::HLERequestContext& ctx);
/**
* NIM::GetNumAutoTitleDownloadTasks service function
* Inputs:
* 1 : None
* Outputs:
* 1 : Result of function, 0 on success, otherwise error code
* 2 : Number of auto title download tasks
*/
void GetNumAutoTitleDownloadTasks(Kernel::HLERequestContext& ctx);
/**
* NIM::GetAutoTitleDownloadTasks service function
* Inputs:
* 1 : Maximum number of AutoTitleDownloadTaskInfos
* 2 : Mapped Output Buffer IPC Header
* 3 : AutoTitleDownloadTaskInfos Output Buffer Pointer
* Outputs:
* 1 : Result of function, 0 on success, otherwise error code
* 2 : Number of AutoTitleDownloadTaskInfos Read
* 3 : Mapped Output Buffer IPC Header
* 4 : AutoTitleDownloadTaskInfos Output Buffer Pointer
*/
void GetAutoTitleDownloadTaskInfos(Kernel::HLERequestContext& ctx);
/**
* NIM::CancelAutoTitleDownloadTask service function
* Inputs:
* 1-2 : Auto Title Download Task ID
* Outputs:
* 1 : Result of function, 0 on success, otherwise error code
*/
void CancelAutoTitleDownloadTask(Kernel::HLERequestContext& ctx);
/**
* NIM::SetAutoDbgDat service function
* Inputs:
* 1 : Mapped Input Buffer IPC Header
* 2 : AutoDbgDat Input Buffer Pointer
* Outputs:
* 1 : Result of function, 0 on success, otherwise error code
* 2 : Mapped Input Buffer IPC Header
* 3 : AutoDbgDat Input Buffer Pointer
*/
void SetAutoDbgDat(Kernel::HLERequestContext& ctx);
/**
* NIM::GetAutoDbgDat service function
* Inputs:
* 1 : Mapped Output Buffer IPC Header
* 2 : AutoDbgDat Output Buffer Pointer
* Outputs:
* 1 : Result of function, 0 on success, otherwise error code
* 2 : Mapped Output Buffer IPC Header
* 3 : AutoDbgDat Output Buffer Pointer
*/
void GetAutoDbgDat(Kernel::HLERequestContext& ctx);
/**
* NIM::SetDbgTasks service function
* Inputs:
* 1 : Number of AutoTitleDownloadTaskInfos
* 2 : Mapped Input Buffer IPC Header
* 3 : AutoTitleDownloadTaskInfos Input Buffer Pointer
* Outputs:
* 1 : Result of function, 0 on success, otherwise error code
* 3 : Mapped Input Buffer IPC Header
* 4 : AutoTitleDownloadTaskInfos Input Buffer Pointer
*/
void SetDbgTasks(Kernel::HLERequestContext& ctx);
/**
* NIM::GetDbgTasks service function
* Inputs:
* 1 : Maximum number of AutoTitleDownloadTaskInfos
* 2 : Mapped Output Buffer IPC Header
* 3 : AutoTitleDownloadTaskInfos Output Buffer Pointer
* Outputs:
* 1 : Result of function, 0 on success, otherwise error code
* 2 : Number of AutoTitleDownloadTaskInfos Read
* 3 : Mapped Output Buffer IPC Header
* 4 : AutoTitleDownloadTaskInfos Output Buffer Pointer
*/
void GetDbgTasks(Kernel::HLERequestContext& ctx);
/**
* NIM::DeleteDbgData service function
* Inputs:
* 1 : None
* Outputs:
* 1 : Result of function, 0 on success, otherwise error code
*/
void DeleteDbgData(Kernel::HLERequestContext& ctx);
/**
* NIM::SetTslXml service function
* Inputs:
* 1 : Buffer Size
* 2 : Mapped Input Buffer IPC Header
* 3 : XML Input Buffer Pointer
* Outputs:
* 1 : Result of function, 0 on success, otherwise error code
* 2 : Mapped Input Buffer IPC Header
* 3 : XML Input Buffer Pointer
*/
void SetTslXml(Kernel::HLERequestContext& ctx);
/**
* NIM::GetTslXmlSize service function
* Inputs:
* 1 : None
* Outputs:
* 1 : Result of function, 0 on success, otherwise error code
* 2-3 : XML Size
*/
void GetTslXmlSize(Kernel::HLERequestContext& ctx);
/**
* NIM::GetTslXml service function
* Inputs:
* 1 : Buffer Capacity
* 2 : Mapped Output Buffer IPC Header
* 3 : XML Output Buffer Pointer
* Outputs:
* 1 : Result of function, 0 on success, otherwise error code
* 2 : Mapped Output Buffer IPC Header
* 3 : XML Output Buffer Pointer
*/
void GetTslXml(Kernel::HLERequestContext& ctx);
/**
* NIM::DeleteTslXml service function
* Inputs:
* 1 : None
* Outputs:
* 1 : Result of function, 0 on success, otherwise error code
*/
void DeleteTslXml(Kernel::HLERequestContext& ctx);
/**
* NIM::SetDtlXml service function
* Inputs:
* 1 : Buffer Size
* 2 : Mapped Input Buffer IPC Header
* 3 : XML Input Buffer Pointer
* Outputs:
* 1 : Result of function, 0 on success, otherwise error code
* 2 : Mapped Input Buffer IPC Header
* 3 : XML Input Buffer Pointer
*/
void SetDtlXml(Kernel::HLERequestContext& ctx);
/**
* NIM::GetDtlXmlSize service function
* Inputs:
* 1 : None
* Outputs:
* 1 : Result of function, 0 on success, otherwise error code
* 2-3 : XML Size
*/
void GetDtlXmlSize(Kernel::HLERequestContext& ctx);
/**
* NIM::GetDtlXml service function
* Inputs:
* 1 : Buffer Capacity
* 2 : Mapped Output Buffer IPC Header
* 3 : XML Output Buffer Pointer
* Outputs:
* 1 : Result of function, 0 on success, otherwise error code
* 2 : Mapped Output Buffer IPC Header
* 3 : XML Output Buffer Pointer
*/
void GetDtlXml(Kernel::HLERequestContext& ctx);
/**
* NIM::UpdateAccountStatus service function
* Inputs:
* 1 : None
* Outputs:
* 1 : Result of function, 0 on success, otherwise error code
* 2 : Result of the actual operation
* 3 : Customer support code of the actual operation
*/
void UpdateAccountStatus(Kernel::HLERequestContext& ctx);
/**
* NIM::StartTitleDownload service function
* Inputs:
* 1-6 : TitleDownloadConfig structure
* Outputs:
* 1 : Result of function, 0 on success, otherwise error code
*/
void StartTitleDownload(Kernel::HLERequestContext& ctx);
/**
* NIM::StopDownload service function
* Inputs:
* 1 : None
* Outputs:
* 1 : Result of function, 0 on success, otherwise error code
*/
void StopTitleDownload(Kernel::HLERequestContext& ctx);
/**
* NIM::GetTitleDownloadProgress service function
* Inputs:
* 1 : None
* Outputs:
* 1 : Result of function, 0 on success, otherwise error code
* 2-7 : TitleDownloadProgress structure
* 8: ?
* 9: ?
*/
void GetTitleDownloadProgress(Kernel::HLERequestContext& ctx);
/**
* NIM::RegisterTask service function
* Inputs:
* 1-6 : TitleDownloadConfig structure
* 7: ?
* 8: ?
* 9: ?
* 10: Process ID IPC Header
* 11: Process ID (Auto-filled by Kernel)
* 12: Static Buffer IPC Header (ID = 0, Size = 0x90)
* 13: Title Name UTF-16 String Pointer
* 14: Static Buffer IPC Header (ID = 1, Size = 0x48)
* 15: Developer Name UTF-16 String Pointer
* Outputs:
* 1 : Result of function, 0 on success, otherwise error code
*/
void RegisterTask(Kernel::HLERequestContext& ctx);
/**
* NIM::IsSystemUpdateAvailable service function
* Inputs:
* 1 : None
* Outputs:
* 1 : Result of function, 0 on success, otherwise error code
* 2 : Result code from the actual operation
* 3 : Customer support code from the actual operation
* 4 : Boolean indicating whether a system update is available
*/
void IsSystemUpdateAvailable(Kernel::HLERequestContext& ctx);
/**
* NIM::Unknown2B service function
* Inputs:
* 1 : None
* Outputs:
* 1 : Result of function, 0 on success, otherwise error code
*/
void Unknown2B(Kernel::HLERequestContext& ctx);
/**
* NIM::UpdateTickets service function
* Inputs:
* 1 : None
* Outputs:
* 1 : Result of function, 0 on success, otherwise error code
* 2 : Result code from the actual operation
* 3 : Customer support code from the actual operation
*/
void UpdateTickets(Kernel::HLERequestContext& ctx);
/**
* NIM::DownloadTitleSeedAsync service function
* Inputs:
* 1-2 : Title ID
* 3: u16 Country Code
* Outputs:
* 1 : Result of function, 0 on success, otherwise error code
* 2 : Copy Handle IPC Header
* 3 : Event handle signaled when the operation completes
*/
void DownloadTitleSeedAsync(Kernel::HLERequestContext& ctx);
/**
* NIM::DownloadMissingTitleSeedsAsync service function
* Inputs:
* 1 : None
* Outputs:
* 1 : Result of function, 0 on success, otherwise error code
* 2 : Copy Handle IPC Header
* 3 : Event handle signaled when the operation completes
*/
void DownloadMissingTitleSeedsAsync(Kernel::HLERequestContext& ctx);
std::shared_ptr<Kernel::Event> nim_system_update_event_for_menu;
std::shared_ptr<Kernel::Event> nim_system_update_event_for_news;
std::shared_ptr<Kernel::Event> nim_async_completion_event;
template <class Archive>
void serialize(Archive& ar, const unsigned int) {
ar& boost::serialization::base_object<Kernel::SessionRequestHandler>(*this);
ar& nim_system_update_event;
ar& nim_system_update_event_for_menu;
ar& nim_system_update_event_for_news;
ar& nim_async_completion_event;
}
friend class boost::serialization::access;
};