core: apt: Implement GetAppletProgramInfo

This commit is contained in:
PabloMK7 2026-07-08 23:28:40 +02:00
parent b64040b5fa
commit 49ba2e8d5f
8 changed files with 64 additions and 4 deletions

View File

@ -444,6 +444,10 @@ std::string GetTitlePath(Service::FS::MediaType media_type, u64 tid);
*/ */
std::string GetMediaTitlePath(Service::FS::MediaType media_type); std::string GetMediaTitlePath(Service::FS::MediaType media_type);
Result GetTitleInfoFromList(Core::System& system, std::span<const u64> title_id_list,
Service::FS::MediaType media_type,
std::vector<TitleInfo>& title_info_out);
/** /**
* Uninstalls the specified title. * Uninstalls the specified title.
* @param media_type the storage medium the title is installed to * @param media_type the storage medium the title is installed to

View File

@ -105,7 +105,7 @@ static constexpr std::array<AppletTitleData, NumApplets> applet_titleids = {{
// TODO(Subv): Fill in the rest of the titleids // TODO(Subv): Fill in the rest of the titleids
}}; }};
static u64 GetTitleIdForApplet(AppletId id, u32 region_value) { u64 GetTitleIdForApplet(AppletId id, u32 region_value) {
ASSERT_MSG(id != AppletId::None, "Invalid applet id"); ASSERT_MSG(id != AppletId::None, "Invalid applet id");
auto itr = std::find_if(applet_titleids.begin(), applet_titleids.end(), auto itr = std::find_if(applet_titleids.begin(), applet_titleids.end(),

View File

@ -104,6 +104,8 @@ enum class AppletId : u32 {
TypeMask = 0xF00, TypeMask = 0xF00,
}; };
u64 GetTitleIdForApplet(AppletId id, u32 region_value);
/// Application Old/New 3DS target platforms /// Application Old/New 3DS target platforms
enum class TargetPlatform : u8 { enum class TargetPlatform : u8 {
Old3ds = 0, Old3ds = 0,

View File

@ -1432,6 +1432,58 @@ void Module::APTInterface::Reboot(Kernel::HLERequestContext& ctx) {
rb.Push(ResultSuccess); rb.Push(ResultSuccess);
} }
void Module::APTInterface::GetAppletProgramInfo(Kernel::HLERequestContext& ctx) {
union {
u32 raw;
BitField<0, 1, u32> mediatype_nand;
BitField<1, 1, u32> mediatype_sdmc;
BitField<2, 1, u32> mediatype_gamecard;
BitField<4, 1, u32> is_appid;
BitField<5, 1, u32> not_appid_must_set;
BitField<8, 1, u32> is_system_app;
} flags;
IPC::RequestParser rp(ctx);
u32 program_id = rp.Pop<u32>();
flags.raw = rp.Pop<u32>();
IPC::RequestBuilder rb = rp.MakeBuilder(2, 0);
u64 title_id;
if (flags.is_appid) {
auto cfg = Service::CFG::GetModule(apt->system);
title_id =
GetTitleIdForApplet(static_cast<AppletId>(program_id), cfg->GetRegionValue(true));
} else {
if (!flags.not_appid_must_set) {
rb.Push(ResultUnknown); // TODO: Find proper error code
rb.Push(0);
return;
} else {
u32 tid_high = flags.is_system_app ? 0x00040010 : 0x00040000;
title_id = static_cast<u64>(tid_high) << 32 | program_id;
}
}
std::vector<Service::AM::TitleInfo> info;
Result res = ResultUnknown; // TODO: Find proper error code
if (res.IsError() && flags.mediatype_nand) {
res = Service::AM::GetTitleInfoFromList(apt->system, std::span<u64>(&title_id, 1),
FS::MediaType::NAND, info);
}
if (res.IsError() && flags.mediatype_sdmc) {
res = Service::AM::GetTitleInfoFromList(apt->system, std::span<u64>(&title_id, 1),
FS::MediaType::SDMC, info);
}
if (res.IsError() && flags.mediatype_gamecard) {
res = Service::AM::GetTitleInfoFromList(apt->system, std::span<u64>(&title_id, 1),
FS::MediaType::GameCard, info);
}
rb.Push(res);
rb.Push(res.IsSuccess() ? info[0].version : 0);
}
void Module::APTInterface::HardwareResetAsync(Kernel::HLERequestContext& ctx) { void Module::APTInterface::HardwareResetAsync(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp(ctx); IPC::RequestParser rp(ctx);

View File

@ -1009,6 +1009,8 @@ public:
*/ */
void Reboot(Kernel::HLERequestContext& ctx); void Reboot(Kernel::HLERequestContext& ctx);
void GetAppletProgramInfo(Kernel::HLERequestContext& ctx);
/** /**
* APT::HardwareResetAsync service function. * APT::HardwareResetAsync service function.
* Outputs: * Outputs:

View File

@ -87,7 +87,7 @@ APT_A::APT_A(std::shared_ptr<Module> apt)
{0x004A, &APT_A::GetCaptureInfo, "GetCaptureInfo"}, {0x004A, &APT_A::GetCaptureInfo, "GetCaptureInfo"},
{0x004B, &APT_A::AppletUtility, "AppletUtility"}, {0x004B, &APT_A::AppletUtility, "AppletUtility"},
{0x004C, nullptr, "SetFatalErrDispMode"}, {0x004C, nullptr, "SetFatalErrDispMode"},
{0x004D, nullptr, "GetAppletProgramInfo"}, {0x004D, &APT_A::GetAppletProgramInfo, "GetAppletProgramInfo"},
{0x004E, &APT_A::HardwareResetAsync, "HardwareResetAsync"}, {0x004E, &APT_A::HardwareResetAsync, "HardwareResetAsync"},
{0x004F, &APT_A::SetAppCpuTimeLimit, "SetAppCpuTimeLimit"}, {0x004F, &APT_A::SetAppCpuTimeLimit, "SetAppCpuTimeLimit"},
{0x0050, &APT_A::GetAppCpuTimeLimit, "GetAppCpuTimeLimit"}, {0x0050, &APT_A::GetAppCpuTimeLimit, "GetAppCpuTimeLimit"},

View File

@ -87,7 +87,7 @@ APT_S::APT_S(std::shared_ptr<Module> apt)
{0x004A, &APT_S::GetCaptureInfo, "GetCaptureInfo"}, {0x004A, &APT_S::GetCaptureInfo, "GetCaptureInfo"},
{0x004B, &APT_S::AppletUtility, "AppletUtility"}, {0x004B, &APT_S::AppletUtility, "AppletUtility"},
{0x004C, nullptr, "SetFatalErrDispMode"}, {0x004C, nullptr, "SetFatalErrDispMode"},
{0x004D, nullptr, "GetAppletProgramInfo"}, {0x004D, &APT_S::GetAppletProgramInfo, "GetAppletProgramInfo"},
{0x004E, &APT_S::HardwareResetAsync, "HardwareResetAsync"}, {0x004E, &APT_S::HardwareResetAsync, "HardwareResetAsync"},
{0x004F, &APT_S::SetAppCpuTimeLimit, "SetAppCpuTimeLimit"}, {0x004F, &APT_S::SetAppCpuTimeLimit, "SetAppCpuTimeLimit"},
{0x0050, &APT_S::GetAppCpuTimeLimit, "GetAppCpuTimeLimit"}, {0x0050, &APT_S::GetAppCpuTimeLimit, "GetAppCpuTimeLimit"},

View File

@ -87,7 +87,7 @@ APT_U::APT_U(std::shared_ptr<Module> apt)
{0x004A, &APT_U::GetCaptureInfo, "GetCaptureInfo"}, {0x004A, &APT_U::GetCaptureInfo, "GetCaptureInfo"},
{0x004B, &APT_U::AppletUtility, "AppletUtility"}, {0x004B, &APT_U::AppletUtility, "AppletUtility"},
{0x004C, nullptr, "SetFatalErrDispMode"}, {0x004C, nullptr, "SetFatalErrDispMode"},
{0x004D, nullptr, "GetAppletProgramInfo"}, {0x004D, &APT_U::GetAppletProgramInfo, "GetAppletProgramInfo"},
{0x004E, &APT_U::HardwareResetAsync, "HardwareResetAsync"}, {0x004E, &APT_U::HardwareResetAsync, "HardwareResetAsync"},
{0x004F, &APT_U::SetAppCpuTimeLimit, "SetAppCpuTimeLimit"}, {0x004F, &APT_U::SetAppCpuTimeLimit, "SetAppCpuTimeLimit"},
{0x0050, &APT_U::GetAppCpuTimeLimit, "GetAppCpuTimeLimit"}, {0x0050, &APT_U::GetAppCpuTimeLimit, "GetAppCpuTimeLimit"},