...
 
Commits (27)
image: devkitpro/devkita64:latest
stages:
- package
- create image
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
......@@ -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
......
......@@ -102,6 +102,7 @@ extern "C" {
#include "switch/services/pdm.h"
#include "switch/services/grc.h"
#include "switch/services/friends.h"
#include "switch/services/notif.h"
#include "switch/display/binder.h"
#include "switch/display/parcel.h"
......
......@@ -6,7 +6,6 @@
*/
#pragma once
#include "../types.h"
#include "../services/applet.h"
#include "../services/set.h"
/// Error type for ErrorCommonHeader.type.
......
This diff is collapsed.
......@@ -169,6 +169,7 @@ typedef enum {
InfoType_UserExceptionContextAddress = 20, ///< [5.0.0+] Address of the process's exception context (for break).
InfoType_TotalNonSystemMemorySize = 21, ///< [6.0.0+] Total amount of memory available for process, excluding that for process memory management.
InfoType_UsedNonSystemMemorySize = 22, ///< [6.0.0+] Amount of memory used by process, excluding that for process memory management.
InfoType_IsApplication = 23, ///< [9.0.0+] Whether the specified process is an Application.
InfoType_ThreadTickCount = 0xF0000002, ///< Number of ticks spent on thread.
} InfoType;
......
......@@ -31,10 +31,10 @@ NX_CONSTEXPR FsDirectoryEntry* fsdevDirGetEntries(fsdev_dir_t *dir)
Result fsdevMountSdmc(void);
/// Mounts the specified save data.
Result fsdevMountSaveData(const char *name, u64 program_id, AccountUid uid);
Result fsdevMountSaveData(const char *name, u64 application_id, AccountUid uid);
/// Mounts the specified system save data.
Result fsdevMountSystemSaveData(const char *name, FsSaveDataSpaceId saveDataSpaceId, u64 saveID, AccountUid uid);
Result fsdevMountSystemSaveData(const char *name, FsSaveDataSpaceId save_data_space_id, u64 system_save_data_id, AccountUid uid);
/// 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.
......
......@@ -10,6 +10,7 @@
#include "../../types.h"
#include "../../services/fs.h"
#include "../../services/ncm_types.h"
/// RomFS header.
typedef struct
......@@ -95,7 +96,7 @@ Result romfsMountFromFsdev(const char *path, u64 offset, const char *name);
* @param storageId Storage ID to mount from.
* @param name Device mount name.
*/
Result romfsMountFromDataArchive(u64 dataId, FsStorageId storageId, const char *name);
Result romfsMountFromDataArchive(u64 dataId, NcmStorageId storageId, const char *name);
/// Unmounts the RomFS device.
Result romfsUnmount(const char *name);
......
......@@ -11,10 +11,9 @@
#define ACC_USER_LIST_SIZE 8
typedef enum {
AccountServiceType_NotInitialized = 0, ///< Same as ::AccountServiceType_Application during \ref accountInitialize.
AccountServiceType_Application = 1, ///< Initializes acc:u0.
AccountServiceType_System = 2, ///< Initializes acc:u1.
AccountServiceType_Administrator = 3, ///< Initializes acc:su.
AccountServiceType_Application = 0, ///< Initializes acc:u0.
AccountServiceType_System = 1, ///< Initializes acc:u1.
AccountServiceType_Administrator = 2, ///< Initializes acc:su.
} AccountServiceType;
/// Profile
......@@ -44,14 +43,13 @@ typedef struct {
char nickname[0x20]; ///< UTF-8 Nickname.
} AccountProfileBase;
/**
* @brief Sets the \ref AccountServiceType for initialization. Call this function before \ref accountInitialize, if needed.
* @note By default ::AccountServiceType_NotInitialized will be used.
*/
void accountSetServiceType(AccountServiceType serviceType);
/// NetworkServiceAccountId
typedef struct {
u64 id; ///< Id.
} AccountNetworkServiceAccountId;
/// Initialize account.
Result accountInitialize(void);
Result accountInitialize(AccountServiceType service_type);
/// Exit account.
void accountExit(void);
......
This diff is collapsed.
......@@ -7,7 +7,6 @@
#pragma once
#include "../types.h"
#include "../sf/service.h"
#include "../services/caps.h"
/// Initialize caps:sc. Only available on [2.0.0+].
Result capsscInitialize(void);
......
......@@ -6,6 +6,9 @@
*/
#pragma once
#include "../types.h"
#include "../kernel/event.h"
#include "../services/applet.h"
#include "../services/acc.h"
#include "../sf/service.h"
/// InAppScreenName
......@@ -14,3 +17,38 @@ typedef struct {
u64 languageCode; ///< LanguageCode, see set.h.
} FriendsInAppScreenName;
/// FriendInvitationGameModeDescription
typedef struct {
u8 unk_x0[0xc00]; ///< Unknown.
} FriendsFriendInvitationGameModeDescription;
/// FriendInvitationId
typedef struct {
u64 id; ///< Id.
} FriendsFriendInvitationId;
/// FriendInvitationGroupId
typedef struct {
u64 id; ///< Id.
} FriendsFriendInvitationGroupId;
/**
* @brief Gets an Event which is signaled when data is available with \ref friendsTryPopFriendInvitationNotificationInfo.
* @note This is a wrapper for \ref appletGetFriendInvitationStorageChannelEvent, see that for the usage requirements.
* @note The Event must be closed by the user once finished with it.
* @param[out] out_event Output Event with autoclear=false.
*/
NX_INLINE Result friendsGetFriendInvitationNotificationEvent(Event *out_event) {
return appletGetFriendInvitationStorageChannelEvent(out_event);
}
/**
* @brief Uses \ref appletTryPopFromFriendInvitationStorageChannel then reads the data from there into the output params.
* @note This is a wrapper for \ref appletTryPopFromFriendInvitationStorageChannel, see that for the usage requirements.
* @param[out] uid \ref AccountUid. Optional, can be NULL.
* @param[out] buffer Output buffer.
* @param[out] size Output buffer size.
* @param[out] out_size Size of the data which was written into the output buffer. Optional, can be NULL.
*/
Result friendsTryPopFriendInvitationNotificationInfo(AccountUid *uid, void* buffer, u64 size, u64 *out_size);
This diff is collapsed.
......@@ -7,7 +7,7 @@
#pragma once
#include "../types.h"
#include "../sf/service.h"
#include "../services/fs.h"
#include "../services/ncm_types.h"
/// Initialize fsp-pr.
Result fsprInitialize(void);
......@@ -18,7 +18,7 @@ void fsprExit(void);
/// Gets the Service object for the actual fsp-pr service session.
Service* fsprGetServiceSession(void);
Result fsprRegisterProgram(u64 pid, u64 tid, FsStorageId sid, const void *fs_access_header, size_t fah_size, const void *fs_access_control, size_t fac_size);
Result fsprRegisterProgram(u64 pid, u64 tid, NcmStorageId sid, const void *fs_access_header, size_t fah_size, const void *fs_access_control, size_t fac_size);
Result fsprUnregisterProgram(u64 pid);
Result fsprSetCurrentProcess(void);
Result fsprSetEnabledProgramVerification(bool enabled);
......@@ -7,8 +7,7 @@
#pragma once
#include "../types.h"
#include "../sf/service.h"
#include "../services/fs.h"
#include "../services/ncm.h"
#include "../services/ncm_types.h"
typedef struct {
u8 main_thread_priority;
......
......@@ -7,7 +7,7 @@
#pragma once
#include "../types.h"
#include "../sf/service.h"
#include "../services/fs.h"
#include "../services/ncm_types.h"
typedef struct {
Service s;
......@@ -26,7 +26,7 @@ void lrExit(void);
/// Gets the Service object for the actual lr service session.
Service* lrGetServiceSession(void);
Result lrOpenLocationResolver(FsStorageId storage, LrLocationResolver* out);
Result lrOpenLocationResolver(NcmStorageId storage, LrLocationResolver* out);
Result lrOpenRegisteredLocationResolver(LrRegisteredLocationResolver* out);
// TODO: Other ILocationResolverManager commands
......
......@@ -6,6 +6,7 @@
*/
#pragma once
#include "../types.h"
#include "../services/ncm_types.h"
#include "../services/fs.h"
#include "../sf/service.h"
......@@ -19,117 +20,6 @@ typedef struct {
Service s; ///< IContentMetaDatabase
} NcmContentMetaDatabase;
/// ContentType
typedef enum {
NcmContentType_Meta = 0, ///< Meta
NcmContentType_Program = 1, ///< Program
NcmContentType_Data = 2, ///< Data
NcmContentType_Control = 3, ///< Control
NcmContentType_HtmlDocument = 4, ///< HtmlDocument
NcmContentType_LegalInformation = 5, ///< LegalInformation
NcmContentType_DeltaFragment = 6, ///< DeltaFragment
} NcmContentType;
/// ContentMetaType
typedef enum {
NcmContentMetaType_Unknown = 0x0, ///< Unknown
NcmContentMetaType_SystemProgram = 0x1, ///< SystemProgram
NcmContentMetaType_SystemData = 0x2, ///< SystemData
NcmContentMetaType_SystemUpdate = 0x3, ///< SystemUpdate
NcmContentMetaType_BootImagePackage = 0x4, ///< BootImagePackage
NcmContentMetaType_BootImagePackageSafe = 0x5, ///< BootImagePackageSafe
NcmContentMetaType_Application = 0x80, ///< Application
NcmContentMetaType_Patch = 0x81, ///< Patch
NcmContentMetaType_AddOnContent = 0x82, ///< AddOnContent
NcmContentMetaType_Delta = 0x83, ///< Delta
} NcmContentMetaType;
/// ContentMetaAttribute
typedef enum {
NcmContentMetaAttribute_None = 0, ///< None
NcmContentMetaAttribute_IncludesExFatDriver = BIT(0), ///< IncludesExFatDriver
NcmContentMetaAttribute_Rebootless = BIT(1), ///< Rebootless
} NcmContentMetaAttribute;
/// ContentInstallType
typedef enum {
NcmContentInstallType_Full = 0, ///< Full
NcmContentInstallType_FragmentOnly = 1, ///< FragmentOnly
NcmContentInstallType_Unknown = 7, ///< Unknown
} NcmContentInstallType;
/// ContentId
typedef struct {
alignas(4) u8 c[0x10]; ///< Id
} NcmContentId;
/// PlaceHolderId
typedef struct {
alignas(8) u8 c[0x10]; ///< Id
} NcmPlaceHolderId;
/// ContentMetaKey
typedef struct {
u64 id; ///< Id.
u32 version; ///< Version.
u8 type; ///< \ref NcmContentMetaType
u8 install_type; ///< \ref NcmContentInstallType
u8 padding[2]; ///< Padding.
} NcmContentMetaKey;
/// ApplicationContentMetaKey
typedef struct {
NcmContentMetaKey key; ///< \ref NcmContentMetaKey
u64 application_id; ///< ApplicationId.
} NcmApplicationContentMetaKey;
/// ContentInfo
typedef struct {
NcmContentId content_id; ///< \ref NcmContentId
u8 size[0x6]; ///< Content size.
u8 content_type; ///< \ref NcmContentType.
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;
/// ContentMetaHeader
typedef struct {
u16 extended_header_size; ///< Size of optional struct that comes after this one.
u16 content_count; ///< Number of NcmContentInfos after the extra bytes.
u16 content_meta_count; ///< Number of NcmContentMetaInfos that come after the NcmContentInfos.
u8 attributes; ///< Usually None (0).
u8 storage_id; ///< Usually None (0).
} NcmContentMetaHeader;
/// ApplicationMetaExtendedHeader
typedef struct {
u64 patch_id; ///< PatchId of this application's patch.
u32 required_system_version; ///< Firmware version required by this application.
u32 required_application_version; ///< [9.0.0+] Owner application version required by this application. Previously padding.
} NcmApplicationMetaExtendedHeader;
/// PatchMetaExtendedHeader
typedef struct {
u64 application_id; ///< ApplicationId of this patch's corresponding application.
u32 required_system_version; ///< Firmware version required by this patch.
u32 extended_data_size; ///< Size of the extended data following the NcmContentInfos.
u8 reserved[0x8]; ///< Unused.
} NcmPatchMetaExtendedHeader;
/// AddOnContentMetaExtendedHeader
typedef struct {
u64 application_id; ///< ApplicationId of this add-on-content's corresponding application.
u32 required_application_version; ///< Version of the application required by this add-on-content.
u32 padding; ///< Padding.
} NcmAddOnContentMetaExtendedHeader;
/// SystemUpdateMetaExtendedHeader
typedef struct {
u32 extended_data_size; ///< Size of the extended data after NcmContentInfos and NcmContentMetaInfos.
} NcmSystemUpdateMetaExtendedHeader;
/// RightsId
typedef struct {
FsRightsId rights_id;
......@@ -137,13 +27,6 @@ typedef struct {
u8 pad[7]; ///< [3.0.0+]
} NcmRightsId;
/// ProgramLocation
typedef struct {
u64 program_id; ///< ProgramId
u8 storageID; ///< \ref FsStorageId
u8 pad[7];
} NcmProgramLocation;
/// Initialize ncm.
Result ncmInitialize(void);
......@@ -153,19 +36,19 @@ void ncmExit(void);
/// Gets the Service object for the actual ncm service session.
Service* ncmGetServiceSession(void);
Result ncmCreateContentStorage(FsStorageId storage_id);
Result ncmCreateContentMetaDatabase(FsStorageId storage_id);
Result ncmVerifyContentStorage(FsStorageId storage_id);
Result ncmVerifyContentMetaDatabase(FsStorageId storage_id);
Result ncmOpenContentStorage(NcmContentStorage* out_content_storage, FsStorageId storage_id);
Result ncmOpenContentMetaDatabase(NcmContentMetaDatabase* out_content_meta_database, FsStorageId storage_id);
Result ncmCloseContentStorageForcibly(FsStorageId storage_id); ///< [1.0.0]
Result ncmCloseContentMetaDatabaseForcibly(FsStorageId storage_id); ///< [1.0.0]
Result ncmCleanupContentMetaDatabase(FsStorageId storage_id);
Result ncmActivateContentStorage(FsStorageId storage_id); ///< [2.0.0+]
Result ncmInactivateContentStorage(FsStorageId storage_id); ///< [2.0.0+]
Result ncmActivateContentMetaDatabase(FsStorageId storage_id); ///< [2.0.0+]
Result ncmInactivateContentMetaDatabase(FsStorageId storage_id); ///< [2.0.0+]
Result ncmCreateContentStorage(NcmStorageId storage_id);
Result ncmCreateContentMetaDatabase(NcmStorageId storage_id);
Result ncmVerifyContentStorage(NcmStorageId storage_id);
Result ncmVerifyContentMetaDatabase(NcmStorageId storage_id);
Result ncmOpenContentStorage(NcmContentStorage* out_content_storage, NcmStorageId storage_id);
Result ncmOpenContentMetaDatabase(NcmContentMetaDatabase* out_content_meta_database, NcmStorageId storage_id);
Result ncmCloseContentStorageForcibly(NcmStorageId storage_id); ///< [1.0.0]
Result ncmCloseContentMetaDatabaseForcibly(NcmStorageId storage_id); ///< [1.0.0]
Result ncmCleanupContentMetaDatabase(NcmStorageId storage_id);
Result ncmActivateContentStorage(NcmStorageId storage_id); ///< [2.0.0+]
Result ncmInactivateContentStorage(NcmStorageId storage_id); ///< [2.0.0+]
Result ncmActivateContentMetaDatabase(NcmStorageId storage_id); ///< [2.0.0+]
Result ncmInactivateContentMetaDatabase(NcmStorageId storage_id); ///< [2.0.0+]
Result ncmInvalidateRightsIdCache(void); ///< [9.0.0+]
void ncmContentStorageClose(NcmContentStorage* cs);
......
/**
* @file ncm_types.h
* @brief Content Manager (ncm) service types (see ncm.h for the rest).
* @author Adubbz, zhuowei, and yellows8
* @copyright libnx Authors
*/
#pragma once
#include "../types.h"
/// StorageId
typedef enum {
NcmStorageId_None = 0, ///< None
NcmStorageId_Host = 1, ///< Host
NcmStorageId_GameCard = 2, ///< GameCard
NcmStorageId_BuiltInSystem = 3, ///< BuiltInSystem
NcmStorageId_BuiltInUser = 4, ///< BuiltInUser
NcmStorageId_SdCard = 5, ///< SdCard
NcmStorageId_Any = 6, ///< Any
} NcmStorageId;
/// ContentType
typedef enum {
NcmContentType_Meta = 0, ///< Meta
NcmContentType_Program = 1, ///< Program
NcmContentType_Data = 2, ///< Data
NcmContentType_Control = 3, ///< Control
NcmContentType_HtmlDocument = 4, ///< HtmlDocument
NcmContentType_LegalInformation = 5, ///< LegalInformation
NcmContentType_DeltaFragment = 6, ///< DeltaFragment
} NcmContentType;
/// ContentMetaType
typedef enum {
NcmContentMetaType_Unknown = 0x0, ///< Unknown
NcmContentMetaType_SystemProgram = 0x1, ///< SystemProgram
NcmContentMetaType_SystemData = 0x2, ///< SystemData
NcmContentMetaType_SystemUpdate = 0x3, ///< SystemUpdate
NcmContentMetaType_BootImagePackage = 0x4, ///< BootImagePackage
NcmContentMetaType_BootImagePackageSafe = 0x5, ///< BootImagePackageSafe
NcmContentMetaType_Application = 0x80, ///< Application
NcmContentMetaType_Patch = 0x81, ///< Patch
NcmContentMetaType_AddOnContent = 0x82, ///< AddOnContent
NcmContentMetaType_Delta = 0x83, ///< Delta
} NcmContentMetaType;
/// ContentMetaAttribute
typedef enum {
NcmContentMetaAttribute_None = 0, ///< None
NcmContentMetaAttribute_IncludesExFatDriver = BIT(0), ///< IncludesExFatDriver
NcmContentMetaAttribute_Rebootless = BIT(1), ///< Rebootless
} NcmContentMetaAttribute;
/// ContentInstallType
typedef enum {
NcmContentInstallType_Full = 0, ///< Full
NcmContentInstallType_FragmentOnly = 1, ///< FragmentOnly
NcmContentInstallType_Unknown = 7, ///< Unknown
} NcmContentInstallType;
/// ContentId
typedef struct {
alignas(4) u8 c[0x10]; ///< Id
} NcmContentId;
/// PlaceHolderId
typedef struct {
alignas(8) u8 c[0x10]; ///< Id
} NcmPlaceHolderId;
/// ContentMetaKey
typedef struct {
u64 id; ///< Id.
u32 version; ///< Version.
u8 type; ///< \ref NcmContentMetaType
u8 install_type; ///< \ref NcmContentInstallType
u8 padding[2]; ///< Padding.
} NcmContentMetaKey;
/// ApplicationContentMetaKey
typedef struct {
NcmContentMetaKey key; ///< \ref NcmContentMetaKey
u64 application_id; ///< ApplicationId.
} NcmApplicationContentMetaKey;
/// ContentInfo
typedef struct {
NcmContentId content_id; ///< \ref NcmContentId
u8 size[0x6]; ///< Content size.
u8 content_type; ///< \ref NcmContentType.
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;
/// ContentMetaHeader
typedef struct {
u16 extended_header_size; ///< Size of optional struct that comes after this one.
u16 content_count; ///< Number of NcmContentInfos after the extra bytes.
u16 content_meta_count; ///< Number of NcmContentMetaInfos that come after the NcmContentInfos.
u8 attributes; ///< Usually None (0).
u8 storage_id; ///< Usually None (0).
} NcmContentMetaHeader;
/// ApplicationMetaExtendedHeader
typedef struct {
u64 patch_id; ///< PatchId of this application's patch.
u32 required_system_version; ///< Firmware version required by this application.
u32 required_application_version; ///< [9.0.0+] Owner application version required by this application. Previously padding.
} NcmApplicationMetaExtendedHeader;
/// PatchMetaExtendedHeader
typedef struct {
u64 application_id; ///< ApplicationId of this patch's corresponding application.
u32 required_system_version; ///< Firmware version required by this patch.
u32 extended_data_size; ///< Size of the extended data following the NcmContentInfos.
u8 reserved[0x8]; ///< Unused.
} NcmPatchMetaExtendedHeader;
/// AddOnContentMetaExtendedHeader
typedef struct {
u64 application_id; ///< ApplicationId of this add-on-content's corresponding application.
u32 required_application_version; ///< Version of the application required by this add-on-content.
u32 padding; ///< Padding.
} NcmAddOnContentMetaExtendedHeader;
/// SystemUpdateMetaExtendedHeader
typedef struct {
u32 extended_data_size; ///< Size of the extended data after NcmContentInfos and NcmContentMetaInfos.
} NcmSystemUpdateMetaExtendedHeader;
/// ProgramLocation
typedef struct {
u64 program_id; ///< ProgramId
u8 storageID; ///< \ref NcmStorageId
u8 pad[7]; ///< Padding
} NcmProgramLocation;
......@@ -8,21 +8,18 @@
#pragma once
#include "../types.h"
#include "../sf/service.h"
#include "../services/hid.h"
/// NfpServiceType
typedef enum {
NfpServiceType_NotInitialized = 0, ///< Same as ::NfpServiceType_User during \ref nfpInitialize.
NfpServiceType_User = 1, ///< Initializes nfp:user.
NfpServiceType_Debug = 2, ///< Initializes nfp:dbg.
NfpServiceType_System = 3, ///< Initializes nfp:sys.
NfpServiceType_User = 0, ///< Initializes nfp:user.
NfpServiceType_Debug = 1, ///< Initializes nfp:dbg.
NfpServiceType_System = 2, ///< Initializes nfp:sys.
} NfpServiceType;
/// NfcServiceType
typedef enum {
NfcServiceType_NotInitialized = 0, ///< Same as ::NfcServiceType_User during \ref nfcInitialize.
NfcServiceType_User = 1, ///< Initializes nfc:user.
NfcServiceType_System = 3, ///< Initializes nfc:sys.
NfcServiceType_User = 0, ///< Initializes nfc:user.
NfcServiceType_System = 1, ///< Initializes nfc:sys.
} NfcServiceType;
typedef enum {
......@@ -147,26 +144,14 @@ typedef struct {
u8 handle[0x8]; ///< Handle.
} NfcDeviceHandle;
/**
* @brief Sets the \ref NfpServiceType for initialization. Call this function before \ref nfpInitialize, if needed.
* @note By default ::NfpServiceType_NotInitialized will be used.
*/
void nfpSetServiceType(NfpServiceType serviceType);
/**
* @brief Sets the \ref NfcServiceType for initialization. Call this function before \ref nfcInitialize, if needed.
* @note By default ::NfcServiceType_NotInitialized will be used.
*/
void nfcSetServiceType(NfcServiceType serviceType);
/// Initialize nfp:*.
Result nfpInitialize(void);
Result nfpInitialize(NfpServiceType service_type);
/// Exit nfp:*.
void nfpExit(void);
/// Initialize nfc:*.
Result nfcInitialize(void);
Result nfcInitialize(NfcServiceType service_type);
/// Exit nfc:*.
void nfcExit(void);
......
......@@ -10,10 +10,9 @@
#include "../sf/service.h"
typedef enum {
NifmServiceType_NotInitialized = 0, ///< Initializes nifm:u.
NifmServiceType_User = 1, ///< Initializes nifm:u.
NifmServiceType_System = 2, ///< Initializes nifm:s.
NifmServiceType_Admin = 3, ///< Initializes nifm:a.
NifmServiceType_User = 0, ///< Initializes nifm:u.
NifmServiceType_System = 1, ///< Initializes nifm:s.
NifmServiceType_Admin = 2, ///< Initializes nifm:a.
} NifmServiceType;
typedef enum {
......@@ -29,16 +28,10 @@ typedef enum {
NifmInternetConnectionStatus_Connected = 4, ///< Internet is connected.
} NifmInternetConnectionStatus;
/**
* @brief Sets the \ref NifmServiceType for initialization. Call this function before \ref nifmInitialize.
* @note By default nifm:u will be used.
*/
void nifmSetServiceType(NifmServiceType serviceType);
/// Initialize nifm. This is used automatically by \ref socketInitialize.
Result nifmInitialize(void);
/// Initialize nifm. This is used automatically by gethostid().
Result nifmInitialize(NifmServiceType service_type);
/// Exit nifm. This is used automatically by \ref socketExit.
/// Exit nifm. This is used automatically by gethostid().
void nifmExit(void);
/// Gets the Service object for the actual nifm:* service session.
......
/**
* @file notif.h
* @brief Alarm notification (notif:*) service IPC wrapper.
* @author yellows8
* @copyright libnx Authors
*/
#pragma once
#include "../types.h"
#include "../kernel/event.h"
#include "../services/applet.h"
#include "../services/acc.h"
#include "../sf/service.h"
/// ServiceType for \ref notifInitialize.
typedef enum {
NotifServiceType_Application = 0, ///< Initializes notif:a, for Application.
NotifServiceType_System = 1, ///< Initializes notif:s, for System.
} NotifServiceType;
/// Data extracted from NotifWeeklyScheduleAlarmSetting::settings. This uses local-time.
typedef struct {
s32 hour; ///< Hour.
s32 minute; ///< Minute.
} NotifAlarmTime;
/// WeeklyScheduleAlarmSetting
typedef struct {
u8 unk_x0[0xa]; ///< Unknown.
s16 settings[7]; ///< Schedule settings for each day of the week, Sun-Sat. High byte is the hour, low byte is the minute. This uses local-time.
} NotifWeeklyScheduleAlarmSetting;
/// AlarmSetting
typedef struct {
u16 alarm_setting_id; ///< AlarmSettingId
u8 kind; ///< Kind: 0 = WeeklySchedule.
u8 muted; ///< u8 bool flag for whether this AlarmSetting is muted (non-zero = AlarmSetting turned off, zero = on).
u8 pad[4]; ///< Padding.
AccountUid uid; ///< \ref AccountUid. User account associated with this AlarmSetting. Used for the preselected_user (\ref accountGetPreselectedUser) when launching the Application when the system was previously in sleep-mode, instead of launching the applet for selecting the user.
u64 application_id; ///< ApplicationId
u64 unk_x20; ///< Unknown.
NotifWeeklyScheduleAlarmSetting schedule; ///< \ref NotifWeeklyScheduleAlarmSetting
} NotifAlarmSetting;
/// Maximum alarms that can be registered at the same time by the host Application.
#define NOTIF_MAX_ALARMS 8
/// Initialize notif. Only available on [9.0.0+]. Note that using Alarms also requires the [9.0.0+] firmware update for controllers to be installed.
Result notifInitialize(NotifServiceType service_type);
/// Exit notif.
void notifExit(void);
/// Gets the Service object for the actual notif:* service session.
Service* notifGetServiceSession(void);
/**
* @brief Creates a \ref NotifAlarmSetting.
* @note This clears the struct, with all schedule settings set the same as \ref notifAlarmSettingDisable.
* @param[out] alarm_setting \ref NotifAlarmSetting
*/
void notifAlarmSettingCreate(NotifAlarmSetting *alarm_setting);
/**
* @brief Sets whether the \ref NotifAlarmSetting is muted.
* @note By default (\ref notifAlarmSettingCreate) this is false.
* @param alarm_setting \ref NotifAlarmSetting
* @param[in] flag Whether the alarm is muted (true = Alarm turned off, false = on).
*/
NX_INLINE void notifAlarmSettingSetIsMuted(NotifAlarmSetting *alarm_setting, bool flag) {
alarm_setting->muted = flag!=0;
}
/**
* @brief Sets the \ref AccountUid for the \ref NotifAlarmSetting, see NotifAlarmSetting::uid.
* @param alarm_setting \ref NotifAlarmSetting
* @param[in] uid \ref AccountUid. If want to clear the uid after it was previously set, you can use an all-zero uid to reset to the default (\ref notifAlarmSettingCreate).
*/
NX_INLINE void notifAlarmSettingSetUid(NotifAlarmSetting *alarm_setting, AccountUid uid) {
alarm_setting->uid = uid;
}
/**
* @brief Gets whether the schedule setting for the specified day_of_week is enabled, for the \ref NotifAlarmSetting.
* @param alarm_setting \ref NotifAlarmSetting
* @param[in] day_of_week Day-of-week, must be 0-6 (Sun-Sat).
* @param[out] out Whether the setting is enabled.
*/
Result notifAlarmSettingIsEnabled(NotifAlarmSetting *alarm_setting, u32 day_of_week, bool *out);
/**
* @brief Gets the schedule setting for the specified day_of_week, for the \ref NotifAlarmSetting.
* @note Should not be used if the output from \ref notifAlarmSettingIsEnabled is false.
* @param alarm_setting \ref NotifAlarmSetting
* @param[in] day_of_week Day-of-week, must be 0-6 (Sun-Sat).
* @param[out] out \ref NotifAlarmTime
*/
Result notifAlarmSettingGet(NotifAlarmSetting *alarm_setting, u32 day_of_week, NotifAlarmTime *out);
/**
* @brief Enables the schedule setting for the specified day_of_week, for the \ref NotifAlarmSetting. This uses local-time.
* @param alarm_setting \ref NotifAlarmSetting
* @param[in] day_of_week Day-of-week, must be 0-6 (Sun-Sat).
* @param[in] hour Hour.
* @param[in] minute Minute.
*/
Result notifAlarmSettingEnable(NotifAlarmSetting *alarm_setting, u32 day_of_week, s32 hour, s32 minute);
/**
* @brief Disables the schedule setting for the specified day_of_week, for the \ref NotifAlarmSetting.
* @note Schedule settings are disabled by default (\ref notifAlarmSettingCreate).
* @param alarm_setting \ref NotifAlarmSetting
* @param[in] day_of_week Day-of-week, must be 0-6 (Sun-Sat).
*/
Result notifAlarmSettingDisable(NotifAlarmSetting *alarm_setting, u32 day_of_week);
/**
* @brief Registers the specified AlarmSetting.
* @note See \ref NOTIF_MAX_ALARMS for the maximum alarms.
* @param[out] alarm_setting_id AlarmSettingId
* @param[in] alarm_setting \ref NotifAlarmSetting
* @param[in] buffer Input buffer containing the ApplicationParameter. Optional, can be NULL.
* @param[in] size Input buffer size, must be <=0x400. Optional, can be 0.
*/
Result notifRegisterAlarmSetting(u16 *alarm_setting_id, const NotifAlarmSetting *alarm_setting, const void* buffer, size_t size);
/**
* @brief Updates the specified AlarmSetting.
* @param[in] alarm_setting \ref NotifAlarmSetting
* @param[in] buffer Input buffer containing the ApplicationParameter. Optional, can be NULL.
* @param[in] size Input buffer size, must be <=0x400. Optional, can be 0.
*/
Result notifUpdateAlarmSetting(const NotifAlarmSetting *alarm_setting, const void* buffer, size_t size);
/**
* @brief Gets a listing of AlarmSettings.
* @param[out] alarm_settings Output \ref NotifAlarmSetting array.
* @param[in] count Total entries in the alarm_settings array.
* @param[out] total_out Total output entries.
*/
Result notifListAlarmSettings(NotifAlarmSetting *alarm_settings, s32 count, s32 *total_out);
/**
* @brief Loads the ApplicationParameter for the specified AlarmSetting.
* @param[in] alarm_setting_id AlarmSettingId
* @param[out] buffer Output buffer containing the ApplicationParameter.
* @param[in] size Output buffer size.
* @param[out] actual_size Actual output size.
*/
Result notifLoadApplicationParameter(u16 alarm_setting_id, void* buffer, size_t size, u32 *actual_size);
/**
* @brief Deletes the specified AlarmSetting.
* @param[in] alarm_setting_id AlarmSettingId
*/
Result notifDeleteAlarmSetting(u16 alarm_setting_id);
/**
* @brief Gets an Event which is signaled when data is available with \ref notifTryPopNotifiedApplicationParameter.
* @note This is a wrapper for \ref appletGetNotificationStorageChannelEvent, see that for the usage requirements.
* @note Some official apps don't use this.
* @note The Event must be closed by the user once finished with it.
* @param[out] out_event Output Event with autoclear=false.
*/
NX_INLINE Result notifGetNotificationSystemEvent(Event *out_event) {
return appletGetNotificationStorageChannelEvent(out_event);
}
/**
* @brief Uses \ref appletTryPopFromNotificationStorageChannel then reads the data from there into the output params.
* @note This is a wrapper for \ref appletTryPopFromNotificationStorageChannel, see that for the usage requirements.
* @note The system will only push data for this when launching the Application when the Alarm was triggered, where the system was previously in sleep-mode.
* @note Some official apps don't use this.
* @param[out] buffer Output buffer.
* @param[out] size Output buffer size.
* @param[out] out_size Size of the data which was written into the output buffer. Optional, can be NULL.
*/
Result notifTryPopNotifiedApplicationParameter(void* buffer, u64 size, u64 *out_size);
......@@ -8,8 +8,7 @@
#include "../types.h"
#include "../nacp.h"
#include "../sf/service.h"
#include "../services/fs.h"
#include "../services/ncm.h"
#include "../services/ncm_types.h"
#include "../services/async.h"
#include "../kernel/event.h"
#include "../kernel/tmem.h"
......@@ -59,7 +58,7 @@ typedef struct {
/// NsApplicationContentMetaStatus
typedef struct {
u8 meta_type; ///< \ref NcmContentMetaType
u8 storageID; ///< \ref FsStorageId
u8 storageID; ///< \ref NcmStorageId
u8 unk_x02; ///< Unknown.
u8 padding; ///< Padding.
u32 version; ///< Application version.
......@@ -80,7 +79,7 @@ typedef struct {
typedef struct {
u64 program_id; ///< program_id.
u32 version; ///< Program version.
u8 storageID; ///< \ref FsStorageId
u8 storageID; ///< \ref NcmStorageId
u8 index; ///< Index.
u8 is_application; ///< Whether this is an Application.
} NsLaunchProperties;
......@@ -186,17 +185,17 @@ Result nsGetApplicationControlData(NsApplicationControlSource source, u64 applic
/**
* @brief Returns the total storage capacity (used + free) from content manager services.
* @param[in] storage_id Specified FsStorageId. (Must be FsStorageId_SdCard)
* @param[in] storage_id \ref NcmStorageId. Must be ::NcmStorageId_SdCard.
* @param[out] size Pointer to output the total storage size to.
*/
Result nsGetTotalSpaceSize(FsStorageId storage_id, u64 *size);
Result nsGetTotalSpaceSize(NcmStorageId storage_id, u64 *size);
/**
* @brief Returns the available storage capacity from content manager services.
* @param[in] storage_id Specified FsStorageId. (Must be FsStorageId_SdCard)
* @param[in] storage_id \ref NcmStorageId. Must be ::NcmStorageId_SdCard.
* @param[out] size Pointer to output the free storage size to.
*/
Result nsGetFreeSpaceSize(FsStorageId storage_id, u64 *size);
Result nsGetFreeSpaceSize(NcmStorageId storage_id, u64 *size);
/**
* @brief Generates a \ref NsSystemDeliveryInfo using the currently installed SystemUpdate meta.
......@@ -300,7 +299,7 @@ Result nsEstimateRequiredSize(const NcmContentMetaKey *meta, s32 count, s64 *out
/**
* @brief RequestReceiveApplication
* @note The system will use the input addr/port with connect(). addr/port are little-endian.
* @note This is the Application version of \ref nssuControlRequestReceiveSystemUpdate, see the notes for that.
* @note Only available on [4.0.0+].
* @param[out] a \ref AsyncResult
* @param[in] addr Server IPv4 address.
......@@ -308,9 +307,9 @@ Result nsEstimateRequiredSize(const NcmContentMetaKey *meta, s32 count, s64 *out
* @param[in] application_id ApplicationId
* @param[in] meta Input array of \ref NcmContentMetaKey. The ::NcmContentMetaType must match ::NcmContentMetaType_Patch.
* @param[in] count Size of the meta array in entries.
* @param[in] storage_id ::FsStorageId. qlaunch uses value 6.
* @param[in] storage_id \ref NcmStorageId. qlaunch uses ::NcmStorageId_Any.
*/
Result nsRequestReceiveApplication(AsyncResult *a, u32 addr, u16 port, u64 application_id, const NcmContentMetaKey *meta, s32 count, FsStorageId storage_id);
Result nsRequestReceiveApplication(AsyncResult *a, u32 addr, u16 port, u64 application_id, const NcmContentMetaKey *meta, s32 count, NcmStorageId storage_id);
/**
* @brief CommitReceiveApplication
......@@ -329,8 +328,7 @@ Result nsGetReceiveApplicationProgress(u64 application_id, NsReceiveApplicationP
/**
* @brief RequestSendApplication
* @note The system will use the input addr/port with bind(), the input addr will eventually be validated with the addr from accept(). addr/port are little-endian.
* @note After the system accepts a connection etc, an error will be thrown if the system is Internet-connected.
* @note This is the Application version of \ref nssuRequestSendSystemUpdate, see the notes for that.
* @note Only available on [4.0.0+].
* @param[out] a \ref AsyncResult
* @param[in] addr Client IPv4 address.
......@@ -715,6 +713,7 @@ Result nssuControlGetReceivedEulaData(NsSystemUpdateControl *c, const char* path
/**
* @brief Does setup for ReceiveSystemUpdate by using the same nim cmds as \ref nssuDestroySystemUpdateTask.
* @note qlaunch uses this before \ref nssuControlRequestReceiveSystemUpdate.
* @note Only available on [4.0.0+].
* @param c \ref NsSystemUpdateControl
*/
......
......@@ -98,7 +98,7 @@ typedef struct {
} unk_x8;
u8 appletId; ///< \ref AppletId
u8 storageId; ///< See FsStorageId.
u8 storageId; ///< \ref NcmStorageId
u8 logPolicy; ///< \ref PdmPlayLogPolicy
u8 eventType; ///< \ref PdmAppletEventType
u8 unused[0xc]; ///< Unused.
......
......@@ -10,7 +10,7 @@
#include "../types.h"
#include "../kernel/event.h"
#include "../sf/service.h"
#include "../services/ncm.h"
#include "../services/ncm_types.h"
/// LaunchFlag
typedef enum {
......
......@@ -211,6 +211,18 @@ Result setsysGetQuestFlag(bool *out);
*/
Result setsysSetQuestFlag(bool flag);
/**
* @brief IsUserSystemClockAutomaticCorrectionEnabled
* @param[out] out Output flag.
*/
Result setsysIsUserSystemClockAutomaticCorrectionEnabled(bool *out);
/**
* @brief SetUserSystemClockAutomaticCorrectionEnabled
* @param[in] flag Input flag.
*/
Result setsysSetUserSystemClockAutomaticCorrectionEnabled(bool flag);
/**
* @brief GetUsb30EnableFlag
* @param[out] out Output flag.
......@@ -439,6 +451,7 @@ Result setsysGetHomeMenuScheme(SetSysHomeMenuScheme *out);
/**
* @brief Gets the \ref SetSysPlatformRegion.
* @note This is used internally by \ref appletGetSettingsPlatformRegion.
* @note Only available on [9.0.0+].
* @param[out] out \ref SetSysPlatformRegion
*/
......
......@@ -142,6 +142,20 @@ NX_INLINE void serviceCreate(Service* s, Handle h)
cmifQueryPointerBufferSize(h, &s->pointer_buffer_size);
}
/**
* @brief Creates a non-domain subservice object from a parent service.
* @param[out] s Service object.
* @param[in] parent Parent service.
* @param[in] h IPC session handle for this subservice.
*/
NX_INLINE void serviceCreateNonDomainSubservice(Service* s, Service* parent, Handle h)
{
s->session = h;
s->own_handle = 1;
s->object_id = 0;
s->pointer_buffer_size = parent->pointer_buffer_size;
}
/**
* @brief Creates a domain subservice object from a parent service.
* @param[out] s Service object.
......@@ -397,7 +411,7 @@ NX_INLINE Result serviceParseResponse(
if (is_domain)
serviceCreateDomainSubservice(&out_objects[i], s, cmifResponseGetObject(&res));
else // Output objects are marshalled as move handles at the beginning of the list.
serviceCreate(&out_objects[i], cmifResponseGetMoveHandle(&res));
serviceCreateNonDomainSubservice(&out_objects[i], s, cmifResponseGetMoveHandle(&res));
}
_serviceResponseGetHandle(&res, out_handle_attrs.attr0, &out_handles[0]);
......
#include <string.h>
#include "types.h"
#include "result.h"
#include "services/acc.h"
#include "services/applet.h"
#include "applets/libapplet.h"
#include "applets/friends_la.h"
#include "runtime/hosversion.h"
static Result _friendsLaShow(const FriendsLaArg *arg, bool playStartupSound) {
Result rc=0;
Result rc2=0;
size_t readsize=0;
u32 version=0x1;
const void* arg_ptr = arg;
size_t arg_size = sizeof(*arg);
LibAppletArgs commonargs;
FriendsLaArgV1 argv1;
libappletArgsCreate(&commonargs, 0x1);
if (hosversionAtLeast(9,0,0))
version = 0x10000;
else {
memset(&argv1, 0, sizeof(argv1));
arg_ptr = &argv1;
arg_size = sizeof(argv1);
memcpy(&argv1.hdr, &arg->hdr, sizeof(FriendsLaArgHeader));
memcpy(&argv1.data, &arg->data.common, sizeof(FriendsLaArgCommonData));
}
libappletArgsCreate(&commonargs, version);
libappletArgsSetPlayStartupSound(&commonargs, playStartupSound);
if (arg->type != FriendsLaArgType_StartSendingFriendRequest)
rc = libappletLaunch(AppletId_myPage, &commonargs, arg, sizeof(*arg), NULL, 0, NULL);
if (arg->hdr.type != FriendsLaArgType_StartSendingFriendRequest && arg->hdr.type != FriendsLaArgType_StartFriendInvitation && arg->hdr.type != FriendsLaArgType_StartSendingFriendInvitation)
rc = libappletLaunch(AppletId_myPage, &commonargs, arg_ptr, arg_size, NULL, 0, NULL);
else {
rc = libappletLaunch(AppletId_myPage, &commonargs, arg, sizeof(*arg), &rc2, sizeof(rc2), &readsize);
rc = libappletLaunch(AppletId_myPage, &commonargs, arg_ptr, arg_size, &rc2, sizeof(rc2), &readsize);
if (R_SUCCEEDED(rc) && readsize!=sizeof(rc2)) rc = MAKERESULT(Module_Libnx, LibnxError_BadInput);
if (R_SUCCEEDED(rc)) rc = rc2;
}
......@@ -27,13 +42,13 @@ static Result _friendsLaShow(const FriendsLaArg *arg, bool playStartupSound) {
}
static Result _friendsLaShowSimple(FriendsLaArgType type, AccountUid uid, bool playStartupSound) {
FriendsLaArg arg = {.type = type, .uid = uid};
FriendsLaArg arg = {.hdr.type = type, .hdr.uid = uid};
return _friendsLaShow(&arg, playStartupSound);
}
static Result _friendsLaShowAll(FriendsLaArgType type, AccountUid uid, u64 networkServiceAccountId, const FriendsInAppScreenName *first_inAppScreenName, const FriendsInAppScreenName *second_inAppScreenName, bool playStartupSound) {
FriendsLaArg arg = {.type = type, .uid = uid, .networkServiceAccountId = networkServiceAccountId, .first_inAppScreenName = *first_inAppScreenName, .second_inAppScreenName = *second_inAppScreenName};
static Result _friendsLaShowAll(FriendsLaArgType type, AccountUid uid, AccountNetworkServiceAccountId id, const FriendsInAppScreenName *first_inAppScreenName, const FriendsInAppScreenName *second_inAppScreenName, bool playStartupSound) {
FriendsLaArg arg = {.hdr.type = type, .hdr.uid = uid, .data.common.id = id, .data.common.first_inAppScreenName = *first_inAppScreenName, .data.common.second_inAppScreenName = *second_inAppScreenName};
return _friendsLaShow(&arg, playStartupSound);
}
......@@ -42,12 +57,12 @@ Result friendsLaShowFriendList(AccountUid uid) {
return _friendsLaShowSimple(FriendsLaArgType_ShowFriendList, uid, false);
}
Result friendsLaShowUserDetailInfo(AccountUid uid, u64 networkServiceAccountId, const FriendsInAppScreenName *first_inAppScreenName, const FriendsInAppScreenName *second_inAppScreenName) {
return _friendsLaShowAll(FriendsLaArgType_ShowUserDetailInfo, uid, networkServiceAccountId, first_inAppScreenName, second_inAppScreenName, false);
Result friendsLaShowUserDetailInfo(AccountUid uid, AccountNetworkServiceAccountId id, const FriendsInAppScreenName *first_inAppScreenName, const FriendsInAppScreenName *second_inAppScreenName) {
return _friendsLaShowAll(FriendsLaArgType_ShowUserDetailInfo, uid, id, first_inAppScreenName, second_inAppScreenName, false);
}
Result friendsLaStartSendingFriendRequest(AccountUid uid, u64 networkServiceAccountId, const FriendsInAppScreenName *first_inAppScreenName, const FriendsInAppScreenName *second_inAppScreenName) {
return _friendsLaShowAll(FriendsLaArgType_StartSendingFriendRequest, uid, networkServiceAccountId, first_inAppScreenName, second_inAppScreenName, false);
Result friendsLaStartSendingFriendRequest(AccountUid uid, AccountNetworkServiceAccountId id, const FriendsInAppScreenName *first_inAppScreenName, const FriendsInAppScreenName *second_inAppScreenName) {
return _friendsLaShowAll(FriendsLaArgType_StartSendingFriendRequest, uid, id, first_inAppScreenName, second_inAppScreenName, false);
}
Result friendsLaShowMethodsOfSendingFriendRequest(AccountUid uid) {
......@@ -74,3 +89,60 @@ Result friendsLaShowMyProfileForHomeMenu(AccountUid uid) {
return _friendsLaShowSimple(FriendsLaArgType_ShowMyProfile, uid, true);
}
Result friendsLaStartFriendInvitation(AccountUid uid, s32 id_count, const FriendsFriendInvitationGameModeDescription *desc, const void* userdata, u64 userdata_size) {
if (hosversionBefore(9,0,0))
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
FriendsLaArg arg;
memset(&arg, 0, sizeof(arg));
if (id_count<1 || id_count>15 || userdata_size>=sizeof(arg.data.start_friend_invitation.userdata) || (userdata==NULL && userdata_size!=0))
return MAKERESULT(Module_Libnx, LibnxError_BadInput);
arg.hdr.type = FriendsLaArgType_StartFriendInvitation;
arg.hdr.uid = uid;
arg.data.start_friend_invitation.id_count = id_count;
arg.data.start_friend_invitation.userdata_size = userdata_size;
if (userdata && userdata_size) memcpy(arg.data.start_friend_invitation.userdata, userdata, userdata_size);
memcpy(&arg.data.start_friend_invitation.desc, desc, sizeof(*desc));
return _friendsLaShow(&arg, false);
}
Result friendsLaStartSendingFriendInvitation(AccountUid uid, const AccountNetworkServiceAccountId *id_list, s32 id_count, const FriendsFriendInvitationGameModeDescription *desc, const void* userdata, u64 userdata_size) {
if (hosversionBefore(9,0,0))
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
FriendsLaArg arg;
memset(&arg, 0, sizeof(arg));
if (id_count<1 || id_count>15 || userdata_size>=sizeof(arg.data.start_sending_friend_invitation.userdata) || (userdata==NULL && userdata_size!=0))
return MAKERESULT(Module_Libnx, LibnxError_BadInput);
arg.hdr.type = FriendsLaArgType_StartSendingFriendInvitation;
arg.hdr.uid = uid;
arg.data.start_sending_friend_invitation.id_count = id_count;
arg.data.start_sending_friend_invitation.userdata_size = userdata_size;
memcpy(arg.data.start_sending_friend_invitation.id_list, id_list, id_count*sizeof(AccountNetworkServiceAccountId));
if (userdata && userdata_size) memcpy(arg.data.start_sending_friend_invitation.userdata, userdata, userdata_size);
memcpy(&arg.data.start_sending_friend_invitation.desc, desc, sizeof(*desc));
return _friendsLaShow(&arg, false);
}
Result friendsLaShowReceivedInvitationDetail(AccountUid uid, FriendsFriendInvitationId invitation_id, FriendsFriendInvitationGroupId invitation_group_id) {
if (hosversionBefore(9,0,0))
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
FriendsLaArg arg;
memset(&arg, 0, sizeof(arg));
arg.hdr.type = FriendsLaArgType_ShowReceivedInvitationDetail;
arg.hdr.uid = uid;
arg.data.show_received_invitation_detail.invitation_id = invitation_id;
arg.data.show_received_invitation_detail.invitation_group_id = invitation_group_id;
return _friendsLaShow(&arg, false);
}
......@@ -2,7 +2,6 @@
#include <malloc.h>
#include "types.h"
#include "result.h"
#include "services/caps.h"
#include "services/applet.h"
#include "applets/libapplet.h"
#include "applets/web.h"
......
......@@ -12,7 +12,6 @@
#include "runtime/devices/fs_dev.h"
#include "runtime/util/utf.h"
#include "runtime/env.h"
#include "services/fs.h"
#include "services/time.h"
#include "path_buf.h"
......@@ -443,10 +442,10 @@ Result fsdevMountSdmc(void)
return rc;
}
Result fsdevMountSaveData(const char *name, u64 program_id, AccountUid uid)
Result fsdevMountSaveData(const char *name, u64 application_id, AccountUid uid)
{
FsFileSystem fs;
Result rc = fsOpen_SaveData(&fs, program_id, uid);
Result rc = fsOpen_SaveData(&fs, application_id, uid);
if(R_SUCCEEDED(rc))
{
int ret = fsdevMountDevice(name, fs);
......@@ -456,10 +455,10 @@ Result fsdevMountSaveData(const char *name, u64 program_id, AccountUid uid)
return rc;
}
Result fsdevMountSystemSaveData(const char *name, FsSaveDataSpaceId saveDataSpaceId, u64 saveID, AccountUid uid)
Result fsdevMountSystemSaveData(const char *name, FsSaveDataSpaceId save_data_space_id, u64 system_save_data_id, AccountUid uid)
{
FsFileSystem fs;
Result rc = fsOpen_SystemSaveData(&fs, saveDataSpaceId, saveID, uid);
Result rc = fsOpen_SystemSaveData(&fs, save_data_space_id, system_save_data_id, uid);
if(R_SUCCEEDED(rc))
{
int ret = fsdevMountDevice(name, fs);
......
......@@ -11,7 +11,6 @@
#include "runtime/devices/romfs_dev.h"
#include "runtime/devices/fs_dev.h"
#include "runtime/util/utf.h"
#include "services/fs.h"
#include "runtime/env.h"
#include "nro.h"
......@@ -43,12 +42,26 @@ extern int __system_argc;
extern char** __system_argv;
#define romFS_root(m) ((romfs_dir*)(m)->dirTable)
#define romFS_dir(m,x) ((romfs_dir*) ((u8*)(m)->dirTable + (x)))
#define romFS_file(m,x) ((romfs_file*)((u8*)(m)->fileTable + (x)))
#define romFS_none ((u32)~0)
#define romFS_dir_mode (S_IFDIR | S_IRUSR | S_IRGRP | S_IROTH)
#define romFS_file_mode (S_IFREG | S_IRUSR | S_IRGRP | S_IROTH)
static romfs_dir *romFS_dir(romfs_mount *mount, u32 off)
{
if (off + sizeof(romfs_dir) > mount->header.dirTableSize) return NULL;
romfs_dir* curDir = ((romfs_dir*) ((u8*)mount->dirTable + off));
if (off + sizeof(romfs_dir) + curDir->nameLen > mount->header.dirTableSize) return NULL;
return curDir;
}
static romfs_file *romFS_file(romfs_mount *mount, u32 off)
{
if (off + sizeof(romfs_file) > mount->header.fileTableSize) return NULL;
romfs_file* curFile = ((romfs_file*) ((u8*)mount->fileTable + off));
if (off + sizeof(romfs_file) + curFile->nameLen > mount->header.fileTableSize) return NULL;
return curFile;
}
static ssize_t _romfs_read(romfs_mount *mount, u64 offset, void* buffer, u64 size)
{
u64 pos = mount->offset + offset;
......@@ -312,7 +325,7 @@ Result romfsMountFromFsdev(const char *path, u64 offset, const char *name)
return romfsMountCommon(name, mount);
}
Result romfsMountFromDataArchive(u64 dataId, FsStorageId storageId, const char *name) {
Result romfsMountFromDataArchive(u64 dataId, NcmStorageId storageId, const char *name) {
FsStorage storage;
Result rc = fsOpenDataStorageByDataId(&storage, dataId, storageId);
......@@ -413,38 +426,44 @@ static u32 calcHash(u32 parent, const uint8_t* name, u32 namelen, u32 total)
return hash % total;
}
static romfs_dir* searchForDir(romfs_mount *mount, romfs_dir* parent, const uint8_t* name, u32 namelen)
static int searchForDir(romfs_mount *mount, romfs_dir* parent, const uint8_t* name, u32 namelen, romfs_dir** out)
{
u64 parentOff = (uintptr_t)parent - (uintptr_t)mount->dirTable;
u32 hash = calcHash(parentOff, name, namelen, mount->header.dirHashTableSize/4);
romfs_dir* curDir = NULL;
u32 curOff;
*out = NULL;
for (curOff = mount->dirHashTable[hash]; curOff != romFS_none; curOff = curDir->nextHash)
{
curDir = romFS_dir(mount, curOff);
if (curDir == NULL) return EFAULT;
if (curDir->parent != parentOff) continue;
if (curDir->nameLen != namelen) continue;
if (memcmp(curDir->name, name, namelen) != 0) continue;
return curDir;
*out = curDir;
return 0;
}
return NULL;
return ENOENT;
}
static romfs_file* searchForFile(romfs_mount *mount, romfs_dir* parent, const uint8_t* name, u32 namelen)
static int searchForFile(romfs_mount *mount, romfs_dir* parent, const uint8_t* name, u32 namelen, romfs_file** out)
{
u64 parentOff = (uintptr_t)parent - (uintptr_t)mount->dirTable;
u32 hash = calcHash(parentOff, name, namelen, mount->header.fileHashTableSize/4);
romfs_file* curFile = NULL;
u32 curOff;
*out = NULL;
for (curOff = mount->fileHashTable[hash]; curOff != romFS_none; curOff = curFile->nextHash)
{
curFile = romFS_file(mount, curOff);
if (curFile == NULL) return EFAULT;
if (curFile->parent != parentOff) continue;
if (curFile->nameLen != namelen) continue;
if (memcmp(curFile->name, name, namelen) != 0) continue;
return curFile;
*out = curFile;
return 0;
}
return NULL;
return ENOENT;
}
static int navigateToDir(romfs_mount *mount, romfs_dir** ppDir, const char** pPath, bool isDir)
......@@ -490,13 +509,15 @@ static int navigateToDir(romfs_mount *mount, romfs_dir** ppDir, const char** pPa
if (component[1]=='.' && !component[2])
{
*ppDir = romFS_dir(mount, (*ppDir)->parent);
if (!*ppDir)
return EFAULT;
continue;
}
}
*ppDir = searchForDir(mount, *ppDir, (uint8_t*)component, strlen(component));
if (!*ppDir)
return EEXIST;
int ret = searchForDir(mount, *ppDir, (uint8_t*)component, strlen(component), ppDir);
if (ret !=0)
return ret;
}
if (!isDir && !**pPath)
......@@ -523,6 +544,7 @@ static nlink_t dir_nlink(romfs_mount *mount, romfs_dir *dir)
while(offset != romFS_none)
{
romfs_dir *tmp = romFS_dir(mount, offset);
if (!tmp) break;
++count;
offset = tmp->sibling;
}
......@@ -531,6 +553,7 @@ static nlink_t dir_nlink(romfs_mount *mount, romfs_dir *dir)
while(offset != romFS_none)
{
romfs_file *tmp = romFS_file(mount, offset);
if (!tmp) break;
++count;
offset = tmp->sibling;
}
......@@ -562,13 +585,14 @@ int romfs_open(struct _reent *r, void *fileStruct, const char *path, int flags,
if (r->_errno != 0)
return -1;
romfs_file* file = searchForFile(fileobj->mount, curDir, (uint8_t*)path, strlen(path));
if (!file)
romfs_file* file = NULL;
int ret = searchForFile(fileobj->mount, curDir, (uint8_t*)path, strlen(path), &file);
if (ret != 0)
{
if(flags & O_CREAT)
if(ret == ENOENT && (flags & O_CREAT))
r->_errno = EROFS;
else
r->_errno = ENOENT;
r->_errno = ret;
return -1;
}
else if((flags & O_CREAT) && (flags & O_EXCL))
......@@ -680,8 +704,15 @@ int romfs_stat(struct _reent *r, const char *path, struct stat *st)
if(r->_errno != 0)
return -1;
romfs_dir* dir = searchForDir(mount, curDir, (uint8_t*)path, strlen(path));
if(dir)
romfs_dir* dir = NULL;
int ret=0;
ret = searchForDir(mount, curDir, (uint8_t*)path, strlen(path), &dir);
if (ret != 0 && ret != ENOENT)
{
r->_errno = ret;
return -1;
}
if(ret == 0)
{
memset(st, 0, sizeof(*st));
st->st_ino = dir_inode(mount, dir);
......@@ -695,8 +726,14 @@ int romfs_stat(struct _reent *r, const char *path, struct stat *st)
return 0;
}
romfs_file* file = searchForFile(mount, curDir, (uint8_t*)path, strlen(path));
if(file)
romfs_file* file = NULL;
ret = searchForFile(mount, curDir, (uint8_t*)path, strlen(path), &file);
if (ret != 0 && ret != ENOENT)
{
r->_errno = ret;
return -1;
}
if(ret == 0)
{
memset(st, 0, sizeof(*st));
st->st_ino = file_inode(mount, file);
......@@ -774,6 +811,11 @@ int romfs_dirnext(struct _reent *r, DIR_ITER *dirState, char *filename, struct s
{
/* '..' entry */
romfs_dir* dir = romFS_dir(iter->mount, iter->dir->parent);
if(!dir)
{
r->_errno = EFAULT;
return -1;
}
memset(filestat, 0, sizeof(*filestat));
filestat->st_ino = dir_inode(