diff --git a/include/core/gamecard.h b/include/core/gamecard.h index e68b0f8..2cc97e2 100644 --- a/include/core/gamecard.h +++ b/include/core/gamecard.h @@ -122,9 +122,11 @@ typedef enum { typedef enum { GameCardFwVersion_ForDev = 0, - GameCardFwVersion_ForProd = BIT(0), - GameCardFwVersion_ForProdSince400NUP = BIT(1), ///< upp_version >= 268435456 (4.0.0-0.0) in GameCardInfo. - GameCardFwVersion_ForProdSince1100NUP = BIT(2) ///< upp_version >= 738197504 (11.0.0-0.0) in GameCardInfo. + GameCardFwVersion_ForProd = 1, + GameCardFwVersion_ForProdSince400NUP = 2, ///< upp_version >= 268435456 (4.0.0-0.0) in GameCardInfo. + GameCardFwVersion_ForDevSince1100NUP = 3, ///< upp_version >= 738197504 (11.0.0-0.0) in GameCardInfo. + GameCardFwVersion_ForProdSince1100NUP = 4, ///< upp_version >= 738197504 (11.0.0-0.0) in GameCardInfo. + GameCardFwVersion_ForProdSince1200NUP = 5 ///< upp_version >= 805306368 (12.0.0-0.0) in GameCardInfo. } GameCardFwVersion; typedef enum { diff --git a/include/core/nca.h b/include/core/nca.h index 6887dee..03519f1 100644 --- a/include/core/nca.h +++ b/include/core/nca.h @@ -90,8 +90,8 @@ typedef enum { NcaKeyGeneration_700_801 = 8, NcaKeyGeneration_810_811 = 9, NcaKeyGeneration_900_901 = 10, - NcaKeyGeneration_910_1101 = 11, - NcaKeyGeneration_Current = NcaKeyGeneration_910_1101 + NcaKeyGeneration_910_1201 = 11, + NcaKeyGeneration_Current = NcaKeyGeneration_910_1201 } NcaKeyGeneration; typedef struct { diff --git a/include/core/services.h b/include/core/services.h index f39dd53..c37433d 100644 --- a/include/core/services.h +++ b/include/core/services.h @@ -40,20 +40,17 @@ bool servicesInitialize(); /// Closes services previously initialized by servicesInitialize(). void servicesClose(); -/// Checks if a service is running by its name. -/// Uses the smRegisterService() call, which may crash under development units. +/// Checks if a service is running using its name. +/// Wrapper for the "AtmosphereHasService" SM API extension from Atmosphère and Atmosphère-based CFWs. +/// Perfectly safe to use under development units. Not available in older Atmosphère releases. bool servicesCheckRunningServiceByName(const char *name); -/// Check if a service has been initialized by its name. +/// Check if a service has been initialized using its name. bool servicesCheckInitializedServiceByName(const char *name); /// Changes CPU/MEM clock rates at runtime. void servicesChangeHardwareClockRates(u32 cpu_rate, u32 mem_rate); -/// Wrapper for the "AtmosphereHasService" SM API extension from Atmosphère and Atmosphère-based CFWs. -/// Perfectly safe under development units. Not available in older Atmosphère releases. -Result servicesHasService(bool *out, const char *name); - #ifdef __cplusplus } #endif diff --git a/source/core/nxdt_utils.c b/source/core/nxdt_utils.c index b07a2e4..5178ead 100644 --- a/source/core/nxdt_utils.c +++ b/source/core/nxdt_utils.c @@ -653,10 +653,8 @@ void utilsOverclockSystem(bool overclock) static void _utilsGetCustomFirmwareType(void) { - bool has_srv = false, tx_srv = false, rnx_srv = false; - - tx_srv = (R_SUCCEEDED(servicesHasService(&has_srv, "tx")) && has_srv); - rnx_srv = (R_SUCCEEDED(servicesHasService(&has_srv, "rnx")) && has_srv); + bool tx_srv = servicesCheckRunningServiceByName("tx"); + bool rnx_srv = servicesCheckRunningServiceByName("rnx"); g_customFirmwareType = (rnx_srv ? UtilsCustomFirmwareType_ReiNX : (tx_srv ? UtilsCustomFirmwareType_SXOS : UtilsCustomFirmwareType_Atmosphere)); } diff --git a/source/core/services.c b/source/core/services.c index 4c28d01..9cafddd 100644 --- a/source/core/services.c +++ b/source/core/services.c @@ -39,7 +39,8 @@ typedef struct { /* Function prototypes. */ -static Result smAtmosphereHasService(bool *out, SmServiceName name); +static Result servicesAtmosphereHasService(bool *out, SmServiceName name); +static bool servicesGetExosphereApiVersion(u32 *out); static Result servicesNifmUserInitialize(void); static bool servicesClkGetServiceType(void *arg); @@ -70,6 +71,11 @@ static ClkrstSession g_clkrstCpuSession = {0}, g_clkrstMemSession = {0}; static Mutex g_servicesMutex = 0; +/* Atmosphère-related constants. */ +static const u32 g_smAtmosphereHasService = 65100; +static const SplConfigItem SplConfigItem_ExosphereApiVersion = (SplConfigItem)65000; +static const u32 g_atmosphereTipcVersion = MAKEHOSVERSION(0, 19, 0); + bool servicesInitialize(void) { mutexLock(&g_servicesMutex); @@ -133,21 +139,20 @@ void servicesClose(void) bool servicesCheckRunningServiceByName(const char *name) { - if (!name || !*name) return false; + if (!name || !*name) + { + LOG_MSG("Invalid parameters!"); + return false; + } Result rc = 0; - Handle handle = INVALID_HANDLE; + bool out = false; SmServiceName service_name = smEncodeName(name); - bool running = false; - rc = smRegisterService(&handle, service_name, false, 1); - if (R_FAILED(rc)) LOG_MSG("smRegisterService failed for \"%s\"! (0x%08X).", name, rc); - running = R_FAILED(rc); + rc = servicesAtmosphereHasService(&out, service_name); + if (R_FAILED(rc)) LOG_MSG("servicesAtmosphereHasService failed for \"%s\"! (0x%08X).", name, rc); - if (handle != INVALID_HANDLE) svcCloseHandle(handle); - if (!running) smUnregisterService(service_name); - - return running; + return out; } bool servicesCheckInitializedServiceByName(const char *name) @@ -191,31 +196,49 @@ void servicesChangeHardwareClockRates(u32 cpu_rate, u32 mem_rate) mutexUnlock(&g_servicesMutex); } -Result servicesHasService(bool *out, const char *name) +/* SM API extension available in Atmosphère and Atmosphère-based CFWs. */ +static Result servicesAtmosphereHasService(bool *out, SmServiceName name) { - if (!out || !name || !*name) + u8 tmp = 0; + Result rc = 0; + u32 version = 0; + + /* Check if service is running. */ + /* Dispatch IPC request using CMIF or TIPC serialization depending on our current environment. */ + if (hosversionAtLeast(12, 0, 0) || (servicesGetExosphereApiVersion(&version) && version >= g_atmosphereTipcVersion)) { - LOG_MSG("Invalid parameters!"); - return MAKERESULT(Module_Libnx, LibnxError_IoError); + rc = tipcDispatchInOut(smGetServiceSessionTipc(), g_smAtmosphereHasService, name, tmp); + } else { + rc = serviceDispatchInOut(smGetServiceSession(), g_smAtmosphereHasService, name, tmp); } - *out = false; - Result rc = 0; - SmServiceName service_name = smEncodeName(name); - - rc = smAtmosphereHasService(out, service_name); - if (R_FAILED(rc)) LOG_MSG("smAtmosphereHasService failed for \"%s\"! (0x%08X).", name, rc); + if (R_SUCCEEDED(rc) && out) *out = tmp; return rc; } -/* SM API extension available in Atmosphère and Atmosphère-based CFWs. */ -static Result smAtmosphereHasService(bool *out, SmServiceName name) +/* SMC API extension available in Atmosphère and Atmosphère-based CFWs. */ +static bool servicesGetExosphereApiVersion(u32 *out) { - u8 tmp = 0; - Result rc = serviceDispatchInOut(smGetServiceSession(), 65100, name, tmp); - if (R_SUCCEEDED(rc) && out) *out = tmp; - return rc; + if (!out) + { + LOG_MSG("Invalid parameters!"); + return false; + } + + Result rc = 0; + u64 version = 0; + + rc = splGetConfig(SplConfigItem_ExosphereApiVersion, &version); + if (R_FAILED(rc)) + { + LOG_MSG("splGetConfig failed! (0x%08X).", rc); + return false; + } + + *out = (u32)((version >> 40) & 0xFFFFFF); + + return true; } static Result servicesNifmUserInitialize(void) diff --git a/source/core/title.c b/source/core/title.c index b3e0ae8..b1dbe8f 100644 --- a/source/core/title.c +++ b/source/core/title.c @@ -30,7 +30,7 @@ typedef struct { u64 title_id; char name[32]; -} SystemTitleName; +} TitleSystemEntry; /* Global variables. */ @@ -92,7 +92,7 @@ static const char *g_filenameTypeStrings[] = { /* Info retrieved from https://switchbrew.org/wiki/Title_list. */ /* Titles bundled with the kernel are excluded. */ -static const SystemTitleName g_systemTitles[] = { +static const TitleSystemEntry g_systemTitles[] = { /* System modules. */ /* Meta + Program NCAs. */ { 0x0100000000000006, "usb" }, @@ -198,7 +198,10 @@ static const SystemTitleName g_systemTitles[] = { { 0x0100000000000826, "RebootlessSystemUpdateVersion" }, { 0x0100000000000827, "ContentActionTable" }, { 0x0100000000000828, "FunctionBlackList" }, + { 0x0100000000000829, "PlatformConfigCalcio" }, { 0x0100000000000830, "NgWordT" }, + { 0x0100000000000831, "PlatformConfigAula" }, + { 0x0100000000000832, "CradleFirmwareAula" }, ///< Placeholder. /* System applets. */ /* Meta + Program NCAs. */ @@ -1132,7 +1135,7 @@ static bool titleGenerateMetadataEntriesFromSystemTitles(void) } /* Fill information. */ - const SystemTitleName *system_title = &(g_systemTitles[extra_app_count]); + const TitleSystemEntry *system_title = &(g_systemTitles[extra_app_count]); cur_app_metadata->title_id = system_title->title_id; sprintf(cur_app_metadata->lang_entry.name, system_title->name);