This commit is contained in:
shchmue 2019-12-07 20:34:13 -07:00
commit 4a7aa499a2
34 changed files with 1791 additions and 195 deletions

View File

@ -124,7 +124,9 @@ extern "C" {
#include "switch/applets/libapplet.h"
#include "switch/applets/album_la.h"
#include "switch/applets/friends_la.h"
#include "switch/applets/hid_la.h"
#include "switch/applets/pctlauth.h"
#include "switch/applets/psel.h"
#include "switch/applets/error.h"
#include "switch/applets/swkbd.h"
#include "switch/applets/web.h"

View File

@ -0,0 +1,152 @@
/**
* @file hid_la.h
* @brief Wrapper for using the controller LibraryApplet.
* @author yellows8
* @copyright libnx Authors
*/
#pragma once
#include "../types.h"
#include "../services/hid.h"
/// Mode values for HidLaControllerSupportArgPrivate::mode.
typedef enum {
HidLaControllerSupportMode_ShowControllerSupport = 0, ///< ShowControllerSupport
HidLaControllerSupportMode_ShowControllerStrapGuide = 1, ///< [3.0.0+] ShowControllerStrapGuide
HidLaControllerSupportMode_ShowControllerFirmwareUpdate = 2, ///< [3.0.0+] ShowControllerFirmwareUpdate
} HidLaControllerSupportMode;
/// ControllerSupportCaller
typedef enum {
HidLaControllerSupportCaller_Application = 0, ///< Application, this is the default.
HidLaControllerSupportCaller_System = 1, ///< System. Skips the firmware-update confirmation dialog. This has the same affect as using the controller-update option from qlaunch System Settings.
} HidLaControllerSupportCaller;
/// ControllerSupportArgPrivate
typedef struct {
u32 private_size; ///< Size of this ControllerSupportArgPrivate struct.
u32 arg_size; ///< Size of the storage following this one (\ref HidLaControllerSupportArg or \ref HidLaControllerFirmwareUpdateArg).
u8 flag0; ///< Flag0
u8 flag1; ///< Flag1
u8 mode; ///< \ref HidLaControllerSupportMode
u8 controller_support_caller; ///< \ref HidLaControllerSupportCaller. Always zero except with \ref hidLaShowControllerFirmwareUpdateForSystem, which sets this to the input param.
u32 npad_style_set; ///< Output from \ref hidGetSupportedNpadStyleSet. With ShowControllerSupportForSystem on pre-3.0.0 this is value 0.
u32 npad_joy_hold_type; ///< Output from \ref hidGetNpadJoyHoldType. With ShowControllerSupportForSystem on pre-3.0.0 this is value 1.
} HidLaControllerSupportArgPrivate;
/// Common header used by HidLaControllerSupportArg*.
/// max_supported_players is 4 on pre-8.0.0, 8 on [8.0.0+]. player_count_min and player_count_max are overriden with value 4 when larger than value 4, during conversion handling for \ref HidLaControllerSupportArg on pre-8.0.0.
typedef struct {
s8 player_count_min; ///< playerCountMin. Must be >=0 and <=max_supported_players.
s8 player_count_max; ///< playerCountMax. Must be >=1 and <=max_supported_players.
u8 enable_take_over_connection; ///< enableTakeOverConnection, non-zero to enable. Disconnects the controllers when not enabled.
u8 enable_left_justify; ///< enableLeftJustify, non-zero to enable.
u8 enable_permit_joy_dual; ///< enablePermitJoyDual, non-zero to enable.
u8 enable_single_mode; ///< enableSingleMode, non-zero to enable. Enables using a single player in handheld-mode, dual-mode, or single-mode (player_count_* are overridden). Using handheld-mode is not allowed if this is not enabled.
u8 enable_identification_color; ///< When non-zero enables using identification_color.
} HidLaControllerSupportArgHeader;
/// Identification color used by HidLaControllerSupportArg*. When HidLaControllerSupportArgHeader::enable_identification_color is set this controls the color of the UI player box outline.
typedef struct {
u8 r; ///< Red color component.
u8 g; ///< Green color component.
u8 b; ///< Blue color component.
u8 a; ///< Alpha color component.
} HidLaControllerSupportArgColor;
/// ControllerSupportArg for [1.0.0+].
typedef struct {
HidLaControllerSupportArgHeader hdr; ///< \ref HidLaControllerSupportArgHeader
HidLaControllerSupportArgColor identification_color[4]; ///< \ref HidLaControllerSupportArgColor for each player, see HidLaControllerSupportArgHeader::enable_identification_color.
u8 enable_explain_text; ///< Enables using the ExplainText data when non-zero.
char explain_text[4][0x81]; ///< ExplainText for each player, NUL-terminated UTF-8 strings.
} HidLaControllerSupportArgV3;
/// ControllerSupportArg for [8.0.0+], converted to \ref HidLaControllerSupportArgV3 on pre-8.0.0.
typedef struct {
HidLaControllerSupportArgHeader hdr; ///< \ref HidLaControllerSupportArgHeader
HidLaControllerSupportArgColor identification_color[8]; ///< \ref HidLaControllerSupportArgColor for each player, see HidLaControllerSupportArgHeader::enable_identification_color.
u8 enable_explain_text; ///< Enables using the ExplainText data when non-zero.
char explain_text[8][0x81]; ///< ExplainText for each player, NUL-terminated UTF-8 strings.
} HidLaControllerSupportArg;
/// ControllerFirmwareUpdateArg
typedef struct {
u8 enable_force_update; ///< enableForceUpdate, non-zero to enable. Default is 0. Forces a firmware update when enabled, without an UI option to skip it.
u8 pad[3]; ///< Padding.
} HidLaControllerFirmwareUpdateArg;
/// ControllerSupportResultInfo. First 8-bytes from the applet output storage.
typedef struct {
s8 player_count; ///< playerCount.
u8 pad[3]; ///< Padding.
u32 selected_id; ///< \ref HidControllerID, selectedId.
} HidLaControllerSupportResultInfo;
/// Struct for the applet output storage.
typedef struct {
HidLaControllerSupportResultInfo info; ///< \ref HidLaControllerSupportResultInfo
u32 res; ///< Output res value.
} HidLaControllerSupportResultInfoInternal;
/**
* @brief Initializes a \ref HidLaControllerSupportArg with the defaults.
* @note This clears the arg, then does: HidLaControllerSupportArgHeader::player_count_min = 0, HidLaControllerSupportArgHeader::player_count_max = 4, HidLaControllerSupportArgHeader::enable_take_over_connection = 1, HidLaControllerSupportArgHeader::enable_left_justify = 1, and HidLaControllerSupportArgHeader::enable_permit_joy_dual = 1.
* @note If preferred, you can also memset \ref HidLaControllerSupportArg manually and initialize it yourself.
* @param[out] arg \ref HidLaControllerSupportArg
*/
void hidLaCreateControllerSupportArg(HidLaControllerSupportArg *arg);
/**
* @brief Initializes a \ref HidLaControllerFirmwareUpdateArg with the defaults.
* @note This just uses memset() with the arg.
* @param[out] arg \ref HidLaControllerFirmwareUpdateArg
*/
void hidLaCreateControllerFirmwareUpdateArg(HidLaControllerFirmwareUpdateArg *arg);
/**
* @brief Sets the ExplainText for the specified player and \ref HidLaControllerSupportArg.
* @note This string is displayed in the UI box for the player.
* @note HidLaControllerSupportArg::enable_explain_text must be set, otherwise this ExplainText is ignored.
* @param arg \ref HidLaControllerSupportArg
* @param[in] str Input ExplainText UTF-8 string, max length is 0x80 excluding NUL-terminator.
+ @oaram[in] id Player controller, must be <8.
*/
Result hidLaSetExplainText(HidLaControllerSupportArg *arg, const char *str, HidControllerID id);
/**
* @brief Launches the applet for ControllerSupport.
* @note This seems to only display the applet UI when doing so is actually needed? This doesn't apply to \ref hidLaShowControllerSupportForSystem.
* @param[out] result_info \ref HidLaControllerSupportResultInfo. Optional, can be NULL.
* @param[in] arg \ref HidLaControllerSupportArg
*/
Result hidLaShowControllerSupport(HidLaControllerSupportResultInfo *result_info, const HidLaControllerSupportArg *arg);
/**
* @brief Launches the applet for ControllerStrapGuide.
* @note Only available on [3.0.0+].
*/
Result hidLaShowControllerStrapGuide(void);
/**
* @brief Launches the applet for ControllerFirmwareUpdate.
* @note Only available on [3.0.0+].
* @param[in] arg \ref HidLaControllerFirmwareUpdateArg
*/
Result hidLaShowControllerFirmwareUpdate(const HidLaControllerFirmwareUpdateArg *arg);
/**
* @brief This is the system version of \ref hidLaShowControllerSupport.
* @param[out] result_info \ref HidLaControllerSupportResultInfo. Optional, can be NULL.
* @param[in] arg \ref HidLaControllerSupportArg
* @param[in] flag Input flag. When true, the applet displays the menu as if launched by qlaunch.
*/
Result hidLaShowControllerSupportForSystem(HidLaControllerSupportResultInfo *result_info, const HidLaControllerSupportArg *arg, bool flag);
/**
* @brief This is the system version of \ref hidLaShowControllerFirmwareUpdate.
* @note Only available on [3.0.0+].
* @param[in] arg \ref HidLaControllerFirmwareUpdateArg
* @param[in] caller \ref HidLaControllerSupportCaller
*/
Result hidLaShowControllerFirmwareUpdateForSystem(const HidLaControllerFirmwareUpdateArg *arg, HidLaControllerSupportCaller caller);

View File

@ -0,0 +1,202 @@
/**
* @file psel.h
* @brief Wrapper for using the playerSelect (user selection) LibraryApplet.
* @author XorTroll, yellows8
* @copyright libnx Authors
*/
#pragma once
#include "../types.h"
#include "../services/acc.h"
/// playerSelect UI modes.
typedef enum {
PselUiMode_UserSelector = 0, ///< UserSelector
PselUiMode_UserCreator = 1, ///< UserCreator
PselUiMode_EnsureNetworkServiceAccountAvailable = 2, ///< EnsureNetworkServiceAccountAvailable
PselUiMode_UserIconEditor = 3, ///< UserIconEditor
PselUiMode_UserNicknameEditor = 4, ///< UserNicknameEditor
PselUiMode_UserCreatorForStarter = 5, ///< UserCreatorForStarter
PselUiMode_NintendoAccountAuthorizationRequestContext = 6, ///< NintendoAccountAuthorizationRequestContext
PselUiMode_IntroduceExternalNetworkServiceAccount = 7, ///< IntroduceExternalNetworkServiceAccount
PselUiMode_IntroduceExternalNetworkServiceAccountForRegistration = 8, ///< [6.0.0+] IntroduceExternalNetworkServiceAccountForRegistration
PselUiMode_NintendoAccountNnidLinker = 9, ///< [6.0.0+] NintendoAccountNnidLinker
PselUiMode_LicenseRequirementsForNetworkService = 10, ///< [6.0.0+] LicenseRequirementsForNetworkService
PselUiMode_LicenseRequirementsForNetworkServiceWithUserContextImpl = 11, ///< [7.0.0+] LicenseRequirementsForNetworkServiceWithUserContextImpl
PselUiMode_UserCreatorForImmediateNaLoginTest = 12, ///< [7.0.0+] UserCreatorForImmediateNaLoginTest
} PselUiMode;
/// UI message text to display with ::PselUiMode_UserSelector. Invalid values are handled as ::PselUserSelectionPurpose_General.
typedef enum {
PselUserSelectionPurpose_General = 0, ///< "Select a user."
PselUserSelectionPurpose_GameCardRegistration = 1, ///< [2.0.0+] "Who will receive the points?"
PselUserSelectionPurpose_EShopLaunch = 2, ///< [2.0.0+] "Who is using Nintendo eShop?"
PselUserSelectionPurpose_EShopItemShow = 3, ///< [2.0.0+] "Who is making this purchase?"
PselUserSelectionPurpose_PicturePost = 4, ///< [2.0.0+] "Who is posting?"
PselUserSelectionPurpose_NintendoAccountLinkage = 5, ///< [2.0.0+] "Select a user to link to a Nintendo Account."
PselUserSelectionPurpose_SettingsUpdate = 6, ///< [2.0.0+] "Change settings for which user?"
PselUserSelectionPurpose_SaveDataDeletion = 7, ///< [2.0.0+] "Format data for which user?"
PselUserSelectionPurpose_UserMigration = 8, ///< [4.0.0+] "Which user will be transferred to another console?"
PselUserSelectionPurpose_SaveDataTransfer = 9, ///< [8.0.0+] "Send save data for which user?"
} PselUserSelectionPurpose;
/// NintendoAccountStartupDialogType
typedef enum {
PselNintendoAccountStartupDialogType_LoginAndCreate = 0, ///< LoginAndCreate
PselNintendoAccountStartupDialogType_Login = 1, ///< Login
PselNintendoAccountStartupDialogType_Create = 2, ///< Create
} PselNintendoAccountStartupDialogType;
/// Base UI settings for playerSelect.
typedef struct {
u32 mode; ///< \ref PselUiMode
u32 pad; ///< Padding.
AccountUid invalid_uid_list[ACC_USER_LIST_SIZE]; ///< List of \ref AccountUid. TODO: This is only correct for ::PselUiMode_UserSelector, for other modes this is a single uid, followed by mode-specific data (if any).
u64 application_id; ///< ApplicationId with \ref pselShowUserSelectorForLauncher.
u8 is_network_service_account_required; ///< PselUserSelectionSettings::is_network_service_account_required.
u8 is_skip_enabled; ///< PselUserSelectionSettings::is_skip_enabled
u8 unk_x92; ///< Set to value 1 by \ref pselShowUserSelectorForSystem / \ref pselShowUserSelectorForLauncher.
u8 is_permitted; ///< isPermitted. With ::PselUiMode_UserSelector: enables the option to create a new user. Set to the output from \ref accountIsUserRegistrationRequestPermitted with pselShowUserSelector*. When not set, a dialog will be displayed when the user attempts to create an user.
u8 show_skip_button; ///< PselUserSelectionSettings::show_skip_button
u8 additional_select; ///< PselUserSelectionSettings::additional_select
u8 unk_x96; ///< [2.0.0+] Set to PselUserSelectionSettingsForSystemService::enable_user_creation_button. \ref pselShowUserSelectorForLauncher / \ref pselShowUserSelector sets this to value 1.
u8 unk_x97; ///< [6.0.0+] Set to PselUserSelectionSettings::is_unqualified_user_selectable ^ 1.
} PselUiSettingsV1;
/// UI settings for versions starting with 0x10000.
typedef struct {
PselUiSettingsV1 settings; ///< \ref PselUiSettingsV1
u32 unk_x98; ///< [2.0.0+] Set to PselUserSelectionSettingsForSystemService::purpose.
u8 unk_x9c[0x4]; ///< Unknown.
} PselUiSettings;
/// UserSelectionSettings
typedef struct {
AccountUid invalid_uid_list[ACC_USER_LIST_SIZE]; ///< invalidUidList.
u8 is_skip_enabled; ///< isSkipEnabled. When set, the first user in invalid_uid_list must not be set, and additional_select must be 0. When enabled \ref accountTrySelectUserWithoutInteraction will be used to select the user, in this case the applet will only be launched if \ref accountTrySelectUserWithoutInteraction doesn't return an user.
u8 is_network_service_account_required; ///< isNetworkServiceAccountRequired. Whether the user needs to be linked to a Nintendo account.
u8 show_skip_button; ///< showSkipButton. Enables the option to skip user selection with a button.
u8 additional_select; ///< additionalSelect.
u8 is_unqualified_user_selectable; ///< [6.0.0+] isUnqualifiedUserSelectable
} PselUserSelectionSettings;
/// [2.0.0+] UserSelectionSettingsForSystemService
typedef struct {
u32 purpose; ///< \ref PselUserSelectionPurpose
u8 enable_user_creation_button; ///< Enables the user-creation button when set. Whether user-creation when pressing the button is actually allowed is controlled by PselUiSettingsV1::is_permitted.
u8 pad[0x3]; ///< Padding.
} PselUserSelectionSettingsForSystemService;
/// Return data sent after execution.
typedef struct {
Result res; ///< Result.
AccountUid user_id; ///< Selected \ref AccountUid.
} PselUiReturnArg;
/**
* @brief Creates a new UI config for the playerSelect applet with the specified mode.
* @param ui PseluiSettings struct.
* @param mode playerSelect UI mode.
*/
Result pselUiCreate(PselUiSettings *ui, PselUiMode mode);
/**
* @brief Adds an user to the user list of the applet.
* @param ui PselUiSettings struct.
* @param[in] user_id user ID.
* @note The users will be treated as invalid users for user selection mode, and as the input user for other modes.
*/
void pselUiAddUser(PselUiSettings *ui, AccountUid user_id);
/**
* @brief Sets whether users can be created in the applet.
* @param ui PselUiSettings struct.
* @param flag Flag value.
* @note Only used for ::PselUiMode_SelectUser.
*/
NX_CONSTEXPR void pselUiSetAllowUserCreation(PselUiSettings *ui, bool flag) {
if(ui->settings.mode == PselUiMode_UserSelector) {
ui->settings.is_permitted = flag!=0;
}
}
/**
* @brief Sets whether users need to be linked to a Nintendo account.
* @param ui PselUiSettings struct.
* @param flag Flag value.
*/
NX_CONSTEXPR void pselUiSetNetworkServiceRequired(PselUiSettings *ui, bool flag) {
ui->settings.is_network_service_account_required = flag;
}
/**
* @brief Sets whether selection can be skipped with a button.
* @param ui PselUiSettings struct.
* @param flag Flag value.
*/
NX_CONSTEXPR void pselUiSetSkipButtonEnabled(PselUiSettings *ui, bool flag) {
ui->settings.show_skip_button = flag!=0;
}
/**
* @brief Shows the applet with the specified UI settings.
* @param ui PselUiSettings struct.
* @param out_user Selected user ID.
* @note If user skips (see \ref pselUiSetSkipEnabled) this will return successfully but the output ID will be 0.
*/
Result pselUiShow(PselUiSettings *ui, AccountUid *out_user);
/**
* @brief This is the System version of \ref pselShowUserSelector.
* @note This uses \ref accountIsUserRegistrationRequestPermitted, hence \ref accountInitialize must be used prior to this. See also the docs for PselUserSelectionSettings::is_skip_enabled.
* @param[out] out_user Returned selected user ID.
* @param[in] settings \ref PselUserSelectionSettings
* @param[in] settings_system [2.0.0+] \ref PselUserSelectionSettingsForSystemService, ignored on prior versions.
*/
Result pselShowUserSelectorForSystem(AccountUid *out_user, const PselUserSelectionSettings *settings, const PselUserSelectionSettingsForSystemService *settings_system);
/**
* @brief This is the Launcher version of \ref pselShowUserSelector.
* @note This uses \ref accountIsUserRegistrationRequestPermitted, hence \ref accountInitialize must be used prior to this. See also the docs for PselUserSelectionSettings::is_skip_enabled.
* @param[out] out_user Returned selected user ID.
* @param[in] settings \ref PselUserSelectionSettings
* @param[in] application_id ApplicationId
*/
Result pselShowUserSelectorForLauncher(AccountUid *out_user, const PselUserSelectionSettings *settings, u64 application_id);
/**
* @brief Shows the applet to select a user.
* @note This uses \ref accountIsUserRegistrationRequestPermitted, hence \ref accountInitialize must be used prior to this. See also the docs for PselUserSelectionSettings::is_skip_enabled.
* @param[out] out_user Returned selected user ID.
* @param[in] settings \ref PselUserSelectionSettings
*/
Result pselShowUserSelector(AccountUid *out_user, const PselUserSelectionSettings *settings);
/**
* @brief Shows the applet to create a user.
* @note This uses \ref accountIsUserRegistrationRequestPermitted, hence \ref accountInitialize must be used prior to this. If the output flag is 0, an error will be thrown.
*/
Result pselShowUserCreator(void);
/**
* @brief Shows the applet to change a user's icon.
* @param[in] user Input user ID.
*/
Result pselShowUserIconEditor(AccountUid user);
/**
* @brief Shows the applet to change a user's nickname.
* @param[in] user Input user ID.
*/
Result pselShowUserNicknameEditor(AccountUid user);
/**
* @brief Shows the applet to create a user. Used by the starter applet during system setup.
*/
Result pselShowUserCreatorForStarter(void);
/**
* @brief Shows the applet for Nintendo Account Nnid linking.
* @note Only available on [6.0.0+].
* @param[in] user Input user ID.
*/
Result pselShowNintendoAccountNnidLinker(AccountUid user);

View File

@ -47,15 +47,15 @@ typedef struct {
u32 unk_x0; ///< Official sw sets this to 0 with appletStorageWrite, separately from the rest of the config struct.
char conntest_url[0x100]; ///< Connection-test URL.
char initial_url[0x400]; ///< Initial URL navigated to by the applet.
u128 uuid; ///< NIFM Network UUID. Only used by the applet when conntest_url is set.
Uuid uuid; ///< NIFM Network UUID. Only used by the applet when conntest_url is set.
u32 rev; ///< Input value for nifm cmd SetRequirementByRevision. Only used by the applet when conntest_url is set.
} PACKED WebWifiPageArg;
} WebWifiPageArg;
/// Struct for the WebWifi applet output storage.
typedef struct {
u32 unk_x0; ///< Unknown.
Result res; ///< Result
} PACKED WebWifiReturnValue;
} WebWifiReturnValue;
/// Config for WebWifi.
typedef struct {
@ -243,7 +243,7 @@ typedef enum {
* @param uuid NIFM Network UUID, for nifm cmd SetNetworkProfileId. Value 0 can be used. Only used by the applet when conntest_url is set.
* @param rev Input value for nifm cmd SetRequirementByRevision. Value 0 can be used. Only used by the applet when conntest_url is set.
*/
void webWifiCreate(WebWifiConfig* config, const char* conntest_url, const char* initial_url, u128 uuid, u32 rev);
void webWifiCreate(WebWifiConfig* config, const char* conntest_url, const char* initial_url, Uuid uuid, u32 rev);
/**
* @brief Launches WifiWebAuthApplet with the specified config and waits for it to exit.

View File

@ -1,7 +1,7 @@
/**
* @file rwlock.h
* @brief Read/write lock synchronization primitive.
* @author plutoo
* @author plutoo, SciresM
* @copyright libnx Authors
*/
#pragma once
@ -11,10 +11,13 @@
/// Read/write lock structure.
typedef struct {
Mutex mutex;
CondVar condvar_readers;
CondVar condvar_writer;
u32 readers : 31;
bool writer : 1;
CondVar condvar_reader_wait;
CondVar condvar_writer_wait;
u32 read_lock_count;
u32 read_waiter_count;
u32 write_lock_count;
u32 write_waiter_count;
u32 write_owner_tag;
} RwLock;
/**
@ -29,6 +32,13 @@ void rwlockInit(RwLock* r);
*/
void rwlockReadLock(RwLock* r);
/**
* @brief Attempts to lock the read/write lock for reading without waiting.
* @param r Read/write lock object.
* @return 1 if the mutex has been acquired successfully, and 0 on contention.
*/
bool rwlockTryReadLock(RwLock* r);
/**
* @brief Unlocks the read/write lock for reading.
* @param r Read/write lock object.
@ -41,8 +51,30 @@ void rwlockReadUnlock(RwLock* r);
*/
void rwlockWriteLock(RwLock* r);
/**
* @brief Attempts to lock the read/write lock for writing without waiting.
* @param r Read/write lock object.
* @return 1 if the mutex has been acquired successfully, and 0 on contention.
*/
bool rwlockTryWriteLock(RwLock* r);
/**
* @brief Unlocks the read/write lock for writing.
* @param r Read/write lock object.
*/
void rwlockWriteUnlock(RwLock* r);
/**
* @brief Checks if the write lock is held by the current thread.
* @param r Read/write lock object.
* @return 1 if the current hold holds the write lock, and 0 if it does not.
*/
bool rwlockIsWriteLockHeldByCurrentThread(RwLock* r);
/**
* @brief Checks if the read/write lock is owned by the current thread.
* @param r Read/write lock object.
* @return 1 if the current hold holds the write lock or if it holds read locks acquired
* while it held the write lock, and 0 if it does not.
*/
bool rwlockIsOwnedByCurrentThread(RwLock* r);

View File

@ -12,57 +12,68 @@ typedef struct {
char author[0x100];
} NacpLanguageEntry;
/// Entry forSendDataConfiguration / ReceivableDataConfiguration.
typedef struct {
u64 id;
u8 key[0x10];
} NacpSendReceiveConfiguration;
/// ns ApplicationControlProperty
typedef struct {
NacpLanguageEntry lang[16];
u8 isbn[0x25];
u8 startupUserAccount;
u8 userAccountSwitchLock;
u8 addOnContentRegistrationType;
u32 applicationAttribute;
u32 supportedLanguages;
u32 parentalControl;
u8 screenshot;
u8 videoCaptureMode;
u8 dataLossConfirmation;
u8 playLogPolicy;
u64 presenceGroupId;
s8 ratingAge[0x20];
char version[0x10];
u64 addOnContentBaseId;
u64 saveDataOwnerId;
u64 userAccountSaveDataSize;
u64 userAccountSaveDataJournalSize;
u64 deviceSaveDataSize;
u64 deviceSaveDataJournalSize;
u64 bcatDeliveryCacheStorageSize;
u64 applicationErrorCodeCategory;
u64 localCommunicationIds[0x08];
u8 logoType;
u8 logoHandling;
u8 runtimeAddOnContentInstall;
u8 reserved_x30F3[0x03];
u8 crashReport;
u8 hdcp;
u64 pseudoDeviceIdSeed;
char bcatPassphrase[0x41];
u8 reserved_x3141;
u8 reserved_x3142[0x06];
u64 userAccountSaveDataMaxSize;
u64 userAccountSaveDataMaxJournalSize;
u64 deviceSaveDataMaxSize;
u64 deviceSaveDataMaxJournalSize;
u64 temporaryStorageSize;
u64 cacheStorageSize;
u64 cacheStorageJournalSize;
u64 cacheStorageAndJournalMaxSize;
u64 cacheStorageMaxIndex;
u64 playLogQueryableApplicationId[0x10];
u8 playLogQueryCapability;
u8 repairFlag;
u8 programIndex;
u8 requiredNetworkServiceLicenseOnLaunch;
u8 reserved_x3214[0xDEC];
NacpLanguageEntry lang[16]; ///< \ref NacpLanguageEntry
u8 isbn[0x25]; ///< Isbn
u8 startup_user_account; ///< StartupUserAccount
u8 user_account_switch_lock; ///< UserAccountSwitchLock
u8 add_on_content_registration_type; ///< AddOnContentRegistrationType
u32 application_attribute; ///< ApplicationAttribute
u32 supported_languages; ///< SupportedLanguages
u32 parental_control; ///< ParentalControl
u8 screenshot; ///< Screenshot
u8 video_capture_mode; ///< VideoCaptureMode
u8 data_loss_confirmation; ///< DataLossConfirmation
u8 play_log_policy; ///< PlayLogPolicy
u64 presence_group_id; ///< PresenceGroupId
s8 rating_age[0x20]; ///< RatingAge
char display_version[0x10]; ///< DisplayVersion
u64 add_on_content_base_id; ///< AddOnContentBaseId
u64 save_data_owner_id; ///< SaveDataOwnerId
u64 user_account_save_data_size; ///< UserAccountSaveDataSize
u64 user_account_save_data_journal_size; ///< UserAccountSaveDataJournalSize
u64 device_save_data_size; ///< DeviceSaveDataSize
u64 device_save_data_journal_size; ///< DeviceSaveDataJournalSize
u64 bcat_delivery_cache_storage_size; ///< BcatDeliveryCacheStorageSize
u64 application_error_code_category; ///< ApplicationErrorCodeCategory
u64 local_communication_ids[0x8]; ///< LocalCommunicationIds
u8 logo_type; ///< LogoType
u8 logo_handling; ///< LogoHandling
u8 runtime_add_on_content_install; ///< RuntimeAddOnContentInstall
u8 reserved_x30f3[0x3]; ///< Reserved
u8 crash_report; ///< CrashReport
u8 hdcp; ///< Hdcp
u64 pseudo_device_id_seed; ///< SeedForPseudoDeviceId
char bcat_passphrase[0x41]; ///< BcatPassphrase
u8 startup_user_account_option; ///< StartupUserAccountOption
u8 reserved_for_user_account_save_data_operation[0x6]; ///< ReservedForUserAccountSaveDataOperation
u64 user_account_save_data_max_size; ///< UserAccountSaveDataMaxSize
u64 user_account_save_data_max_journal_size; ///< UserAccountSaveDataMaxJournalSize
u64 device_save_data_max_size; ///< DeviceSaveDataMaxSize
u64 device_save_data_max_journal_size; ///< DeviceSaveDataMaxJournalSize
u64 temporary_storage_size; ///< TemporaryStorageSize
u64 cache_storage_size; ///< CacheStorageSize
u64 cache_storage_journal_size; ///< CacheStorageJournalSize
u64 cache_storage_and_journal_max_size; ///< CacheStorageMaxSizeAndMaxJournalSize
u64 cache_storage_max_index; ///< CacheStorageMaxIndex
u64 play_log_queryable_application_id[0x10]; ///< PlayLogQueryableApplicationId
u8 play_log_query_capability; ///< PlayLogQueryCapability
u8 repair_flag; ///< RepairFlag
u8 program_index; ///< ProgramIndex
u8 required_network_service_license_on_launch; ///< RequiredNetworkServiceLicenseOnLaunchFlag
u32 reserved_x3214; ///< Reserved
NacpSendReceiveConfiguration send_data_configuration; ///< SendDataConfiguration
NacpSendReceiveConfiguration receivable_data_configurations[0x10]; ///< ReceivableDataConfigurations
u64 jit_configuration_flag; ///< JitConfigurationFlag
u64 memory_size; ///< MemorySize
u8 reserved_x33c0[0xc40]; ///< Reserved
} NacpStruct;
/// Get the NacpLanguageEntry from the input nacp corresponding to the current system language (this may fallback to other languages when needed). Output langentry is NULL if none found / content of entry is empty.

View File

@ -124,6 +124,7 @@ enum {
LibnxError_NvbufFailedToInitialize,
LibnxError_LibAppletBadExit,
LibnxError_InvalidCmifOutHeader,
LibnxError_ShouldNotHappen,
};
/// libnx binder error codes

View File

@ -53,8 +53,11 @@ FsFileSystem* fsdevGetDeviceFileSystem(const char *name);
/// Writes the FS-path to outpath (which has buffer size FS_MAX_PATH), for the input path (as used in stdio). The FsFileSystem is also written to device when not NULL.
int fsdevTranslatePath(const char *path, FsFileSystem** device, char *outpath);
/// This calls fsFsSetArchiveBit on the filesystem specified by the input path (as used in stdio).
Result fsdevSetArchiveBit(const char *path);
/// This calls fsFsSetConcatenationFileAttribute on the filesystem specified by the input path (as used in stdio).
Result fsdevSetConcatenationFileAttribute(const char *path);
// Uses \ref fsFsIsValidSignedSystemPartitionOnSdCard with the specified device.
Result fsdevIsValidSignedSystemPartitionOnSdCard(const char *name, bool *out);
/// This calls fsFsCreateFile on the filesystem specified by the input path (as used in stdio).
Result fsdevCreateFile(const char* path, size_t size, u32 flags);

View File

@ -74,6 +74,12 @@ Result accountGetLastOpenedUser(AccountUid *uid);
/// Get an AccountProfile for the specified userId.
Result accountGetProfile(AccountProfile* out, AccountUid uid);
/// IsUserRegistrationRequestPermitted
Result accountIsUserRegistrationRequestPermitted(bool *out);
/// TrySelectUserWithoutInteraction
Result accountTrySelectUserWithoutInteraction(AccountUid *uid, bool is_network_service_account_required);
/// Close the AccountProfile.
void accountProfileClose(AccountProfile* profile);

View File

@ -640,9 +640,9 @@ Result appletSetAlbumImageOrientation(AlbumImageOrientation orientation);
/**
* @brief Sets the DesirableKeyboardLayout.
* @note Only available with [4.0.0+].
* @param[in] layout Input layout.
* @param[in] layout Input \ref SetKeyboardLayout.
*/
Result appletSetDesirableKeyboardLayout(u32 layout);
Result appletSetDesirableKeyboardLayout(SetKeyboardLayout layout);
Result appletCreateManagedDisplayLayer(u64 *out);
@ -1347,7 +1347,7 @@ void appletNotifyRunning(bool *out);
* @note Only available with AppletType_*Application on [2.0.0+].
* @param[out] out Output PseudoDeviceId.
*/
Result appletGetPseudoDeviceId(u128 *out);
Result appletGetPseudoDeviceId(Uuid *out);
/// Set media playback state.
/// If state is set to true, screen dimming and auto sleep is disabled.
@ -2030,9 +2030,9 @@ Result appletGetNextReturnDestinationAppletIdentityInfo(AppletIdentityInfo *info
/**
* @brief Gets the DesirableKeyboardLayout previously set by \ref appletSetDesirableKeyboardLayout. An error is returned when it's not set.
* @note Only available with AppletType_LibraryApplet on [4.0.0+].
* @param[out] layout Output layout.
* @param[out] layout Output \ref SetKeyboardLayout.
*/
Result appletGetDesirableKeyboardLayout(u32 *layout);
Result appletGetDesirableKeyboardLayout(SetKeyboardLayout *layout);
/**
* @brief Pops a storage from current-LibraryApplet Extra input.

View File

@ -58,7 +58,7 @@ typedef struct {
u8 pad[3];
s8 type; ///< See FsDirEntryType.
u8 pad2[3]; ///< ?
u64 fileSize; ///< File size.
s64 file_size; ///< File size.
} FsDirectoryEntry;
/// SaveDataAttribute
@ -211,7 +211,9 @@ typedef enum {
typedef enum {
FsGameCardAttribute_AutoBootFlag = BIT(0), ///< Causes the cartridge to automatically start on bootup
FsGameCardAttribute_HistoryEraseFlag = BIT(1), ///< Causes NS to throw an error on attempt to load the cartridge
FsGameCardAttribute_RepairToolFlag = BIT(2), ///< Indicates that this gamecard is a repair tool.
FsGameCardAttribute_RepairToolFlag = BIT(2), ///< [4.0.0+] Indicates that this gamecard is a repair tool.
FsGameCardAttribute_DifferentRegionCupToTerraDeviceFlag = BIT(3), ///< [9.0.0+] DifferentRegionCupToTerraDeviceFlag
FsGameCardAttribute_DifferentRegionCupToGlobalDeviceFlag = BIT(4), ///< [9.0.0+] DifferentRegionCupToGlobalDeviceFlag
} FsGameCardAttribute;
typedef enum {
@ -272,9 +274,11 @@ typedef enum {
FsFileSystemType_RegisteredUpdate = 8, ///< [4.0.0+] RegisteredUpdate
} FsFileSystemType;
/// FileSystemQueryId
typedef enum {
FsFileSystemQueryType_SetArchiveBit = 0,
} FsFileSystemQueryType;
FsFileSystemQueryId_SetConcatenationFileAttribute = 0, ///< [4.0.0+]
FsFileSystemQueryId_IsValidSignedSystemPartitionOnSdCard = 2, ///< [8.0.0+]
} FsFileSystemQueryId;
/// FsPriority
typedef enum {
@ -346,8 +350,8 @@ Result fsSetGlobalAccessLogMode(u32 mode);
Result fsGetGlobalAccessLogMode(u32* out_mode);
// Wrapper(s) for fsCreateSaveDataFileSystemBySystemSaveDataId.
Result fsCreate_SystemSaveDataWithOwner(FsSaveDataSpaceId save_data_space_id, u64 system_save_data_id, AccountUid uid, u64 owner_id, u64 size, u64 journal_size, u32 flags);
Result fsCreate_SystemSaveData(FsSaveDataSpaceId save_data_space_id, u64 system_save_data_id, u64 size, u64 journal_size, u32 flags);
Result fsCreate_SystemSaveDataWithOwner(FsSaveDataSpaceId save_data_space_id, u64 system_save_data_id, AccountUid uid, u64 owner_id, s64 size, s64 journal_size, u32 flags);
Result fsCreate_SystemSaveData(FsSaveDataSpaceId save_data_space_id, u64 system_save_data_id, s64 size, s64 journal_size, u32 flags);
/// Wrapper(s) for fsOpenSaveDataFileSystem.
/// See FsSave for program_id and uid.
@ -358,7 +362,7 @@ Result fsOpen_SaveData(FsFileSystem* out, u64 application_id, AccountUid uid);
Result fsOpen_SystemSaveData(FsFileSystem* out, FsSaveDataSpaceId save_data_space_id, u64 system_save_data_id, AccountUid uid);
// IFileSystem
Result fsFsCreateFile(FsFileSystem* fs, const char* path, u64 size, u32 option);
Result fsFsCreateFile(FsFileSystem* fs, const char* path, s64 size, u32 option);
Result fsFsDeleteFile(FsFileSystem* fs, const char* path);
Result fsFsCreateDirectory(FsFileSystem* fs, const char* path);
Result fsFsDeleteDirectory(FsFileSystem* fs, const char* path);
@ -369,44 +373,48 @@ Result fsFsGetEntryType(FsFileSystem* fs, const char* path, FsDirEntryType* out)
Result fsFsOpenFile(FsFileSystem* fs, const char* path, u32 mode, FsFile* out);
Result fsFsOpenDirectory(FsFileSystem* fs, const char* path, u32 mode, FsDir* out);
Result fsFsCommit(FsFileSystem* fs);
Result fsFsGetFreeSpace(FsFileSystem* fs, const char* path, u64* out);
Result fsFsGetTotalSpace(FsFileSystem* fs, const char* path, u64* out);
Result fsFsGetFreeSpace(FsFileSystem* fs, const char* path, s64* out);
Result fsFsGetTotalSpace(FsFileSystem* fs, const char* path, s64* out);
Result fsFsGetFileTimeStampRaw(FsFileSystem* fs, const char* path, FsTimeStampRaw *out); ///< [3.0.0+]
Result fsFsCleanDirectoryRecursively(FsFileSystem* fs, const char* path); ///< [3.0.0+]
Result fsFsQueryEntry(FsFileSystem* fs, void *out, size_t out_size, const void *in, size_t in_size, const char* path, FsFileSystemQueryType query_type); ///< [4.0.0+]
Result fsFsQueryEntry(FsFileSystem* fs, void *out, size_t out_size, const void *in, size_t in_size, const char* path, FsFileSystemQueryId query_id); ///< [4.0.0+]
void fsFsClose(FsFileSystem* fs);
/// Uses \ref fsFsQueryEntry to set the archive bit on the specified absolute directory path.
/// This will cause HOS to treat the directory as if it were a file containing the directory's concatenated contents.
Result fsFsSetArchiveBit(FsFileSystem* fs, const char *path);
Result fsFsSetConcatenationFileAttribute(FsFileSystem* fs, const char *path);
/// Wrapper for fsFsQueryEntry with FsFileSystemQueryId_IsValidSignedSystemPartitionOnSdCard.
/// Only available on [8.0.0+].
Result fsFsIsValidSignedSystemPartitionOnSdCard(FsFileSystem* fs, bool *out);
// IFile
Result fsFileRead(FsFile* f, u64 off, void* buf, u64 read_size, u32 option, u64* bytes_read);
Result fsFileWrite(FsFile* f, u64 off, const void* buf, u64 write_size, u32 option);
Result fsFileRead(FsFile* f, s64 off, void* buf, u64 read_size, u32 option, u64* bytes_read);
Result fsFileWrite(FsFile* f, s64 off, const void* buf, u64 write_size, u32 option);
Result fsFileFlush(FsFile* f);
Result fsFileSetSize(FsFile* f, u64 sz);
Result fsFileGetSize(FsFile* f, u64* out);
Result fsFileOperateRange(FsFile* f, FsOperationId op_id, u64 off, u64 len, FsRangeInfo* out); ///< [4.0.0+]
Result fsFileSetSize(FsFile* f, s64 sz);
Result fsFileGetSize(FsFile* f, s64* out);
Result fsFileOperateRange(FsFile* f, FsOperationId op_id, s64 off, s64 len, FsRangeInfo* out); ///< [4.0.0+]
void fsFileClose(FsFile* f);
// IDirectory
Result fsDirRead(FsDir* d, u64 inval, u64* total_entries, size_t max_entries, FsDirectoryEntry *buf);
Result fsDirGetEntryCount(FsDir* d, u64* count);
Result fsDirRead(FsDir* d, s64* total_entries, size_t max_entries, FsDirectoryEntry *buf);
Result fsDirGetEntryCount(FsDir* d, s64* count);
void fsDirClose(FsDir* d);
// IStorage
Result fsStorageRead(FsStorage* s, u64 off, void* buf, u64 read_size);
Result fsStorageWrite(FsStorage* s, u64 off, const void* buf, u64 write_size);
Result fsStorageRead(FsStorage* s, s64 off, void* buf, u64 read_size);
Result fsStorageWrite(FsStorage* s, s64 off, const void* buf, u64 write_size);
Result fsStorageFlush(FsStorage* s);
Result fsStorageSetSize(FsStorage* s, u64 sz);
Result fsStorageGetSize(FsStorage* s, u64* out);
Result fsStorageOperateRange(FsStorage* s, FsOperationId op_id, u64 off, u64 len, FsRangeInfo* out); ///< [4.0.0+]
Result fsStorageSetSize(FsStorage* s, s64 sz);
Result fsStorageGetSize(FsStorage* s, s64* out);
Result fsStorageOperateRange(FsStorage* s, FsOperationId op_id, s64 off, s64 len, FsRangeInfo* out); ///< [4.0.0+]
void fsStorageClose(FsStorage* s);
// ISaveDataInfoReader
/// Read FsSaveDataInfo data into the buf array.
Result fsSaveDataInfoReaderRead(FsSaveDataInfoReader *s, FsSaveDataInfo* buf, size_t max_entries, u64* total_entries);
Result fsSaveDataInfoReaderRead(FsSaveDataInfoReader *s, FsSaveDataInfo* buf, size_t max_entries, s64* total_entries);
void fsSaveDataInfoReaderClose(FsSaveDataInfoReader *s);
// IEventNotifier

View File

@ -778,6 +778,9 @@ Result hidAcquireNpadStyleSetUpdateEventHandle(HidControllerID id, Event* out_ev
/// Sets the hold-type, see \ref HidJoyHoldType.
Result hidSetNpadJoyHoldType(HidJoyHoldType type);
/// Gets the hold-type, see \ref HidJoyHoldType.
Result hidGetNpadJoyHoldType(HidJoyHoldType *type);
/// Use this if you want to use a single joy-con as a dedicated CONTROLLER_PLAYER_*.
/// When used, both joy-cons in a pair should be used with this (CONTROLLER_PLAYER_1 and CONTROLLER_PLAYER_2 for example).
/// id must be CONTROLLER_PLAYER_*.

View File

@ -6,6 +6,7 @@
*/
#pragma once
#include "../types.h"
#include "../crypto/sha256.h"
/// StorageId
typedef enum {
@ -64,7 +65,7 @@ typedef struct {
/// PlaceHolderId
typedef struct {
alignas(8) u8 c[0x10]; ///< Id
alignas(8) Uuid uuid; ///< UUID
} NcmPlaceHolderId;
/// ContentMetaKey
@ -90,8 +91,20 @@ typedef struct {
u8 id_offset; ///< Offset of this content. Unused by most applications.
} NcmContentInfo;
/// Used by system updates. They share the exact same struct as NcmContentMetaKey
typedef NcmContentMetaKey NcmContentMetaInfo;
/// PackagedContentInfo
typedef struct {
u8 hash[SHA256_HASH_SIZE];
NcmContentInfo info;
} NcmPackagedContentInfo;
/// ContentMetaInfo
typedef struct {
u64 id; ///< Id.
u32 version; ///< Version.
u8 type; ///< \ref NcmContentMetaType
u8 attr; ///< \ref NcmContentMetaAttribute
u8 padding[2]; ///< Padding.
} NcmContentMetaInfo;
/// ContentMetaHeader
typedef struct {

View File

@ -9,6 +9,8 @@
#pragma once
#include "../types.h"
#include "../kernel/event.h"
#include "../services/time.h"
#include "../services/acc.h"
#include "../sf/service.h"
#define SET_MAX_NAME_SIZE 0x48
@ -53,6 +55,90 @@ typedef enum {
SetRegion_TWN = 6, ///< Taiwan
} SetRegion;
/// UserSelectorFlag
typedef enum {
SetSysUserSelectorFlag_SkipsIfSingleUser = BIT(0),
} SetSysUserSelectorFlag;
/// EulaVersionClockType
typedef enum {
SetSysEulaVersionClockType_NetworkSystemClock = 0,
SetSysEulaVersionClockType_SteadyClock = 1,
} SetSysEulaVersionClockType;
/// NotificationVolume
typedef enum {
SetSysNotificationVolume_Mute = 0,
SetSysNotificationVolume_Low = 1,
SetSysNotificationVolume_High = 2,
} SetSysNotificationVolume;
/// FriendPresenceOverlayPermission
typedef enum {
SetSysFriendPresenceOverlayPermission_NotConfirmed = 0,
SetSysFriendPresenceOverlayPermission_NoDisplay = 1,
SetSysFriendPresenceOverlayPermission_FavoriteFriends = 2,
SetSysFriendPresenceOverlayPermission_Friends = 3,
} SetSysFriendPresenceOverlayPermission;
/// PrimaryAlbumStorage
typedef enum {
SetSysPrimaryAlbumStorage_Nand = 0,
SetSysPrimaryAlbumStorage_SdCard = 1,
} SetSysPrimaryAlbumStorage;
/// HandheldSleepPlan
typedef enum {
SetSysHandheldSleepPlan_1Min = 0,
SetSysHandheldSleepPlan_3Min = 1,
SetSysHandheldSleepPlan_5Min = 2,
SetSysHandheldSleepPlan_10Min = 3,
SetSysHandheldSleepPlan_30Min = 4,
SetSysHandheldSleepPlan_Never = 5,
} SetSysHandheldSleepPlan;
/// ConsoleSleepPlan
typedef enum {
SetSysConsoleSleepPlan_1Hour = 0,
SetSysConsoleSleepPlan_2Hour = 1,
SetSysConsoleSleepPlan_3Hour = 2,
SetSysConsoleSleepPlan_6Hour = 3,
SetSysConsoleSleepPlan_12Hour = 4,
SetSysConsoleSleepPlan_Never = 5,
} SetSysConsoleSleepPlan;
/// ErrorReportSharePermission
typedef enum {
SetSysErrorReportSharePermission_NotConfirmed = 0,
SetSysErrorReportSharePermission_Granted = 1,
SetSysErrorReportSharePermission_Denied = 2,
} SetSysErrorReportSharePermission;
/// KeyboardLayout
typedef enum {
SetKeyboardLayout_Japanese = 0,
SetKeyboardLayout_EnglishUs = 1,
SetKeyboardLayout_EnglishUsInternational = 2,
SetKeyboardLayout_EnglishUk = 3,
SetKeyboardLayout_French = 4,
SetKeyboardLayout_FrenchCa = 5,
SetKeyboardLayout_Spanish = 6,
SetKeyboardLayout_SpanishLatin = 7,
SetKeyboardLayout_German = 8,
SetKeyboardLayout_Italian = 9,
SetKeyboardLayout_Portuguese = 10,
SetKeyboardLayout_Russian = 11,
SetKeyboardLayout_Korean = 12,
SetKeyboardLayout_ChineseSimplified = 13,
SetKeyboardLayout_ChineseTraditional = 14,
} SetKeyboardLayout;
/// ChineseTraditionalInputMethod
typedef enum {
SetChineseTraditionalInputMethod_Unknown1 = 1,
SetChineseTraditionalInputMethod_Unknown2 = 2,
} SetChineseTraditionalInputMethod;
/// PlatformRegion. Other values not listed here should be handled as "Unknown".
typedef enum {
SetSysPlatformRegion_Global = 1,
@ -65,6 +151,11 @@ typedef enum {
SetSysTouchScreenMode_Standard = 1, ///< Standard, the default.
} SetSysTouchScreenMode;
/// BatteryLot
typedef struct {
char lot[0x18]; ///< BatteryLot string.
} SetBatteryLot;
/// Structure returned by \ref setsysGetFirmwareVersion.
typedef struct {
u8 major;
@ -81,6 +172,87 @@ typedef struct {
char display_title[0x80];
} SetSysFirmwareVersion;
/// UserSelectorSettings
typedef struct {
u32 flags; ///< Bitmask with \ref SetSysUserSelectorFlag.
} SetSysUserSelectorSettings;
/// AccountSettings
typedef struct {
SetSysUserSelectorSettings settings;
} SetSysAccountSettings;
/// EulaVersion
typedef struct {
u32 version;
s32 region_code;
s32 clock_type; ///< \ref SetSysEulaVersionClockType
u32 pad;
u64 network_clock_time; ///< POSIX timestamp.
TimeSteadyClockTimePoint steady_clock_time; ///< \ref TimeSteadyClockTimePoint
} SetSysEulaVersion;
/// NotificationTime
typedef struct {
s32 hour;
s32 minute;
} SetSysNotificationTime;
/// NotificationSettings
typedef struct {
u32 flags; ///< Bitmask with NotificationFlag.
s32 volume; ///< \ref SetSysNotificationVolume
SetSysNotificationTime start_time; ///< \ref SetSysNotificationTime
SetSysNotificationTime end_time; ///< \ref SetSysNotificationTime
} SetSysNotificationSettings;
/// AccountNotificationSettings
typedef struct {
AccountUid uid; ///< \ref AccountUid
u32 flags; ///< Bitmask with AccountNotificationFlag.
s8 friend_presence_overlay_permission; ///< \ref SetSysFriendPresenceOverlayPermission
u8 pad[3]; ///< Padding.
} SetSysAccountNotificationSettings;
/// TvSettings
typedef struct {
u32 flags; ///< Bitmask with TvFlag.
s32 tv_resolution; ///< \ref SetSysTvResolution
s32 hdmi_content_type; ///< \ref SetSysHdmiContentType
s32 rgb_range; ///< \ref SetSysRgbRange
s32 cmu_mode; ///< \ref SetSysCmuMode
u32 underscan; ///< Underscan.
float gamma; ///< Gamma.
float contrast; ///< Contrast.
} SetSysTvSettings;
/// DataDeletionSettings
typedef struct {
u32 flags; ///< Bitmask with DataDeletionFlag.
s32 use_count; ///< Use count.
} SetSysDataDeletionSettings;
/// SleepSettings
typedef struct {
u32 flags; ///< Bitmask with SleepFlag.
s32 handheld_sleep_plan; ///< \ref SetSysHandheldSleepPlan
s32 console_sleep_plan; ///< \ref SetSysConsoleSleepPlan
} SetSysSleepSettings;
/// InitialLaunchSettings
typedef struct {
u32 flags; ///< Bitmask with InitialLaunchFlag.
u32 pad; ///< Padding.
TimeSteadyClockTimePoint timestamp; ///< \ref TimeSteadyClockTimePoint timestamp.
} SetSysInitialLaunchSettings;
/// RebootlessSystemUpdateVersion. This is the content of the RebootlessSystemUpdateVersion SystemData, in the "/version" file.
typedef struct {
u32 version;
u8 reserved[0x1c];
char display_version[0x20];
} SetSysRebootlessSystemUpdateVersion;
/// Output from \ref setsysGetHomeMenuScheme. This contains RGBA8 colors which correspond with the physical shell of the system.
typedef struct {
u32 main_color; ///< Main Color.
@ -133,6 +305,12 @@ void setsysExit(void);
/// Gets the Service object for the actual setsys service session.
Service* setsysGetServiceSession(void);
/**
* @brief SetLanguageCode
* @param[in] LanguageCode LanguageCode.
*/
Result setsysSetLanguageCode(u64 LanguageCode);
/**
* @brief Gets the system firmware version.
* @param[out] out Firmware version to populate.
@ -151,6 +329,33 @@ Result setsysGetLockScreenFlag(bool *out);
*/
Result setsysSetLockScreenFlag(bool flag);
/**
* @brief GetAccountSettings
* @param[out] out \ref SetSysAccountSettings
*/
Result setsysGetAccountSettings(SetSysAccountSettings *out);
/**
* @brief SetAccountSettings
* @param[in] settings \ref SetSysAccountSettings
*/
Result setsysSetAccountSettings(SetSysAccountSettings settings);
/**
* @brief GetEulaVersions
* @param[out] total_out Total output entries.
* @param[out] versions Output array of \ref SetSysEulaVersion.
* @param[in] count Size of the versions array in entries.
*/
Result setsysGetEulaVersions(s32 *total_out, SetSysEulaVersion *versions, s32 count);
/**
* @brief SetEulaVersions
* @param[in] versions Input array of \ref SetSysEulaVersion.
* @param[in] count Size of the versions array in entries.
*/
Result setsysSetEulaVersions(const SetSysEulaVersion *versions, s32 count);
/// Gets the current system theme.
Result setsysGetColorSetId(ColorSetId *out);
@ -181,6 +386,33 @@ Result setsysGetAutomaticApplicationDownloadFlag(bool *out);
*/
Result setsysSetAutomaticApplicationDownloadFlag(bool flag);
/**
* @brief GetNotificationSettings
* @param[out] out \ref SetSysNotificationSettings
*/
Result setsysGetNotificationSettings(SetSysNotificationSettings *out);
/**
* @brief SetNotificationSettings
* @param[in] settings \ref SetSysNotificationSettings
*/
Result setsysSetNotificationSettings(const SetSysNotificationSettings *settings);
/**
* @brief GetAccountNotificationSettings
* @param[out] total_out Total output entries.
* @param[out] settings Output array of \ref SetSysAccountNotificationSettings.
* @param[in] count Size of the settings array in entries.
*/
Result setsysGetAccountNotificationSettings(s32 *total_out, SetSysAccountNotificationSettings *settings, s32 count);
/**
* @brief SetAccountNotificationSettings
* @param[in] settings Input array of \ref SetSysAccountNotificationSettings.
* @param[in] count Size of the settings array in entries.
*/
Result setsysSetAccountNotificationSettings(const SetSysAccountNotificationSettings *settings, s32 count);
/**
* @brief Gets the size of a settings item value.
* @param name Name string.
@ -199,6 +431,18 @@ Result setsysGetSettingsItemValueSize(const char *name, const char *item_key, u6
*/
Result setsysGetSettingsItemValue(const char *name, const char *item_key, void *value_out, size_t value_out_size, u64 *size_out);
/**
* @brief GetTvSettings
* @param[out] out \ref SetSysTvSettings
*/
Result setsysGetTvSettings(SetSysTvSettings *out);
/**
* @brief SetTvSettings
* @param[in] settings \ref SetSysTvSettings
*/
Result setsysSetTvSettings(const SetSysTvSettings *settings);
/**
* @brief GetQuestFlag
* @param[out] out Output flag.
@ -211,6 +455,38 @@ Result setsysGetQuestFlag(bool *out);
*/
Result setsysSetQuestFlag(bool flag);
/**
* @brief GetDataDeletionSettings
* @param[out] out \ref SetSysDataDeletionSettings
*/
Result setsysGetDataDeletionSettings(SetSysDataDeletionSettings *out);
/**
* @brief SetDataDeletionSettings
* @param[in] settings \ref SetSysDataDeletionSettings
*/
Result setsysSetDataDeletionSettings(const SetSysDataDeletionSettings *settings);
/**
* @brief GetWirelessCertificationFileSize
* @param[out] out_size Output size.
*/
Result setsysGetWirelessCertificationFileSize(u64 *out_size);
/**
* @brief GetWirelessCertificationFile
* @param[out] buffer Output buffer.
* @param[in] size Output buffer size.
* @param[out] out_size Output size.
*/
Result setsysGetWirelessCertificationFile(void* buffer, size_t size, u64 *out_size);
/**
* @brief SetRegionCode
* @param[in] region \ref SetRegion
*/
Result setsysSetRegionCode(SetRegion region);
/**
* @brief IsUserSystemClockAutomaticCorrectionEnabled
* @param[out] out Output flag.
@ -223,6 +499,18 @@ Result setsysIsUserSystemClockAutomaticCorrectionEnabled(bool *out);
*/
Result setsysSetUserSystemClockAutomaticCorrectionEnabled(bool flag);
/**
* @brief GetPrimaryAlbumStorage
* @param[out] out \ref GetPrimaryAlbumStorage
*/
Result setsysGetPrimaryAlbumStorage(SetSysPrimaryAlbumStorage *out);
/**
* @brief SetPrimaryAlbumStorage
* @param[in] storage \ref SetSysPrimaryAlbumStorage
*/
Result setsysSetPrimaryAlbumStorage(SetSysPrimaryAlbumStorage storage);
/**
* @brief GetUsb30EnableFlag
* @param[out] out Output flag.
@ -235,6 +523,12 @@ Result setsysGetUsb30EnableFlag(bool *out);
*/
Result setsysSetUsb30EnableFlag(bool flag);
/**
* @brief Gets the \ref SetBatteryLot.
* @param[out] out \ref SetBatteryLot
*/
Result setsysGetBatteryLot(SetBatteryLot *out);
/**
* @brief Gets the system's serial number.
* @param serial Pointer to output the serial to. (The buffer size needs to be at least 0x19 bytes)
@ -253,6 +547,18 @@ Result setsysGetNfcEnableFlag(bool *out);
*/
Result setsysSetNfcEnableFlag(bool flag);
/**
* @brief GetSleepSettings
* @param[out] out \ref SetSysSleepSettings
*/
Result setsysGetSleepSettings(SetSysSleepSettings *out);
/**
* @brief SetSleepSettings
* @param[in] settings \ref SetSysSleepSettings
*/
Result setsysSetSleepSettings(const SetSysSleepSettings *settings);
/**
* @brief GetWirelessLanEnableFlag
* @param[out] out Output flag.
@ -265,6 +571,18 @@ Result setsysGetWirelessLanEnableFlag(bool *out);
*/
Result setsysSetWirelessLanEnableFlag(bool flag);
/**
* @brief GetInitialLaunchSettings
* @param[out] out \ref SetSysInitialLaunchSettings
*/
Result setsysGetInitialLaunchSettings(SetSysInitialLaunchSettings *out);
/**
* @brief SetInitialLaunchSettings
* @param[in] settings \ref SetSysInitialLaunchSettings
*/
Result setsysSetInitialLaunchSettings(const SetSysInitialLaunchSettings *settings);
/**
* @brief Gets the system's nickname.
* @param nickname Pointer to output the nickname to. (The buffer size needs to be at least 0x80 bytes)
@ -277,6 +595,12 @@ Result setsysGetDeviceNickname(char* nickname);
*/
Result setsysSetDeviceNickname(const char* nickname);
/**
* @brief GetProductModel
* @param[out] out Output ProductModel.
*/
Result setsysGetProductModel(s32 *out);
/**
* @brief GetBluetoothEnableFlag
* @param[out] out Output flag.
@ -289,6 +613,12 @@ Result setsysGetBluetoothEnableFlag(bool *out);
*/
Result setsysSetBluetoothEnableFlag(bool flag);
/**
* @brief GetMiiAuthorId
* @param[out] out Output MiiAuthorId.
*/
Result setsysGetMiiAuthorId(Uuid *out);
/**
* @brief Gets an event that settings will signal on flag change.
* @param out_event Event to bind. Output event will have autoclear=false.
@ -414,6 +744,48 @@ Result setsysGetHeadphoneVolumeUpdateFlag(bool *out);
*/
Result setsysSetHeadphoneVolumeUpdateFlag(bool flag);
/**
* @brief GetErrorReportSharePermission
* @note Only available on [4.0.0+].
* @param[out] out \ref SetSysErrorReportSharePermission
*/
Result setsysGetErrorReportSharePermission(SetSysErrorReportSharePermission *out);
/**
* @brief SetErrorReportSharePermission
* @note Only available on [4.0.0+].
* @param[in] permission \ref SetSysErrorReportSharePermission
*/
Result setsysSetErrorReportSharePermission(SetSysErrorReportSharePermission permission);
/**
* @brief GetAppletLaunchFlags
* @note Only available on [4.0.0+].
* @param[out] out Output AppletLaunchFlags bitmask.
*/
Result setsysGetAppletLaunchFlags(u32 *out);
/**
* @brief SetAppletLaunchFlags
* @note Only available on [4.0.0+].
* @param[in] flags Input AppletLaunchFlags bitmask.
*/
Result setsysSetAppletLaunchFlags(u32 flags);
/**
* @brief GetKeyboardLayout
* @note Only available on [4.0.0+].
* @param[out] out \ref SetKeyboardLayout
*/
Result setsysGetKeyboardLayout(SetKeyboardLayout *out);
/**
* @brief SetKeyboardLayout
* @note Only available on [4.0.0+].
* @param[in] layout \ref SetKeyboardLayout
*/
Result setsysSetKeyboardLayout(SetKeyboardLayout layout);
/**
* @brief GetRequiresRunRepairTimeReviser
* @note Only available on [5.0.0+].
@ -421,6 +793,13 @@ Result setsysSetHeadphoneVolumeUpdateFlag(bool flag);
*/
Result setsysGetRequiresRunRepairTimeReviser(bool *out);
/**
* @brief GetRebootlessSystemUpdateVersion
* @note Only available on [5.0.0+].
* @param[out] out \ref SetSysRebootlessSystemUpdateVersion
*/
Result setsysGetRebootlessSystemUpdateVersion(SetSysRebootlessSystemUpdateVersion *out);
/**
* @brief SetRequiresRunRepairTimeReviser
* @note Only available on [5.0.0+].
@ -442,6 +821,20 @@ Result setsysGetPctlReadyFlag(bool *out);
*/
Result setsysSetPctlReadyFlag(bool flag);
/**
* @brief GetChineseTraditionalInputMethod
* @note Only available on [7.0.0+].
* @param[out] out \ref SetChineseTraditionalInputMethod
*/
Result setsysGetChineseTraditionalInputMethod(SetChineseTraditionalInputMethod *out);
/**
* @brief SetChineseTraditionalInputMethod
* @note Only available on [7.0.0+].
* @param[in] method \ref SetChineseTraditionalInputMethod
*/
Result setsysSetChineseTraditionalInputMethod(SetChineseTraditionalInputMethod method);
/**
* @brief Gets the \ref SetSysHomeMenuScheme.
* @note Only available on [9.0.0+].

View File

@ -52,6 +52,11 @@ typedef struct {
char name[0x24];
} TimeLocationName;
typedef struct {
s64 time_point; ///< A point in time.
Uuid source_id; ///< An ID representing the clock source.
} TimeSteadyClockTimePoint;
/// Initialize time. Used automatically during app startup.
Result timeInitialize(void);

View File

@ -48,6 +48,8 @@ typedef u32 Result; ///< Function error code result type.
typedef void (*ThreadFunc)(void *); ///< Thread entrypoint function.
typedef void (*VoidFn)(void); ///< Function without arguments nor return value.
typedef struct { u8 uuid[0x10]; } Uuid; ///< Unique identifier.
/// Creates a bitmask from a bit number.
#ifndef BIT
#define BIT(n) (1U<<(n))

View File

@ -1,8 +1,5 @@
#include <string.h>
#include "types.h"
#include "result.h"
#include "services/applet.h"
#include "applets/libapplet.h"
#include "libapplet_internal.h"
#include "applets/album_la.h"
static Result _albumLaShow(u8 arg, bool playStartupSound) {

View File

@ -1,9 +1,5 @@
#include <string.h>
#include "types.h"
#include "result.h"
#include "services/applet.h"
#include "services/set.h"
#include "applets/libapplet.h"
#include "libapplet_internal.h"
#include "applets/error.h"
#include "runtime/hosversion.h"

View File

@ -1,8 +1,5 @@
#include <string.h>
#include "types.h"
#include "result.h"
#include "services/applet.h"
#include "applets/libapplet.h"
#include "libapplet_internal.h"
#include "applets/friends_la.h"
#include "runtime/hosversion.h"

209
nx/source/applets/hid_la.c Normal file
View File

@ -0,0 +1,209 @@
#include <string.h>
#include "libapplet_internal.h"
#include "applets/hid_la.h"
#include "runtime/hosversion.h"
static Result _hidLaShow(const HidLaControllerSupportArgPrivate *private_arg, const void* arg, size_t arg_size, void* reply, size_t reply_size) {
Result rc=0;
LibAppletArgs commonargs;
AppletHolder holder;
u32 version=0x3; // [1.0.0+]
if (hosversionAtLeast(8,0,0))
version = 0x7;
else if (hosversionAtLeast(6,0,0))
version = 0x5;
else if (hosversionAtLeast(3,0,0))
version = 0x4;
rc = appletCreateLibraryApplet(&holder, AppletId_controller, LibAppletMode_AllForeground);
if (R_FAILED(rc)) return rc;
libappletArgsCreate(&commonargs, version);
libappletArgsSetPlayStartupSound(&commonargs, (private_arg->flag1!=0) && (private_arg->flag0!=0));
if (R_SUCCEEDED(rc)) rc = libappletArgsPush(&commonargs, &holder);
if (R_SUCCEEDED(rc)) rc = libappletPushInData(&holder, private_arg, sizeof(*private_arg));
if (R_SUCCEEDED(rc)) rc = libappletPushInData(&holder, arg, arg_size);
if (R_SUCCEEDED(rc)) rc = libappletStart(&holder);
if (R_SUCCEEDED(rc)) libappletPopOutData(&holder, reply, reply_size, NULL); // Official sw ignores the rc/transfer_size.
appletHolderClose(&holder);
return rc;
}
static Result _hidLaShowControllerSupportCore(HidLaControllerSupportResultInfo *result_info, const HidLaControllerSupportArg *arg, const HidLaControllerSupportArgPrivate *private_arg) {
Result rc=0;
HidLaControllerSupportResultInfoInternal res={0};
HidLaControllerSupportArgV3 arg_v3;
const void* arg_ptr = arg;
size_t arg_size = sizeof(*arg);
if (private_arg->mode == HidLaControllerSupportMode_ShowControllerFirmwareUpdate)
return MAKERESULT(Module_Libnx, LibnxError_BadInput);
if (hosversionBefore(8,0,0)) {
memset(&arg_v3, 0, sizeof(arg_v3));
arg_ptr = &arg_v3;
arg_size = sizeof(arg_v3);
memcpy(&arg_v3.hdr, &arg->hdr, sizeof(arg->hdr));
memcpy(arg_v3.identification_color, arg->identification_color, sizeof(arg_v3.identification_color));
arg_v3.enable_explain_text = arg->enable_explain_text;
memcpy(arg_v3.explain_text, arg->explain_text, sizeof(arg_v3.explain_text));
if (arg_v3.hdr.player_count_min > 4) arg_v3.hdr.player_count_min = 4;
if (arg_v3.hdr.player_count_max > 4) arg_v3.hdr.player_count_max = 4;
}
rc = _hidLaShow(private_arg, arg_ptr, arg_size, &res, sizeof(res));
if (R_SUCCEEDED(rc)) {
if (result_info) {
*result_info = res.info;
result_info->selected_id = hidControllerIDFromOfficial(result_info->selected_id);
}
if (res.res != 0) {
rc = MAKERESULT(Module_Libnx, LibnxError_LibAppletBadExit); // Official sw would return different values for 2/{other values}, but we won't do so.
}
}
return rc;
}
static Result _hidLaShowControllerFirmwareUpdateCore(const HidLaControllerFirmwareUpdateArg *arg, const HidLaControllerSupportArgPrivate *private_arg) {
Result rc=0;
HidLaControllerSupportResultInfoInternal res={0};
if (hosversionBefore(3,0,0)) return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
if (private_arg->mode != HidLaControllerSupportMode_ShowControllerFirmwareUpdate)
return MAKERESULT(Module_Libnx, LibnxError_BadInput);
rc = _hidLaShow(private_arg, arg, sizeof(*arg), &res, sizeof(res));
if (R_SUCCEEDED(rc)) {
if (res.res != 0) {
rc = MAKERESULT(Module_Libnx, LibnxError_LibAppletBadExit);
}
}
return rc;
}
static Result _hidLaSetupControllerSupportArgPrivate(HidLaControllerSupportArgPrivate *private_arg) {
Result rc=0;
HidControllerType type;
HidJoyHoldType hold_type;
rc = hidGetSupportedNpadStyleSet(&type);
if (R_SUCCEEDED(rc)) rc = hidGetNpadJoyHoldType(&hold_type);
if (R_SUCCEEDED(rc)) {
private_arg->npad_style_set = type;
private_arg->npad_joy_hold_type = hold_type;
}
return rc;
}
void hidLaCreateControllerSupportArg(HidLaControllerSupportArg *arg) {
memset(arg, 0, sizeof(*arg));
arg->hdr.player_count_min = 0;
arg->hdr.player_count_max = 4;
arg->hdr.enable_take_over_connection = 1;
arg->hdr.enable_left_justify = 1;
arg->hdr.enable_permit_joy_dual = 1;
}
void hidLaCreateControllerFirmwareUpdateArg(HidLaControllerFirmwareUpdateArg *arg) {
memset(arg, 0, sizeof(*arg));
}
Result hidLaSetExplainText(HidLaControllerSupportArg *arg, const char *str, HidControllerID id) {
if (id >= 8)
return MAKERESULT(Module_Libnx, LibnxError_BadInput);
memset(arg->explain_text[id], 0, sizeof(arg->explain_text[id]));
strncpy(arg->explain_text[id], str, sizeof(arg->explain_text[id])-1);
return 0;
}
Result hidLaShowControllerSupport(HidLaControllerSupportResultInfo *result_info, const HidLaControllerSupportArg *arg) {
Result rc=0;
HidLaControllerSupportArgPrivate private_arg = {
.private_size = sizeof(private_arg), .arg_size = sizeof(*arg), .mode = HidLaControllerSupportMode_ShowControllerSupport
};
rc = _hidLaSetupControllerSupportArgPrivate(&private_arg);
if (R_SUCCEEDED(rc)) rc = _hidLaShowControllerSupportCore(result_info, arg, &private_arg);
return rc;
}
Result hidLaShowControllerStrapGuide(void) {
Result rc=0;
HidLaControllerSupportArg arg;
HidLaControllerSupportArgPrivate private_arg = {
.private_size = sizeof(private_arg), .arg_size = sizeof(arg), .mode = HidLaControllerSupportMode_ShowControllerStrapGuide
};
if (hosversionBefore(3,0,0)) return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
hidLaCreateControllerSupportArg(&arg);
rc = _hidLaSetupControllerSupportArgPrivate(&private_arg);
if (R_SUCCEEDED(rc)) rc = _hidLaShowControllerSupportCore(NULL, &arg, &private_arg);
return rc;
}
Result hidLaShowControllerFirmwareUpdate(const HidLaControllerFirmwareUpdateArg *arg) {
Result rc=0;
HidLaControllerSupportArgPrivate private_arg = {
.private_size = sizeof(private_arg), .arg_size = sizeof(*arg), .mode = HidLaControllerSupportMode_ShowControllerFirmwareUpdate
};
rc = _hidLaSetupControllerSupportArgPrivate(&private_arg);
if (R_SUCCEEDED(rc)) rc = _hidLaShowControllerFirmwareUpdateCore(arg, &private_arg);
return rc;
}
Result hidLaShowControllerSupportForSystem(HidLaControllerSupportResultInfo *result_info, const HidLaControllerSupportArg *arg, bool flag) {
Result rc=0;
HidLaControllerSupportArgPrivate private_arg = {
.private_size = sizeof(private_arg), .arg_size = sizeof(*arg),
.flag0 = flag!=0, .flag1 = 1, .mode = HidLaControllerSupportMode_ShowControllerSupport
};
if (hosversionAtLeast(3,0,0)) {
rc = _hidLaSetupControllerSupportArgPrivate(&private_arg);
}
else {
private_arg.npad_style_set = 0;
private_arg.npad_joy_hold_type = HidJoyHoldType_Horizontal;
}
if (R_SUCCEEDED(rc)) rc = _hidLaShowControllerSupportCore(result_info, arg, &private_arg);
return rc;
}
Result hidLaShowControllerFirmwareUpdateForSystem(const HidLaControllerFirmwareUpdateArg *arg, HidLaControllerSupportCaller caller) {
Result rc=0;
HidLaControllerSupportArgPrivate private_arg = {
.private_size = sizeof(private_arg), .arg_size = sizeof(*arg),
.flag1 = 1, .mode = HidLaControllerSupportMode_ShowControllerFirmwareUpdate, .controller_support_caller = caller
};
rc = _hidLaSetupControllerSupportArgPrivate(&private_arg);
if (R_SUCCEEDED(rc)) rc = _hidLaShowControllerFirmwareUpdateCore(arg, &private_arg);
return rc;
}

View File

@ -1,9 +1,6 @@
#include <string.h>
#include "types.h"
#include "result.h"
#include "libapplet_internal.h"
#include "arm/counter.h"
#include "services/applet.h"
#include "applets/libapplet.h"
static bool g_libappletJumpFlag;

View File

@ -0,0 +1,5 @@
#pragma once
#include "types.h"
#include "result.h"
#include "services/applet.h"
#include "applets/libapplet.h"

View File

@ -1,8 +1,5 @@
#include <string.h>
#include "types.h"
#include "result.h"
#include "services/applet.h"
#include "applets/libapplet.h"
#include "libapplet_internal.h"
#include "applets/pctlauth.h"
#include "runtime/hosversion.h"

195
nx/source/applets/psel.c Normal file
View File

@ -0,0 +1,195 @@
#include <string.h>
#include "libapplet_internal.h"
#include "applets/psel.h"
#include "runtime/hosversion.h"
Result pselUiCreate(PselUiSettings *ui, PselUiMode mode) {
memset(ui, 0, sizeof(PselUiSettings));
ui->settings.mode = mode;
return 0;
}
void pselUiAddUser(PselUiSettings *ui, AccountUid user_id) {
for(u32 i=0; i<ACC_USER_LIST_SIZE; i++) {
if(!accountUidIsValid(&ui->settings.invalid_uid_list[i])) {
ui->settings.invalid_uid_list[i] = user_id;
break;
}
}
}
static u32 _pselGetLaVersion() {
u32 ver = 0x1; // [1.0.0]
if (hosversionAtLeast(6,0,0))
ver = 0x20000;
else if (hosversionAtLeast(2,0,0))
ver = 0x10000;
return ver;
}
Result pselUiShow(PselUiSettings *ui, AccountUid *out_user) {
Result rc = 0;
LibAppletArgs args;
u32 la_ver = _pselGetLaVersion();
libappletArgsCreate(&args, la_ver);
PselUiReturnArg ret;
size_t reply_size;
const void* arg_ptr = ui;
size_t arg_size = sizeof(*ui);
if (la_ver == 0x1) { // [1.0.0]
arg_ptr = &ui->settings;
arg_size = sizeof(ui->settings);
}
// TODO: Official sw supports pushing an optional additional storage from appletCreateTransferMemoryStorage with writable=0 using an input buffer, when that buffer is specified. However, sdknso itself doesn't use this besides a wrapper func. Figure out what this, and implement it?(libappletLaunch could no longer be used with this)
rc = libappletLaunch(AppletId_playerSelect, &args, arg_ptr, arg_size, &ret, sizeof(ret), &reply_size);
if (R_SUCCEEDED(rc)) {
rc = ret.res; // Official sw returns this directly.
if (R_SUCCEEDED(rc) && out_user) *out_user = ret.user_id;
}
return rc;
}
static Result _pselUserSelectorCommonInit(PselUiSettings *ui, const PselUserSelectionSettings *settings) {
Result rc=0;
bool tmp=0;
rc = accountIsUserRegistrationRequestPermitted(&tmp);
if (R_FAILED(rc)) return rc;
ui->settings.is_permitted = tmp!=0;
memcpy(&ui->settings.invalid_uid_list, settings->invalid_uid_list, sizeof(settings->invalid_uid_list));
ui->settings.is_network_service_account_required = settings->is_network_service_account_required;
ui->settings.is_skip_enabled = settings->is_skip_enabled;
ui->settings.show_skip_button = settings->show_skip_button;
ui->settings.additional_select = settings->additional_select;
if (hosversionAtLeast(6,0,0))
ui->settings.unk_x97 = settings->is_unqualified_user_selectable ^ 1;
return rc;
}
static Result _pselShowUserSelectorCommon(PselUiSettings *ui, AccountUid *out_user) {
Result rc=0;
bool show_psel=1;
if (ui->settings.is_skip_enabled!=0) {
if (accountUidIsValid(&ui->settings.invalid_uid_list[0]) || ui->settings.additional_select)
rc = MAKERESULT(Module_Libnx, LibnxError_ShouldNotHappen);
if (R_SUCCEEDED(rc)) rc = accountTrySelectUserWithoutInteraction(out_user, ui->settings.is_network_service_account_required);
if (R_SUCCEEDED(rc) && accountUidIsValid(out_user)) show_psel = 0;
}
if (R_SUCCEEDED(rc) && show_psel)
rc = pselUiShow(ui, out_user);
return rc;
}
Result pselShowUserSelectorForSystem(AccountUid *out_user, const PselUserSelectionSettings *settings, const PselUserSelectionSettingsForSystemService *settings_system) {
PselUiSettings ui;
Result rc = pselUiCreate(&ui, PselUiMode_UserSelector);
if(R_SUCCEEDED(rc)) {
rc = _pselUserSelectorCommonInit(&ui, settings);
if(R_SUCCEEDED(rc)) {
ui.settings.unk_x92 = 1;
if (hosversionAtLeast(2,0,0)) {
ui.settings.unk_x96 = settings_system->enable_user_creation_button;
ui.unk_x98 = settings_system->purpose;
}
}
if(R_SUCCEEDED(rc)) rc = _pselShowUserSelectorCommon(&ui, out_user);
}
return rc;
}
Result pselShowUserSelectorForLauncher(AccountUid *out_user, const PselUserSelectionSettings *settings, u64 application_id) {
PselUiSettings ui;
Result rc = pselUiCreate(&ui, PselUiMode_UserSelector);
if(R_SUCCEEDED(rc)) {
rc = _pselUserSelectorCommonInit(&ui, settings);
if(R_SUCCEEDED(rc)) {
ui.settings.application_id = application_id;
ui.settings.unk_x92 = 1;
if (hosversionAtLeast(2,0,0))
ui.settings.unk_x96 = 1;
}
if(R_SUCCEEDED(rc)) rc = _pselShowUserSelectorCommon(&ui, out_user);
}
return rc;
}
Result pselShowUserSelector(AccountUid *out_user, const PselUserSelectionSettings *settings) {
PselUiSettings ui;
Result rc = pselUiCreate(&ui, PselUiMode_UserSelector);
if(R_SUCCEEDED(rc)) {
rc = _pselUserSelectorCommonInit(&ui, settings);
if(R_SUCCEEDED(rc) && hosversionAtLeast(2,0,0)) ui.settings.unk_x96 = 1;
if(R_SUCCEEDED(rc)) rc = _pselShowUserSelectorCommon(&ui, out_user);
}
return rc;
}
Result pselShowUserCreator(void) {
PselUiSettings ui;
bool tmp=0;
Result rc = pselUiCreate(&ui, PselUiMode_UserCreator);
if(R_SUCCEEDED(rc)) {
rc = accountIsUserRegistrationRequestPermitted(&tmp);
if(R_SUCCEEDED(rc) && tmp==0) rc = MAKERESULT(Module_Libnx, LibnxError_ShouldNotHappen);
if(R_SUCCEEDED(rc)) rc = pselUiShow(&ui, NULL);
}
return rc;
}
Result pselShowUserIconEditor(AccountUid user) {
PselUiSettings ui;
Result rc = pselUiCreate(&ui, PselUiMode_UserIconEditor);
if(R_SUCCEEDED(rc)) {
pselUiAddUser(&ui, user);
rc = pselUiShow(&ui, NULL);
}
return rc;
}
Result pselShowUserNicknameEditor(AccountUid user) {
PselUiSettings ui;
Result rc = pselUiCreate(&ui, PselUiMode_UserNicknameEditor);
if(R_SUCCEEDED(rc)) {
pselUiAddUser(&ui, user);
rc = pselUiShow(&ui, NULL);
}
return rc;
}
Result pselShowUserCreatorForStarter(void) {
PselUiSettings ui;
Result rc = pselUiCreate(&ui, PselUiMode_UserCreatorForStarter);
if(R_SUCCEEDED(rc)) {
rc = pselUiShow(&ui, NULL);
}
return rc;
}
Result pselShowNintendoAccountNnidLinker(AccountUid user) {
if (hosversionBefore(6,0,0))
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
PselUiSettings ui;
Result rc = pselUiCreate(&ui, PselUiMode_NintendoAccountNnidLinker);
if(R_SUCCEEDED(rc)) {
pselUiAddUser(&ui, user);
rc = pselUiShow(&ui, NULL);
}
return rc;
}

View File

@ -1,10 +1,7 @@
#include <string.h>
#include <malloc.h>
#include <math.h>
#include "types.h"
#include "result.h"
#include "services/applet.h"
#include "applets/libapplet.h"
#include "libapplet_internal.h"
#include "applets/swkbd.h"
#include "runtime/hosversion.h"
#include "runtime/util/utf.h"

View File

@ -1,9 +1,6 @@
#include <string.h>
#include <malloc.h>
#include "types.h"
#include "result.h"
#include "services/applet.h"
#include "applets/libapplet.h"
#include "libapplet_internal.h"
#include "applets/web.h"
#include "runtime/hosversion.h"
@ -55,7 +52,7 @@ static Result _webShow(AppletHolder *holder, AppletId id, u32 version, void* arg
return rc;
}
void webWifiCreate(WebWifiConfig* config, const char* conntest_url, const char* initial_url, u128 uuid, u32 rev) {
void webWifiCreate(WebWifiConfig* config, const char* conntest_url, const char* initial_url, Uuid uuid, u32 rev) {
memset(config, 0, sizeof(*config));
if (conntest_url) strncpy(config->arg.conntest_url, conntest_url, sizeof(config->arg.conntest_url)-1);

View File

@ -1,59 +1,170 @@
// Copyright 2018 plutoo
#include "kernel/mutex.h"
#include "kernel/rwlock.h"
#include "../internal.h"
NX_INLINE u32 _GetCurrentThreadTag(void) {
return getThreadVars()->handle;
}
void rwlockInit(RwLock* r) {
mutexInit(&r->mutex);
condvarInit(&r->condvar_readers);
condvarInit(&r->condvar_writer);
condvarInit(&r->condvar_reader_wait);
condvarInit(&r->condvar_writer_wait);
r->readers = 0;
r->writer = false;
r->read_lock_count = 0;
r->read_waiter_count = 0;
r->write_lock_count = 0;
r->write_waiter_count = 0;
r->write_owner_tag = 0;
}
void rwlockReadLock(RwLock* r) {
mutexLock(&r->mutex);
const u32 cur_tag = _GetCurrentThreadTag();
while (r->writer) {
condvarWait(&r->condvar_writer, &r->mutex);
if (r->write_owner_tag == cur_tag) {
r->read_lock_count++;
return;
}
r->readers++;
mutexLock(&r->mutex);
while (r->write_waiter_count > 0) {
r->read_waiter_count++;
condvarWait(&r->condvar_reader_wait, &r->mutex);
r->read_waiter_count--;
}
r->read_lock_count++;
mutexUnlock(&r->mutex);
}
bool rwlockTryReadLock(RwLock* r) {
const u32 cur_tag = _GetCurrentThreadTag();
if (r->write_owner_tag == cur_tag) {
r->read_lock_count++;
return true;
}
if (!mutexTryLock(&r->mutex)) {
return false;
}
const bool got_lock = r->write_waiter_count == 0;
if (got_lock) {
r->read_lock_count++;
}
mutexUnlock(&r->mutex);
return got_lock;
}
void rwlockReadUnlock(RwLock* r) {
mutexLock(&r->mutex);
const u32 cur_tag = _GetCurrentThreadTag();
if (--r->readers == 0) {
condvarWakeAll(&r->condvar_readers);
if (r->write_owner_tag == cur_tag) {
// Write lock is owned by this thread.
r->read_lock_count--;
if (r->read_lock_count == 0 && r->write_lock_count == 0) {
// Relinquish control of the lock.
r->write_owner_tag = 0;
if (r->write_waiter_count > 0) {
condvarWakeOne(&r->condvar_writer_wait);
} else if (r->read_waiter_count > 0) {
condvarWakeAll(&r->condvar_reader_wait);
}
// Corresponding mutexLock was called in WriteLock/WriteTryLock.
mutexUnlock(&r->mutex);
}
} else {
// Write lock isn't owned by this thread.
mutexLock(&r->mutex);
r->read_lock_count--;
if (r->read_lock_count == 0 && r->write_waiter_count > 0) {
condvarWakeOne(&r->condvar_writer_wait);
}
mutexUnlock(&r->mutex);
}
}
void rwlockWriteLock(RwLock* r) {
const u32 cur_tag = _GetCurrentThreadTag();
if (r->write_owner_tag == cur_tag) {
r->write_lock_count++;
return;
}
mutexLock(&r->mutex);
while (r->writer) {
condvarWait(&r->condvar_writer, &r->mutex);
while (r->read_lock_count > 0) {
r->write_waiter_count++;
condvarWait(&r->condvar_writer_wait, &r->mutex);
r->write_waiter_count--;
}
r->writer = true;
r->write_lock_count = 1;
r->write_owner_tag = cur_tag;
while (r->readers > 0) {
condvarWait(&r->condvar_readers, &r->mutex);
// mutexUnlock(&r->mutex) is intentionally not called here.
// The mutex will be unlocked by a call to ReadUnlock or WriteUnlock.
}
bool rwlockTryWriteLock(RwLock* r) {
const u32 cur_tag = _GetCurrentThreadTag();
if (r->write_owner_tag == cur_tag) {
r->write_lock_count++;
return true;
}
if (!mutexTryLock(&r->mutex)) {
return false;
}
if (r->read_lock_count > 0) {
mutexUnlock(&r->mutex);
return false;
}
r->write_lock_count = 1;
r->write_owner_tag = cur_tag;
// mutexUnlock(&r->mutex) is intentionally not called here.
// The mutex will be unlocked by a call to ReadUnlock or WriteUnlock.
return true;
}
void rwlockWriteUnlock(RwLock* r) {
mutexLock(&r->mutex);
// This function assumes the write lock is held.
// This means that r->mutex is locked, and r->write_owner_tag == cur_tag.
// if (r->write_owner_tag == cur_tag)
{
r->write_lock_count--;
if (r->write_lock_count == 0 && r->read_lock_count == 0) {
// Relinquish control of the lock.
r->write_owner_tag = 0;
r->writer = false;
condvarWakeAll(&r->condvar_writer);
if (r->write_waiter_count > 0) {
condvarWakeOne(&r->condvar_writer_wait);
} else if (r->read_waiter_count > 0) {
condvarWakeAll(&r->condvar_reader_wait);
}
// Corresponding mutexLock was called in WriteLock/WriteTryLock.
mutexUnlock(&r->mutex);
}
}
}
bool rwlockIsWriteLockHeldByCurrentThread(RwLock* r) {
return r->write_owner_tag == _GetCurrentThreadTag() && r->write_lock_count > 0;
}
bool rwlockIsOwnedByCurrentThread(RwLock* r) {
return r->write_owner_tag == _GetCurrentThreadTag();
}

View File

@ -57,7 +57,7 @@ typedef struct
{
FsFile fd;
int flags; /*! Flags used in open(2) */
u64 offset; /*! Current file offset */
s64 offset; /*! Current file offset */
FsTimeStampRaw timestamps;
} fsdev_file_t;
@ -397,14 +397,24 @@ Result fsdevCommitDevice(const char *name)
return fsFsCommit(&device->fs);
}
Result fsdevSetArchiveBit(const char *path) {
Result fsdevSetConcatenationFileAttribute(const char *path) {
char *fs_path = __nx_dev_path_buf;
fsdev_fsdevice *device = NULL;
if(fsdev_getfspath(_REENT, path, &device, fs_path)==-1)
return MAKERESULT(Module_Libnx, LibnxError_NotFound);
return fsFsSetArchiveBit(&device->fs, fs_path);
return fsFsSetConcatenationFileAttribute(&device->fs, fs_path);
}
Result fsdevIsValidSignedSystemPartitionOnSdCard(const char *name, bool *out) {
fsdev_fsdevice *device;
device = fsdevFindDevice(name);
if(device==NULL)
return MAKERESULT(Module_Libnx, LibnxError_NotFound);
return fsFsIsValidSignedSystemPartitionOnSdCard(&device->fs, out);
}
Result fsdevCreateFile(const char* path, size_t size, u32 flags) {
@ -911,7 +921,7 @@ fsdev_seek(struct _reent *r,
int whence)
{
Result rc;
u64 offset;
s64 offset;
/* get pointer to our data */
fsdev_file_t *file = (fsdev_file_t*)fd;
@ -973,7 +983,7 @@ fsdev_fstat(struct _reent *r,
struct stat *st)
{
Result rc;
u64 size;
s64 size;
fsdev_file_t *file = (fsdev_file_t*)fd;
rc = fsFileGetSize(&file->fd, &size);
@ -1318,7 +1328,7 @@ fsdev_dirnext(struct _reent *r,
struct stat *filestat)
{
Result rc;
u64 entries;
s64 entries;
ssize_t units;
FsDirectoryEntry *entry;
@ -1341,7 +1351,7 @@ fsdev_dirnext(struct _reent *r,
/* fetch the next batch */
memset(entry_data, 0, sizeof(FsDirectoryEntry)*max_entries);
rc = fsDirRead(&dir->fd, 0, &entries, max_entries, entry_data);
rc = fsDirRead(&dir->fd, &entries, max_entries, entry_data);
if(R_SUCCEEDED(rc))
{
if(entries == 0)
@ -1367,7 +1377,7 @@ fsdev_dirnext(struct _reent *r,
else if(entry->type == FsDirEntryType_File)
{
filestat->st_mode = S_IFREG;
filestat->st_size = entry->fileSize;
filestat->st_size = entry->file_size;
}
else
{
@ -1440,7 +1450,7 @@ fsdev_statvfs(struct _reent *r,
Result rc=0;
char *fs_path = __nx_dev_path_buf;
fsdev_fsdevice *device = r->deviceData;
u64 freespace = 0, total_space = 0;
s64 freespace = 0, total_space = 0;
if(fsdev_getfspath(r, path, &device, fs_path)==-1)
return -1;

View File

@ -64,7 +64,7 @@ static romfs_file *romFS_file(romfs_mount *mount, u32 off)
static ssize_t _romfs_read(romfs_mount *mount, u64 offset, void* buffer, u64 size)
{
u64 pos = mount->offset + offset;
s64 pos = mount->offset + offset;
u64 read = 0;
Result rc = 0;
if(mount->fd_type == RomfsSource_FsFile)

View File

@ -116,6 +116,21 @@ Result accountGetProfile(AccountProfile* out, AccountUid uid) {
);
}
Result accountIsUserRegistrationRequestPermitted(bool *out) {
u64 pid_placeholder=0;
u8 tmp=0;
Result rc = serviceDispatchInOut(&g_accSrv, 50, pid_placeholder, tmp,
.in_send_pid = true,
);
if (R_SUCCEEDED(rc) && out) *out = tmp & 1;
return rc;
}
Result accountTrySelectUserWithoutInteraction(AccountUid *uid, bool is_network_service_account_required) {
u8 tmp=is_network_service_account_required!=0;
return serviceDispatchInOut(&g_accSrv, 51, tmp, *uid);
}
// IProfile
void accountProfileClose(AccountProfile* profile) {

View File

@ -1056,7 +1056,7 @@ IPC_MAKE_CMD_IMPL(static Result _appletSetOutOfFocusSuspendingEnabled(bool flag)
IPC_MAKE_CMD_IMPL_HOSVER(Result appletSetControllerFirmwareUpdateSection(bool flag), &g_appletISelfController, 17, _appletCmdInBoolNoOut, (3,0,0), flag)
IPC_MAKE_CMD_IMPL_HOSVER(Result appletSetRequiresCaptureButtonShortPressedMessage(bool flag), &g_appletISelfController, 18, _appletCmdInBoolNoOut, (3,0,0), flag)
IPC_MAKE_CMD_IMPL_HOSVER(Result appletSetAlbumImageOrientation(AlbumImageOrientation orientation), &g_appletISelfController, 19, _appletCmdInU32NoOut, (3,0,0), orientation)
IPC_MAKE_CMD_IMPL_HOSVER(Result appletSetDesirableKeyboardLayout(u32 layout), &g_appletISelfController, 20, _appletCmdInU32NoOut, (4,0,0), layout)
IPC_MAKE_CMD_IMPL_HOSVER(Result appletSetDesirableKeyboardLayout(SetKeyboardLayout layout), &g_appletISelfController, 20, _appletCmdInU32NoOut, (4,0,0), layout)
IPC_MAKE_CMD_IMPL( Result appletCreateManagedDisplayLayer(u64 *out), &g_appletISelfController, 40, _appletCmdNoInOutU64, out)
IPC_MAKE_CMD_IMPL_HOSVER(Result appletIsSystemBufferSharingEnabled(void), &g_appletISelfController, 41, _appletCmdNoIO, (4,0,0))
@ -2005,7 +2005,7 @@ void appletNotifyRunning(bool *out) {
if (R_FAILED(rc)) fatalThrow(MAKERESULT(Module_Libnx, LibnxError_BadAppletNotifyRunning));
}
Result appletGetPseudoDeviceId(u128 *out) {
Result appletGetPseudoDeviceId(Uuid *out) {
if (!serviceIsActive(&g_appletSrv) || !_appletIsApplication())
return MAKERESULT(Module_Libnx, LibnxError_NotInitialized);
if (hosversionBefore(2,0,0))
@ -2593,7 +2593,19 @@ Result appletGetCallerAppletIdentityInfoStack(AppletIdentityInfo *stack, s32 cou
}
IPC_MAKE_CMD_IMPL_INITEXPR_HOSVER(Result appletGetNextReturnDestinationAppletIdentityInfo(AppletIdentityInfo *info), &g_appletILibraryAppletSelfAccessor, 18, _appletGetIdentityInfo, __nx_applet_type != AppletType_LibraryApplet, (4,0,0), info)
IPC_MAKE_CMD_IMPL_INITEXPR_HOSVER(Result appletGetDesirableKeyboardLayout(u32 *layout), &g_appletILibraryAppletSelfAccessor, 19, _appletCmdNoInOutU32, __nx_applet_type != AppletType_LibraryApplet, (4,0,0), layout)
Result appletGetDesirableKeyboardLayout(SetKeyboardLayout *layout) {
if (__nx_applet_type != AppletType_LibraryApplet)
return MAKERESULT(Module_Libnx, LibnxError_NotInitialized);
if (hosversionBefore(4,0,0))
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
u32 tmp=0;
Result rc = _appletCmdNoInOutU32(&g_appletILibraryAppletSelfAccessor, &tmp, 19);
if (R_SUCCEEDED(rc) && layout) *layout = tmp;
return rc;
}
IPC_MAKE_CMD_IMPL_INITEXPR( Result appletPopExtraStorage(AppletStorage *s), &g_appletILibraryAppletSelfAccessor, 20, _appletCmdNoInOutStorage, __nx_applet_type != AppletType_LibraryApplet, s)
IPC_MAKE_CMD_IMPL_INITEXPR( Result appletGetPopExtraStorageEvent(Event *out_event), &g_appletILibraryAppletSelfAccessor, 25, _appletCmdGetEvent, __nx_applet_type != AppletType_LibraryApplet, out_event, false)
IPC_MAKE_CMD_IMPL_INITEXPR( Result appletUnpopInData(AppletStorage *s), &g_appletILibraryAppletSelfAccessor, 30, _appletCmdInStorage, __nx_applet_type != AppletType_LibraryApplet, s)

View File

@ -446,7 +446,7 @@ Result fsGetGlobalAccessLogMode(u32* out_mode) {
}
// Wrapper(s) for fsCreateSaveDataFileSystemBySystemSaveDataId.
Result fsCreate_SystemSaveDataWithOwner(FsSaveDataSpaceId save_data_space_id, u64 system_save_data_id, AccountUid uid, u64 owner_id, u64 size, u64 journal_size, u32 flags) {
Result fsCreate_SystemSaveDataWithOwner(FsSaveDataSpaceId save_data_space_id, u64 system_save_data_id, AccountUid uid, u64 owner_id, s64 size, s64 journal_size, u32 flags) {
FsSaveDataAttribute attr = {
.uid = uid,
.system_save_data_id = system_save_data_id,
@ -463,7 +463,7 @@ Result fsCreate_SystemSaveDataWithOwner(FsSaveDataSpaceId save_data_space_id, u6
return fsCreateSaveDataFileSystemBySystemSaveDataId(&attr, &create);
}
Result fsCreate_SystemSaveData(FsSaveDataSpaceId save_data_space_id, u64 system_save_data_id, u64 size, u64 journal_size, u32 flags) {
Result fsCreate_SystemSaveData(FsSaveDataSpaceId save_data_space_id, u64 system_save_data_id, s64 size, s64 journal_size, u32 flags) {
return fsCreate_SystemSaveDataWithOwner(save_data_space_id, system_save_data_id, (AccountUid){}, 0, size, journal_size, flags);
}
@ -494,7 +494,7 @@ Result fsOpen_SystemSaveData(FsFileSystem* out, FsSaveDataSpaceId save_data_spac
// IFileSystem
//-----------------------------------------------------------------------------
Result fsFsCreateFile(FsFileSystem* fs, const char* path, u64 size, u32 option) {
Result fsFsCreateFile(FsFileSystem* fs, const char* path, s64 size, u32 option) {
const struct {
u32 option;
u64 size;
@ -585,12 +585,12 @@ static Result _fsFsCmdWithInPathAndOutU64(FsFileSystem* fs, const char* path, u6
);
}
Result fsFsGetFreeSpace(FsFileSystem* fs, const char* path, u64* out) {
return _fsFsCmdWithInPathAndOutU64(fs, path, out, 11);
Result fsFsGetFreeSpace(FsFileSystem* fs, const char* path, s64* out) {
return _fsFsCmdWithInPathAndOutU64(fs, path, (u64*)out, 11);
}
Result fsFsGetTotalSpace(FsFileSystem* fs, const char* path, u64* out) {
return _fsFsCmdWithInPathAndOutU64(fs, path, out, 12);
Result fsFsGetTotalSpace(FsFileSystem* fs, const char* path, s64* out) {
return _fsFsCmdWithInPathAndOutU64(fs, path, (u64*)out, 12);
}
Result fsFsCleanDirectoryRecursively(FsFileSystem* fs, const char* path) {
@ -610,14 +610,14 @@ Result fsFsGetFileTimeStampRaw(FsFileSystem* fs, const char* path, FsTimeStampRa
);
}
Result fsFsQueryEntry(FsFileSystem* fs, void *out, size_t out_size, const void *in, size_t in_size, const char* path, FsFileSystemQueryType query_type) {
Result fsFsQueryEntry(FsFileSystem* fs, void *out, size_t out_size, const void *in, size_t in_size, const char* path, FsFileSystemQueryId query_id) {
if (hosversionBefore(4,0,0))
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
char send_path[FS_MAX_PATH] = {0};
strncpy(send_path, path, sizeof(send_path)-1);
return _fsObjectDispatchIn(&fs->s, 15, query_type,
return _fsObjectDispatchIn(&fs->s, 15, query_id,
.buffer_attrs = {
SfBufferAttr_HipcPointer | SfBufferAttr_In,
SfBufferAttr_HipcMapAlias | SfBufferAttr_In | SfBufferAttr_HipcMapTransferAllowsNonSecure,
@ -631,8 +631,18 @@ Result fsFsQueryEntry(FsFileSystem* fs, void *out, size_t out_size, const void *
);
}
Result fsFsSetArchiveBit(FsFileSystem* fs, const char *path) {
return fsFsQueryEntry(fs, NULL, 0, NULL, 0, path, FsFileSystemQueryType_SetArchiveBit);
Result fsFsSetConcatenationFileAttribute(FsFileSystem* fs, const char *path) {
return fsFsQueryEntry(fs, NULL, 0, NULL, 0, path, FsFileSystemQueryId_SetConcatenationFileAttribute);
}
Result fsFsIsValidSignedSystemPartitionOnSdCard(FsFileSystem* fs, bool *out) {
if (hosversionBefore(8,0,0))
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
u8 tmp=0;
Result rc = fsFsQueryEntry(fs, &tmp, sizeof(tmp), NULL, 0, "/", FsFileSystemQueryId_IsValidSignedSystemPartitionOnSdCard);
if (R_SUCCEEDED(rc) && out) *out = tmp & 1;
return rc;
}
void fsFsClose(FsFileSystem* fs) {
@ -643,11 +653,11 @@ void fsFsClose(FsFileSystem* fs) {
// IFile
//-----------------------------------------------------------------------------
Result fsFileRead(FsFile* f, u64 off, void* buf, u64 read_size, u32 option, u64* bytes_read) {
Result fsFileRead(FsFile* f, s64 off, void* buf, u64 read_size, u32 option, u64* bytes_read) {
const struct {
u32 option;
u32 pad;
u64 offset;
s64 offset;
u64 read_size;
} in = { option, 0, off, read_size };
@ -657,11 +667,11 @@ Result fsFileRead(FsFile* f, u64 off, void* buf, u64 read_size, u32 option, u64*
);
}
Result fsFileWrite(FsFile* f, u64 off, const void* buf, u64 write_size, u32 option) {
Result fsFileWrite(FsFile* f, s64 off, const void* buf, u64 write_size, u32 option) {
const struct {
u32 option;
u32 pad;
u64 offset;
s64 offset;
u64 write_size;
} in = { option, 0, off, write_size };
@ -675,23 +685,23 @@ Result fsFileFlush(FsFile* f) {
return _fsCmdNoIO(&f->s, 2);
}
Result fsFileSetSize(FsFile* f, u64 sz) {
Result fsFileSetSize(FsFile* f, s64 sz) {
return _fsObjectDispatchIn(&f->s, 3, sz);
}
Result fsFileGetSize(FsFile* f, u64* out) {
Result fsFileGetSize(FsFile* f, s64* out) {
return _fsObjectDispatchOut(&f->s, 4, *out);
}
Result fsFileOperateRange(FsFile* f, FsOperationId op_id, u64 off, u64 len, FsRangeInfo* out) {
Result fsFileOperateRange(FsFile* f, FsOperationId op_id, s64 off, s64 len, FsRangeInfo* out) {
if (hosversionBefore(4,0,0))
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
const struct {
u32 op_id;
u32 pad;
u64 off;
u64 len;
s64 off;
s64 len;
} in = { op_id, 0, off, len };
return _fsObjectDispatchInOut(&f->s, 5, in, *out);
@ -706,14 +716,14 @@ void fsDirClose(FsDir* d) {
_fsObjectClose(&d->s);
}
Result fsDirRead(FsDir* d, u64 inval, u64* total_entries, size_t max_entries, FsDirectoryEntry *buf) {
return _fsObjectDispatchInOut(&d->s, 0, inval, *total_entries,
Result fsDirRead(FsDir* d, s64* total_entries, size_t max_entries, FsDirectoryEntry *buf) {
return _fsObjectDispatchOut(&d->s, 0, *total_entries,
.buffer_attrs = { SfBufferAttr_HipcMapAlias | SfBufferAttr_Out },
.buffers = { { buf, sizeof(FsDirectoryEntry)*max_entries } },
.buffers = { { buf, max_entries*sizeof(FsDirectoryEntry) } },
);
}
Result fsDirGetEntryCount(FsDir* d, u64* count) {
Result fsDirGetEntryCount(FsDir* d, s64* count) {
return _fsObjectDispatchOut(&d->s, 1, *count);
}
@ -721,9 +731,9 @@ Result fsDirGetEntryCount(FsDir* d, u64* count) {
// IStorage
//-----------------------------------------------------------------------------
Result fsStorageRead(FsStorage* s, u64 off, void* buf, u64 read_size) {
Result fsStorageRead(FsStorage* s, s64 off, void* buf, u64 read_size) {
const struct {
u64 offset;
s64 offset;
u64 read_size;
} in = { off, read_size };
@ -733,9 +743,9 @@ Result fsStorageRead(FsStorage* s, u64 off, void* buf, u64 read_size) {
);
}
Result fsStorageWrite(FsStorage* s, u64 off, const void* buf, u64 write_size) {
Result fsStorageWrite(FsStorage* s, s64 off, const void* buf, u64 write_size) {
const struct {
u64 offset;
s64 offset;
u64 write_size;
} in = { off, write_size };
@ -749,23 +759,23 @@ Result fsStorageFlush(FsStorage* s) {
return _fsCmdNoIO(&s->s, 2);
}
Result fsStorageSetSize(FsStorage* s, u64 sz) {
Result fsStorageSetSize(FsStorage* s, s64 sz) {
return _fsObjectDispatchIn(&s->s, 3, sz);
}
Result fsStorageGetSize(FsStorage* s, u64* out) {
Result fsStorageGetSize(FsStorage* s, s64* out) {
return _fsObjectDispatchOut(&s->s, 4, *out);
}
Result fsStorageOperateRange(FsStorage* s, FsOperationId op_id, u64 off, u64 len, FsRangeInfo* out) {
Result fsStorageOperateRange(FsStorage* s, FsOperationId op_id, s64 off, s64 len, FsRangeInfo* out) {
if (hosversionBefore(4,0,0))
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
const struct {
u32 op_id;
u32 pad;
u64 off;
u64 len;
s64 off;
s64 len;
} in = { op_id, 0, off, len };
return _fsObjectDispatchInOut(&s->s, 5, in, *out);
@ -780,10 +790,10 @@ void fsStorageClose(FsStorage* s) {
//-----------------------------------------------------------------------------
// Actually called ReadSaveDataInfo
Result fsSaveDataInfoReaderRead(FsSaveDataInfoReader *s, FsSaveDataInfo* buf, size_t max_entries, u64* total_entries) {
Result fsSaveDataInfoReaderRead(FsSaveDataInfoReader *s, FsSaveDataInfo* buf, size_t max_entries, s64* total_entries) {
return _fsObjectDispatchOut(&s->s, 0, *total_entries,
.buffer_attrs = { SfBufferAttr_HipcMapAlias | SfBufferAttr_Out },
.buffers = { { buf, sizeof(FsSaveDataInfo)*max_entries } },
.buffers = { { buf, max_entries*sizeof(FsSaveDataInfo) } },
);
}

View File

@ -719,6 +719,19 @@ static Result _hidCmdOutU32(u32 *out, u32 cmd_id) {
);
}
static Result _hidCmdOutU64(u64 *out, u32 cmd_id) {
Result rc;
u64 AppletResourceUserId;
rc = appletGetAppletResourceUserId(&AppletResourceUserId);
if (R_FAILED(rc))
AppletResourceUserId = 0;
return serviceDispatchInOut(&g_hidSrv, cmd_id, AppletResourceUserId, *out,
.in_send_pid = true,
);
}
static Result _hidCmdNoInOutU8(u8 *out, u32 cmd_id) {
return serviceDispatchOut(&g_hidSrv, cmd_id, *out);
}
@ -835,6 +848,13 @@ Result hidSetNpadJoyHoldType(HidJoyHoldType type) {
return _hidCmdWithInputU64(type, 120);
}
Result hidGetNpadJoyHoldType(HidJoyHoldType *type) {
u64 tmp=0;
Result rc = _hidCmdOutU64(&tmp, 121);
if (R_SUCCEEDED(rc) && type) *type = tmp;
return rc;
}
Result hidSetNpadJoyAssignmentModeSingleByDefault(HidControllerID id) {
return _hidCmdWithInputU32(hidControllerIDToOfficial(id), 122);
}

View File

@ -79,6 +79,10 @@ static Result _setCmdNoInOutBool(Service* srv, bool *out, u32 cmd_id) {
return rc;
}
static Result _setCmdNoInOutUuid(Service* srv, Uuid *out, u32 cmd_id) {
return serviceDispatchOut(srv, cmd_id, *out);
}
static Result _setCmdInU8NoOut(Service* srv, u8 inval, u64 cmd_id) {
return serviceDispatchIn(srv, cmd_id, inval);
}
@ -91,6 +95,10 @@ static Result _setCmdInU32NoOut(Service* srv, u32 inval, u32 cmd_id) {
return serviceDispatchIn(srv, cmd_id, inval);
}
static Result _setCmdInU64NoOut(Service* srv, u64 inval, u32 cmd_id) {
return serviceDispatchIn(srv, cmd_id, inval);
}
static Result setInitializeLanguageCodesCache(void) {
if (g_setLanguageCodesInitialized) return 0;
Result rc = 0;
@ -186,6 +194,10 @@ Result setGetRegionCode(SetRegion *out) {
return rc;
}
Result setsysSetLanguageCode(u64 LanguageCode) {
return _setCmdInU64NoOut(&g_setsysSrv, LanguageCode, 0);
}
static Result _setsysGetFirmwareVersionImpl(SetSysFirmwareVersion *out, u32 cmd_id) {
return serviceDispatch(&g_setsysSrv, cmd_id,
.buffer_attrs = { SfBufferAttr_FixedSize | SfBufferAttr_HipcPointer | SfBufferAttr_Out },
@ -210,6 +222,28 @@ Result setsysSetLockScreenFlag(bool flag) {
return _setCmdInBoolNoOut(&g_setsysSrv, flag, 8);
}
Result setsysGetAccountSettings(SetSysAccountSettings *out) {
return serviceDispatchOut(&g_setsysSrv, 17, *out);
}
Result setsysSetAccountSettings(SetSysAccountSettings settings) {
return serviceDispatchIn(&g_setsysSrv, 18, settings);
}
Result setsysGetEulaVersions(s32 *total_out, SetSysEulaVersion *versions, s32 count) {
return serviceDispatchOut(&g_setsysSrv, 21, *total_out,
.buffer_attrs = { SfBufferAttr_HipcMapAlias | SfBufferAttr_Out },
.buffers = { { versions, count*sizeof(SetSysEulaVersion) } },
);
}
Result setsysSetEulaVersions(const SetSysEulaVersion *versions, s32 count) {
return serviceDispatch(&g_setsysSrv, 22,
.buffer_attrs = { SfBufferAttr_HipcMapAlias | SfBufferAttr_In },
.buffers = { { versions, count*sizeof(SetSysEulaVersion) } },
);
}
Result setsysGetColorSetId(ColorSetId *out) {
u32 color_set=0;
Result rc = _setCmdNoInOutU32(&g_setsysSrv, &color_set, 23);
@ -237,6 +271,28 @@ Result setsysSetAutomaticApplicationDownloadFlag(bool flag) {
return _setCmdInBoolNoOut(&g_setsysSrv, flag, 28);
}
Result setsysGetNotificationSettings(SetSysNotificationSettings *out) {
return serviceDispatchOut(&g_setsysSrv, 29, *out);
}
Result setsysSetNotificationSettings(const SetSysNotificationSettings *settings) {
return serviceDispatchIn(&g_setsysSrv, 30, *settings);
}
Result setsysGetAccountNotificationSettings(s32 *total_out, SetSysAccountNotificationSettings *settings, s32 count) {
return serviceDispatchOut(&g_setsysSrv, 31, *total_out,
.buffer_attrs = { SfBufferAttr_HipcMapAlias | SfBufferAttr_Out },
.buffers = { { settings, count*sizeof(SetSysAccountNotificationSettings) } },
);
}
Result setsysSetAccountNotificationSettings(const SetSysAccountNotificationSettings *settings, s32 count) {
return serviceDispatch(&g_setsysSrv, 32,
.buffer_attrs = { SfBufferAttr_HipcMapAlias | SfBufferAttr_In },
.buffers = { { settings, count*sizeof(SetSysAccountNotificationSettings) } },
);
}
Result setsysGetSettingsItemValueSize(const char *name, const char *item_key, u64 *size_out) {
char send_name[SET_MAX_NAME_SIZE];
char send_item_key[SET_MAX_NAME_SIZE];
@ -281,6 +337,14 @@ Result setsysGetSettingsItemValue(const char *name, const char *item_key, void *
);
}
Result setsysGetTvSettings(SetSysTvSettings *out) {
return serviceDispatchOut(&g_setsysSrv, 39, *out);
}
Result setsysSetTvSettings(const SetSysTvSettings *settings) {
return serviceDispatchIn(&g_setsysSrv, 40, *settings);
}
Result setsysGetQuestFlag(bool *out) {
return _setCmdNoInOutBool(&g_setsysSrv, out, 47);
}
@ -289,6 +353,29 @@ Result setsysSetQuestFlag(bool flag) {
return _setCmdInBoolNoOut(&g_setsysSrv, flag, 48);
}
Result setsysGetDataDeletionSettings(SetSysDataDeletionSettings *out) {
return serviceDispatchOut(&g_setsysSrv, 49, *out);
}
Result setsysSetDataDeletionSettings(const SetSysDataDeletionSettings *settings) {
return serviceDispatchIn(&g_setsysSrv, 50, *settings);
}
Result setsysGetWirelessCertificationFileSize(u64 *out_size) {
return _setCmdNoInOut64(&g_setsysSrv, out_size, 55);
}
Result setsysGetWirelessCertificationFile(void* buffer, size_t size, u64 *out_size) {
return serviceDispatchOut(&g_setsysSrv, 56, *out_size,
.buffer_attrs = { SfBufferAttr_HipcMapAlias | SfBufferAttr_Out },
.buffers = { { buffer, size } },
);
}
Result setsysSetRegionCode(SetRegion region) {
return _setCmdInU32NoOut(&g_setsysSrv, region, 57);
}
Result setsysIsUserSystemClockAutomaticCorrectionEnabled(bool *out) {
return _setCmdNoInOutBool(&g_setsysSrv, out, 60);
}
@ -297,6 +384,17 @@ Result setsysSetUserSystemClockAutomaticCorrectionEnabled(bool flag) {
return _setCmdInBoolNoOut(&g_setsysSrv, flag, 61);
}
Result setsysGetPrimaryAlbumStorage(SetSysPrimaryAlbumStorage *out) {
u32 tmp=0;
Result rc = _setCmdNoInOutU32(&g_setsysSrv, &tmp, 63);
if (R_SUCCEEDED(rc) && out) *out = tmp;
return rc;
}
Result setsysSetPrimaryAlbumStorage(SetSysPrimaryAlbumStorage storage) {
return _setCmdInU32NoOut(&g_setsysSrv, storage, 64);
}
Result setsysGetUsb30EnableFlag(bool *out) {
return _setCmdNoInOutBool(&g_setsysSrv, out, 65);
}
@ -305,6 +403,10 @@ Result setsysSetUsb30EnableFlag(bool flag) {
return _setCmdInBoolNoOut(&g_setsysSrv, flag, 66);
}
Result setsysGetBatteryLot(SetBatteryLot *out) {
return serviceDispatchOut(&g_setsysSrv, 67, *out);
}
Result setsysGetSerialNumber(char *serial) {
char out[0x18]={0};
@ -324,6 +426,14 @@ Result setsysSetNfcEnableFlag(bool flag) {
return _setCmdInBoolNoOut(&g_setsysSrv, flag, 70);
}
Result setsysGetSleepSettings(SetSysSleepSettings *out) {
return serviceDispatchOut(&g_setsysSrv, 71, *out);
}
Result setsysSetSleepSettings(const SetSysSleepSettings *settings) {
return serviceDispatchIn(&g_setsysSrv, 72, *settings);
}
Result setsysGetWirelessLanEnableFlag(bool *out) {
return _setCmdNoInOutBool(&g_setsysSrv, out, 73);
}
@ -332,6 +442,14 @@ Result setsysSetWirelessLanEnableFlag(bool flag) {
return _setCmdInBoolNoOut(&g_setsysSrv, flag, 74);
}
Result setsysGetInitialLaunchSettings(SetSysInitialLaunchSettings *out) {
return serviceDispatchOut(&g_setsysSrv, 75, *out);
}
Result setsysSetInitialLaunchSettings(const SetSysInitialLaunchSettings *settings) {
return serviceDispatchIn(&g_setsysSrv, 76, *settings);
}
Result setsysGetDeviceNickname(char* nickname) {
return serviceDispatch(&g_setsysSrv, 77,
.buffer_attrs = { SfBufferAttr_HipcMapAlias | SfBufferAttr_Out },
@ -349,6 +467,10 @@ Result setsysSetDeviceNickname(const char* nickname) {
);
}
Result setsysGetProductModel(s32 *out) {
return _setCmdNoInOutU32(&g_setsysSrv, (u32*)out, 79);
}
Result setsysGetBluetoothEnableFlag(bool *out) {
return _setCmdNoInOutBool(&g_setsysSrv, out, 88);
}
@ -357,6 +479,10 @@ Result setsysSetBluetoothEnableFlag(bool flag) {
return _setCmdInBoolNoOut(&g_setsysSrv, flag, 89);
}
Result setsysGetMiiAuthorId(Uuid *out) {
return _setCmdNoInOutUuid(&g_setsysSrv, out, 90);
}
Result setsysBindFatalDirtyFlagEvent(Event *out_event) {
return _setCmdGetEvent(&g_setsysSrv, out_event, false, 93);
}
@ -485,6 +611,54 @@ Result setsysSetHeadphoneVolumeUpdateFlag(bool flag) {
return _setCmdInBoolNoOut(&g_setsysSrv, flag, 118);
}
Result setsysGetErrorReportSharePermission(SetSysErrorReportSharePermission *out) {
if (hosversionBefore(4,0,0))
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
u32 tmp=0;
Result rc = _setCmdNoInOutU32(&g_setsysSrv, &tmp, 124);
if (R_SUCCEEDED(rc) && out) *out = tmp;
return rc;
}
Result setsysSetErrorReportSharePermission(SetSysErrorReportSharePermission permission) {
if (hosversionBefore(4,0,0))
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
return _setCmdInU32NoOut(&g_setsysSrv, permission, 125);
}
Result setsysGetAppletLaunchFlags(u32 *out) {
if (hosversionBefore(4,0,0))
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
return _setCmdNoInOutU32(&g_setsysSrv, out, 126);
}
Result setsysSetAppletLaunchFlags(u32 flags) {
if (hosversionBefore(4,0,0))
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
return _setCmdInU32NoOut(&g_setsysSrv, flags, 127);
}
Result setsysGetKeyboardLayout(SetKeyboardLayout *out) {
if (hosversionBefore(4,0,0))
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
u32 tmp=0;
Result rc = _setCmdNoInOutU32(&g_setsysSrv, &tmp, 136);
if (R_SUCCEEDED(rc) && out) *out = tmp;
return rc;
}
Result setsysSetKeyboardLayout(SetKeyboardLayout layout) {
if (hosversionBefore(4,0,0))
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
return _setCmdInU32NoOut(&g_setsysSrv, layout, 137);
}
Result setsysGetRequiresRunRepairTimeReviser(bool *out) {
if (hosversionBefore(5,0,0))
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
@ -492,6 +666,13 @@ Result setsysGetRequiresRunRepairTimeReviser(bool *out) {
return _setCmdNoInOutBool(&g_setsysSrv, out, 141);
}
Result setsysGetRebootlessSystemUpdateVersion(SetSysRebootlessSystemUpdateVersion *out) {
if (hosversionBefore(5,0,0))
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
return serviceDispatchOut(&g_setsysSrv, 149, *out);
}
Result setsysSetRequiresRunRepairTimeReviser(bool flag) {
if (hosversionBefore(5,0,0))
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
@ -513,6 +694,23 @@ Result setsysSetPctlReadyFlag(bool flag) {
return _setCmdInBoolNoOut(&g_setsysSrv, flag, 157);
}
Result setsysGetChineseTraditionalInputMethod(SetChineseTraditionalInputMethod *out) {
if (hosversionBefore(7,0,0))
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
u32 tmp=0;
Result rc = _setCmdNoInOutU32(&g_setsysSrv, &tmp, 170);
if (R_SUCCEEDED(rc) && out) *out = tmp;
return rc;
}
Result setsysSetChineseTraditionalInputMethod(SetChineseTraditionalInputMethod method) {
if (hosversionBefore(7,0,0))
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
return _setCmdInU32NoOut(&g_setsysSrv, method, 171);
}
Result setsysGetHomeMenuScheme(SetSysHomeMenuScheme *out) {
if (hosversionBefore(9,0,0))
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);