...
 
Commits (32)
image: devkitpro/devkita64:latest
stages:
- build-prepare
- package
- create image
rebase-upstream-auto:
image: $CI_SERVER_HOST:4567/libretro/infrastructure/libretro-build-amd64-ubuntu:latest
stage: build-prepare
only: [chat]
before_script:
- url_host=`git remote get-url origin | sed -e "s/https:\/\/gitlab-ci-token:.*@//g"`
script:
- git config user.name $GIT_ACCESS_USER
- git config user.email $GIT_ACCESS_EMAIL
- git fetch origin
- git reset --hard
- git clean -fd
- git checkout $CI_COMMIT_REF_NAME
- git reset --hard origin/$CI_COMMIT_REF_NAME
- git remote set-url origin "https://$GIT_ACCESS_USER:$GIT_ACCESS_TOKEN@${url_host}"
- git remote add upstream "https://github.com/switchbrew/libnx.git"
- git fetch upstream
- git rebase upstream/master
- git push origin ${CI_BUILD_REF_NAME} --force || true
package:
stage: package
before_script:
- dkp-pacman -Syy
- dkp-pacman -S --noconfirm devkitARM
- export DEVKITPRO=/opt/devkitpro
- export DEVKITARM=/opt/devkitpro/devkitARM
script:
- make -j10
- make install
- rm -rf libnx/
- mv /opt/devkitpro/libnx libnx/
artifacts:
name: libnx
paths:
- libnx/
docker image:
stage: create image
script:
- "curl -X POST -F token=$TOKEN_DOCKER_IMAGE -F ref=master https://git.m4xw.net/api/v4/projects/103/trigger/pipeline"
when: on_success
only:
- master
nightly image:
stage: create image
script:
- "curl -X POST -F token=$TOKEN_DOCKER_IMAGE -F ref=develop https://git.m4xw.net/api/v4/projects/103/trigger/pipeline"
when: on_success
only:
- develop
- cicd/updates
This diff is collapsed.
......@@ -8,8 +8,8 @@ endif
include $(DEVKITPRO)/devkitA64/base_rules
export LIBNX_MAJOR := 2
export LIBNX_MINOR := 5
export LIBNX_MAJOR := 3
export LIBNX_MINOR := 0
export LIBNX_PATCH := 0
......@@ -33,7 +33,7 @@ INCLUDES := include external/bsd/include
#---------------------------------------------------------------------------------
ARCH := -march=armv8-a+crc+crypto -mtune=cortex-a57 -mtp=soft -fPIC -ftls-model=local-exec
CFLAGS := -g -Wall -Werror \
CFLAGS := -g -Wall \
-ffunction-sections \
-fdata-sections \
$(ARCH) \
......@@ -122,7 +122,7 @@ debug:
lib/libnx.a : lib release $(SOURCES) $(INCLUDES)
@$(MAKE) BUILD=release OUTPUT=$(CURDIR)/$@ \
BUILD_CFLAGS="-DNDEBUG=1 -O2" \
BUILD_CFLAGS="-DNDEBUG=1 -O3 -ffast-math" \
DEPSDIR=$(CURDIR)/release \
--no-print-directory -C release \
-f $(CURDIR)/Makefile
......
......@@ -36,7 +36,6 @@ extern "C" {
#include "switch/kernel/detect.h"
#include "switch/kernel/random.h"
#include "switch/kernel/jit.h"
#include "switch/kernel/ipc.h" // Deprecated
#include "switch/kernel/barrier.h"
#include "switch/sf/hipc.h"
......@@ -124,7 +123,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"
......
/**
* @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);
This diff is collapsed.
......@@ -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.
......
......@@ -51,7 +51,8 @@ static inline Result condvarWait(CondVar* c, Mutex* m)
*/
static inline Result condvarWake(CondVar* c, int num)
{
return svcSignalProcessWideKey(c, num);
svcSignalProcessWideKey(c, num);
return 0;
}
/**
......
This diff is collapsed.
/**
* @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);
......@@ -472,10 +472,9 @@ Result svcWaitProcessWideKeyAtomic(u32* key, u32* tag_location, u32 self_tag, u6
/**
* @brief Performs a condition variable wake-up operation in userspace.
* @return Result code.
* @note Syscall number 0x1D.
*/
Result svcSignalProcessWideKey(u32* key, s32 num);
void svcSignalProcessWideKey(u32* key, s32 num);
///@}
......
......@@ -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.
......
......@@ -124,6 +124,7 @@ enum {
LibnxError_NvbufFailedToInitialize,
LibnxError_LibAppletBadExit,
LibnxError_InvalidCmifOutHeader,
LibnxError_ShouldNotHappen,
};
/// libnx binder error codes
......
......@@ -38,6 +38,7 @@ Result fsdevMountSystemSaveData(const char *name, FsSaveDataSpaceId save_data_sp
/// Mounts the input fs with the specified device name. fsdev will handle closing the fs when required, including when fsdevMountDevice() fails.
/// Returns -1 when any errors occur.
/// Input device name string shouldn't exceed 31 characters, and shouldn't have a trailing colon.
int fsdevMountDevice(const char *name, FsFileSystem fs);
/// Unmounts the specified device.
......@@ -53,8 +54,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);
......
......@@ -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);
......
......@@ -21,10 +21,10 @@ typedef enum {
ApmCpuBoostMode_Type2 = 2, ///< Use performance configurations 0x9222000B and 0x9222000C.
} ApmCpuBoostMode;
/// Initialize apm. Used automatically by \ref appletInitialize.
/// Initialize apm. Used automatically by \ref appletInitialize with AppletType_Application.
Result apmInitialize(void);
/// Exit apm. Used automatically by \ref appletExit.
/// Exit apm. Used automatically by \ref appletExit with AppletType_Application.
void apmExit(void);
/// Gets the Service object for the actual apm service session.
......
......@@ -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.
......@@ -2189,13 +2189,6 @@ Result appletStartShutdownSequenceForOverlay(void);
*/
Result appletStartRebootSequenceForOverlay(void);
/**
* @brief Sets HandlingHomeButtonShortPressedEnabled.
* @note Only available with AppletType_OverlayApplet on [8.0.0+].
* @param[in] flag Flag
*/
Result appletSetHandlingHomeButtonShortPressedEnabled(bool flag);
/**
* @brief SetHealthWarningShowingState
* @note Only available with AppletType_OverlayApplet on [9.0.0+].
......@@ -2418,6 +2411,13 @@ Result appletGetLaunchStorageInfoForDebug(NcmStorageId *app_storageId, NcmStorag
*/
Result appletGetGpuErrorDetectedSystemEvent(Event *out_event);
/**
* @brief Sets HandlingHomeButtonShortPressedEnabled.
* @note Only available with AppletType_OverlayApplet on [8.0.0+]. Or with non-AppletType_OverlayApplet on [9.1.0+].
* @param[in] flag Flag
*/
Result appletSetHandlingHomeButtonShortPressedEnabled(bool flag);
///@}
///@name State / other
......
......@@ -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
......@@ -209,9 +209,11 @@ typedef enum {
} FsSaveDataFlags;
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_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), ///< [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
......
......@@ -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_*.
......
......@@ -65,7 +65,7 @@ typedef struct {
/// PlaceHolderId
typedef struct {
alignas(8) u8 c[0x10]; ///< Id
alignas(8) Uuid uuid; ///< UUID
} NcmPlaceHolderId;
/// ContentMetaKey
......@@ -97,8 +97,14 @@ typedef struct {
NcmContentInfo info;
} NcmPackagedContentInfo;
/// Used by system updates. They share the exact same struct as NcmContentMetaKey
typedef NcmContentMetaKey NcmContentMetaInfo;
/// 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 {
......
This diff is collapsed.
......@@ -8,95 +8,8 @@
#pragma once
#include "../types.h"
#include "../kernel/svc.h"
#include "../kernel/ipc.h"
#include "../sf/service.h"
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
/**
* @brief Closes a domain object by ID.
* @param[in] s Service object, necessarily a domain or domain subservice.
* @param object_id ID of the object to close.
* @return Result code.
*/
DEPRECATED
static inline Result serviceCloseObjectById(Service* s, u32 object_id) {
return ipcCloseObjectById(s->session, object_id);
}
/**
* @brief Dispatches an IPC request to a service.
* @param[in] s Service object.
* @return Result code.
*/
DEPRECATED
static inline Result serviceIpcDispatch(Service* s) {
return ipcDispatch(s->session);
}
/**
* @brief Creates a subservice object from a parent service.
* @param[out] s Service object.
* @param[in] parent Parent service, possibly a domain or domain subservice.
* @param[in] r Parsed IPC command containing handles/object IDs to create subservice from.
* @param[in] i The index of the handle/object ID to create subservice from.
*/
DEPRECATED
static inline void serviceCreateSubservice(Service* s, Service* parent, IpcParsedCommand* r, int i) {
if (r->IsDomainResponse) {
return serviceCreateDomainSubservice(s, parent, r->OutObjectIds[i]);
} else {
return serviceCreate(s, r->Handles[i]);
}
}
/**
* @brief Sends a service object with the specified cmd. This only supports domains.
* @param[in] s Service object to send.
* @param[in] cmd IPC command structure.
*/
DEPRECATED
static inline void serviceSendObject(Service* s, IpcCommand* cmd) {
if (serviceIsDomain(s) || serviceIsDomainSubservice(s)) {
ipcSendObjectId(cmd, s->object_id);
}
}
/**
* @brief Prepares the header of an IPC command structure for a service.
* @param s Service to prepare message header for
* @param cmd IPC command structure.
* @param sizeof_raw Size in bytes of the raw data structure to embed inside the IPC request
* @return Pointer to the raw embedded data structure in the request, ready to be filled out.
*/
DEPRECATED
static inline void* serviceIpcPrepareHeader(Service* s, IpcCommand* cmd, size_t sizeof_raw) {
if (serviceIsDomain(s) || serviceIsDomainSubservice(s)) {
return ipcPrepareHeaderForDomain(cmd, sizeof_raw, serviceGetObjectId(s));
} else {
return ipcPrepareHeader(cmd, sizeof_raw);
}
}
/**
* @brief Parse an IPC command response into an IPC parsed command structure for a service.
* @param s Service to prepare message header for
* @param r IPC parsed command structure to fill in.
* @param sizeof_raw Size in bytes of the raw data structure.
* @return Result code.
*/
DEPRECATED
static inline Result serviceIpcParse(Service* s, IpcParsedCommand* r, size_t sizeof_raw) {
if (serviceIsDomain(s) || serviceIsDomainSubservice(s)) {
return ipcParseDomainResponse(r, sizeof_raw);
} else {
return ipcParse(r);
}
}
#pragma GCC diagnostic pop
/// Structure representing a service name (null terminated, remaining characters set to zero).
typedef struct SmServiceName {
char name[8];
......
......@@ -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);
......
......@@ -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))
......
#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) {
......
#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"
......
#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"
......
#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;
}
#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;
......
#pragma once
#include "types.h"
#include "result.h"
#include "services/applet.h"
#include "applets/libapplet.h"
#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"
......
#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);
}
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;
}
#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"
......