Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
162 changes: 157 additions & 5 deletions libctru/include/3ds/services/cfgu.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,152 @@ typedef enum
CFG_MODEL_N2DSXL = 5, ///< New 2DS XL (JAN)
} CFG_SystemModel;

/// Configuration country values.
typedef enum
{
CFG_COUNTRY_JP = 1,
CFG_COUNTRY_AI = 8,
CFG_COUNTRY_AG = 9,
CFG_COUNTRY_AR = 10,
CFG_COUNTRY_AW = 11,
CFG_COUNTRY_BS = 12,
CFG_COUNTRY_BB = 13,
CFG_COUNTRY_BZ = 14,
CFG_COUNTRY_BO = 15,
CFG_COUNTRY_BR = 16,
CFG_COUNTRY_VG = 17,
CFG_COUNTRY_CA = 18,
CFG_COUNTRY_KY = 19,
CFG_COUNTRY_CL = 20,
CFG_COUNTRY_CO = 21,
CFG_COUNTRY_CR = 22,
CFG_COUNTRY_DM = 23,
CFG_COUNTRY_DO = 24,
CFG_COUNTRY_EC = 25,
CFG_COUNTRY_SV = 26,
CFG_COUNTRY_GF = 27,
CFG_COUNTRY_GD = 28,
CFG_COUNTRY_GP = 29,
CFG_COUNTRY_GT = 30,
CFG_COUNTRY_GY = 31,
CFG_COUNTRY_HT = 32,
CFG_COUNTRY_HN = 33,
CFG_COUNTRY_JM = 34,
CFG_COUNTRY_MQ = 35,
CFG_COUNTRY_MX = 36,
CFG_COUNTRY_MS = 37,
CFG_COUNTRY_AN = 38,
CFG_COUNTRY_NI = 39,
CFG_COUNTRY_PA = 40,
CFG_COUNTRY_PY = 41,
CFG_COUNTRY_PE = 42,
CFG_COUNTRY_KN = 43,
CFG_COUNTRY_LC = 44,
CFG_COUNTRY_VC = 45,
CFG_COUNTRY_SR = 46,
CFG_COUNTRY_TT = 47,
CFG_COUNTRY_TC = 48,
CFG_COUNTRY_US = 49,
CFG_COUNTRY_UY = 50,
CFG_COUNTRY_VI = 51,
CFG_COUNTRY_VE = 52,
CFG_COUNTRY_AL = 64,
CFG_COUNTRY_AU = 65,
CFG_COUNTRY_AT = 66,
CFG_COUNTRY_BE = 67,
CFG_COUNTRY_BA = 68,
CFG_COUNTRY_BW = 69,
CFG_COUNTRY_BG = 70,
CFG_COUNTRY_HR = 71,
CFG_COUNTRY_CY = 72,
CFG_COUNTRY_CZ = 73,
CFG_COUNTRY_DK = 74,
CFG_COUNTRY_EE = 75,
CFG_COUNTRY_FI = 76,
CFG_COUNTRY_FR = 77,
CFG_COUNTRY_DE = 78,
CFG_COUNTRY_GR = 79,
CFG_COUNTRY_HU = 80,
CFG_COUNTRY_IS = 81,
CFG_COUNTRY_IE = 82,
CFG_COUNTRY_IT = 83,
CFG_COUNTRY_LV = 84,
CFG_COUNTRY_LS = 85,
CFG_COUNTRY_LI = 86,
CFG_COUNTRY_LT = 87,
CFG_COUNTRY_LU = 88,
CFG_COUNTRY_MK = 89,
CFG_COUNTRY_MT = 90,
CFG_COUNTRY_ME = 91,
CFG_COUNTRY_MZ = 92,
CFG_COUNTRY_NA = 93,
CFG_COUNTRY_NL = 94,
CFG_COUNTRY_NZ = 95,
CFG_COUNTRY_NO = 96,
CFG_COUNTRY_PL = 97,
CFG_COUNTRY_PT = 98,
CFG_COUNTRY_RO = 99,
CFG_COUNTRY_RU = 100,
CFG_COUNTRY_RS = 101,
CFG_COUNTRY_SK = 102,
CFG_COUNTRY_SI = 103,
CFG_COUNTRY_ZA = 104,
CFG_COUNTRY_ES = 105,
CFG_COUNTRY_SZ = 106,
CFG_COUNTRY_SE = 107,
CFG_COUNTRY_CH = 108,
CFG_COUNTRY_TR = 109,
CFG_COUNTRY_GB = 110,
CFG_COUNTRY_ZM = 111,
CFG_COUNTRY_ZW = 112,
CFG_COUNTRY_AZ = 113,
CFG_COUNTRY_MR = 114,
CFG_COUNTRY_ML = 115,
CFG_COUNTRY_NE = 116,
CFG_COUNTRY_TD = 117,
CFG_COUNTRY_SD = 118,
CFG_COUNTRY_ER = 119,
CFG_COUNTRY_DJ = 120,
CFG_COUNTRY_SO = 121,
CFG_COUNTRY_AD = 122,
CFG_COUNTRY_GI = 123,
CFG_COUNTRY_GG = 124,
CFG_COUNTRY_IM = 125,
CFG_COUNTRY_JE = 126,
CFG_COUNTRY_MC = 127,
CFG_COUNTRY_TW = 128,
CFG_COUNTRY_KR = 136,
CFG_COUNTRY_HK = 144,
CFG_COUNTRY_MO = 145,
CFG_COUNTRY_ID = 152,
CFG_COUNTRY_SG = 153,
CFG_COUNTRY_TH = 154,
CFG_COUNTRY_PH = 155,
CFG_COUNTRY_MY = 156,
CFG_COUNTRY_CN = 160,
CFG_COUNTRY_AE = 168,
CFG_COUNTRY_IN = 169,
CFG_COUNTRY_EG = 170,
CFG_COUNTRY_OM = 171,
CFG_COUNTRY_QA = 172,
CFG_COUNTRY_KW = 173,
CFG_COUNTRY_SA = 174,
CFG_COUNTRY_SY = 175,
CFG_COUNTRY_BH = 176,
CFG_COUNTRY_JO = 177,
CFG_COUNTRY_SM = 184,
CFG_COUNTRY_VA = 185,
CFG_COUNTRY_BM = 186,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There should be:

  • CFG_COUNTRY_OTHER = 254 (used for some niche TWL stuff when restricting CTR country to TWL country enum)
  • CFG_COUNTRY_OTHER = 255 which can be returned by CFGU_GetCountryCodeID

} CFG_Country;

// Configuration country info structure.
typedef struct
{
u8 unk[2];
u8 state;
u8 country;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CFG_Country

} CFG_CountryInfo;

/// Initializes CFGU.
Result cfguInit(void);

Expand Down Expand Up @@ -85,17 +231,17 @@ Result CFGU_GetModelNintendo2DS(u8* value);

/**
* @brief Gets a string representing a country code.
* @param code Country code to use.
* @param string Pointer to output the string to.
* @param code Country code to use. (see @ref CFG_Country)
* @param string Pointer to output the string to. (must contain at least 2 bytes)
*/
Result CFGU_GetCountryCodeString(u16 code, u16* string);
Result CFGU_GetCountryCodeString(u16 code, char *string);
Copy link
Collaborator

@TuxSH TuxSH Feb 28, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actual type for the string is a NUL-terminated 2-char string (thus 3B in total). While char * is correct, a size hint wouldn't hurt; could you use char str[3] please?

Also, while inconsistent with the current rest-of-the-file, I would prefer (char outStr[3], CFG_Country code), likewise w/ the other functions you modified.

Corresponding decomp of the impl:

int __fastcall sub_108038(_DWORD *a1, unsigned int a2)
{
  unsigned int v2; // r6

  if ( a2 >= 0xBB )
  {
    strncpy(a1, (int *)dword_10D280, 3);
    return 0xD90103FA;
  }
  v2 = a2;
  strncpy(a1, (int *)dword_10D284[a2], 3);
  if ( (unsigned int)sub_105D90((char *)dword_10D284[v2]) < 2 )
    return 0xD90103FA;
  return 0;
}


/**
* @brief Gets a country code ID from its string.
* @param string String to use.
* @param code Pointer to output the country code to.
* @param code Pointer to output the country code to. (see @ref CFG_Country)
*/
Result CFGU_GetCountryCodeID(u16 string, u16* code);
Result CFGU_GetCountryCodeID(const char *string, u16* code);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

const char str[3]


/**
* @brief Checks if NFC (code name: fangate) is supported.
Expand Down Expand Up @@ -155,6 +301,12 @@ Result CFG_UpdateConfigSavegame(void);
*/
Result CFGU_GetSystemLanguage(u8* language);

/**
* @brief Gets the system's country info.
* @param language Pointer to write the country info to. (see @ref CFG_CountryInfo)
*/
Result CFGU_GetSystemCountryInfo(CFG_CountryInfo* country);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cfguGetSystemCountryInfo since this is just a wrapper and not an actual IPC command


/**
* @brief Deletes the NAND LocalFriendCodeSeed file, then recreates it using the LocalFriendCodeSeed data stored in memory.
*/
Expand Down
17 changes: 13 additions & 4 deletions libctru/source/services/cfgu.c
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#include <stdlib.h>
#include <string.h>
#include <3ds/types.h>
#include <3ds/result.h>
#include <3ds/svc.h>
Expand All @@ -10,6 +11,8 @@
static Handle cfguHandle;
static int cfguRefCount;

#define MIN(x,y) ((x) > (y) ? (y) : (x))

Result cfguInit(void)
{
Result ret;
Expand Down Expand Up @@ -103,7 +106,7 @@ Result CFGU_GetModelNintendo2DS(u8* value)
return (Result)cmdbuf[1];
}

Result CFGU_GetCountryCodeString(u16 code, u16* string)
Result CFGU_GetCountryCodeString(u16 code, char* string)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

char str[3]

{
Result ret = 0;
u32 *cmdbuf = getThreadCommandBuffer();
Expand All @@ -113,18 +116,19 @@ Result CFGU_GetCountryCodeString(u16 code, u16* string)

if(R_FAILED(ret = svcSendSyncRequest(cfguHandle)))return ret;

*string = (u16)cmdbuf[2] & 0xFFFF;
memcpy(string, &cmdbuf[2], 2);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

2 -> 3 (or manually assign str[2] = '\0';)


return (Result)cmdbuf[1];
}

Result CFGU_GetCountryCodeID(u16 string, u16* code)
Result CFGU_GetCountryCodeID(const char* string, u16* code)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

const char str[3]

{
Result ret = 0;
u32 *cmdbuf = getThreadCommandBuffer();

cmdbuf[0] = IPC_MakeHeader(0xA,1,0); // 0xA0040
cmdbuf[1] = (u32)string;
cmdbuf[1] = 0;
memcpy(&cmdbuf[1], string, MIN(strnlen(string, 2), 2));

if(R_FAILED(ret = svcSendSyncRequest(cfguHandle)))return ret;

Expand Down Expand Up @@ -246,6 +250,11 @@ Result CFGU_GetSystemLanguage(u8* language)
return CFGU_GetConfigInfoBlk2(1, 0xA0002, language);
}

Result CFGU_GetSystemCountryInfo(CFG_CountryInfo* country)
{
return CFGU_GetConfigInfoBlk2(4, 0xB0000, country);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cfguGetSystemCountryInfo (and nit: wrong indentation here)

}

Result CFGI_RestoreLocalFriendCodeSeed(void)
{
Result ret = 0;
Expand Down