This commit is contained in:
shchmue 2020-02-17 14:54:23 -07:00
commit 1965841400
5 changed files with 979 additions and 31 deletions

View File

@ -28,6 +28,11 @@ typedef enum {
NifmInternetConnectionStatus_Connected = 4, ///< Internet is connected. NifmInternetConnectionStatus_Connected = 4, ///< Internet is connected.
} NifmInternetConnectionStatus; } NifmInternetConnectionStatus;
/// ClientId
typedef struct {
u32 id; ///< ClientId
} NifmClientId;
/// Initialize nifm. This is used automatically by gethostid(). /// Initialize nifm. This is used automatically by gethostid().
Result nifmInitialize(NifmServiceType service_type); Result nifmInitialize(NifmServiceType service_type);
@ -40,6 +45,11 @@ Service* nifmGetServiceSession_StaticService(void);
/// Gets the Service object for IGeneralService. /// Gets the Service object for IGeneralService.
Service* nifmGetServiceSession_GeneralService(void); Service* nifmGetServiceSession_GeneralService(void);
/**
* @brief GetClientId
*/
NifmClientId nifmGetClientId(void);
Result nifmGetCurrentIpAddress(u32* out); Result nifmGetCurrentIpAddress(u32* out);
/** /**
@ -56,6 +66,13 @@ Result nifmIsWirelessCommunicationEnabled(bool* out);
Result nifmGetInternetConnectionStatus(NifmInternetConnectionType* connectionType, u32* wifiStrength, NifmInternetConnectionStatus* connectionStatus); Result nifmGetInternetConnectionStatus(NifmInternetConnectionType* connectionType, u32* wifiStrength, NifmInternetConnectionStatus* connectionStatus);
Result nifmIsEthernetCommunicationEnabled(bool* out); Result nifmIsEthernetCommunicationEnabled(bool* out);
/**
* @brief IsAnyInternetRequestAccepted
* @param[in] id \ref NifmClientId
*/
bool nifmIsAnyInternetRequestAccepted(NifmClientId id);
Result nifmIsAnyForegroundRequestAccepted(bool* out); Result nifmIsAnyForegroundRequestAccepted(bool* out);
Result nifmPutToSleep(void); Result nifmPutToSleep(void);
Result nifmWakeUp(void); Result nifmWakeUp(void);

View File

@ -10,6 +10,8 @@
#include "../sf/service.h" #include "../sf/service.h"
#include "../services/ncm_types.h" #include "../services/ncm_types.h"
#include "../services/async.h" #include "../services/async.h"
#include "../services/acc.h"
#include "../services/fs.h"
#include "../kernel/event.h" #include "../kernel/event.h"
#include "../kernel/tmem.h" #include "../kernel/tmem.h"
@ -43,6 +45,11 @@ typedef enum {
NsLatestSystemUpdate_Unknown2 = 2, ///< Unknown. NsLatestSystemUpdate_Unknown2 = 2, ///< Unknown.
} NsLatestSystemUpdate; } NsLatestSystemUpdate;
/// RequestServerStopper
typedef struct {
Service s; ///< IRequestServerStopper
} NsRequestServerStopper;
/// SystemUpdateControl /// SystemUpdateControl
typedef struct { typedef struct {
Service s; ///< ISystemUpdateControl Service s; ///< ISystemUpdateControl
@ -136,6 +143,15 @@ typedef struct {
u8 hmac[0x20]; ///< HMAC-SHA256 over the above data. u8 hmac[0x20]; ///< HMAC-SHA256 over the above data.
} NsApplicationDeliveryInfo; } NsApplicationDeliveryInfo;
/// NsApplicationRightsOnClient
typedef struct {
u64 application_id; ///< ApplicationId.
AccountUid uid; ///< \ref AccountUid
u8 flags_x18; ///< qlaunch uses bit0-bit4 and bit7 from here.
u8 flags_x19; ///< qlaunch uses bit0 from here.
u8 unk_x1a[0x6]; ///< Unknown.
} NsApplicationRightsOnClient;
/// Default size for \ref nssuControlSetupCardUpdate / \ref nssuControlSetupCardUpdateViaSystemUpdater. This is the size used by qlaunch for SetupCardUpdate. /// Default size for \ref nssuControlSetupCardUpdate / \ref nssuControlSetupCardUpdateViaSystemUpdater. This is the size used by qlaunch for SetupCardUpdate.
#define NSSU_CARDUPDATE_TMEM_SIZE_DEFAULT 0x100000 #define NSSU_CARDUPDATE_TMEM_SIZE_DEFAULT 0x100000
@ -164,14 +180,222 @@ Service* nsGetServiceSession_ApplicationManagerInterface(void);
Result nsListApplicationRecord(NsApplicationRecord* records, s32 count, s32 entry_offset, s32* out_entrycount); Result nsListApplicationRecord(NsApplicationRecord* records, s32 count, s32 entry_offset, s32* out_entrycount);
/** /**
* @brief Gets an listing of \ref NsApplicationContentMetaStatus. * @brief GetApplicationRecordUpdateSystemEvent
* @param[in] application_id ApplicationId. * @note The Event must be closed by the user once finished with it.
* @param[in] index Starting entry index. * @param[out] out_event Output Event with autoclear=true.
* @param[out] list Output array of \ref NsApplicationContentMetaStatus.
* @param[in] count Size of the list array in entries.
* @param[out] out_entrycount Total output entries.
*/ */
Result nsListApplicationContentMetaStatus(u64 application_id, s32 index, NsApplicationContentMetaStatus* list, s32 count, s32* out_entrycount); Result nsGetApplicationRecordUpdateSystemEvent(Event* out_event);
/**
* @brief DeleteApplicationEntity
* @param[in] application_id ApplicationId.
*/
Result nsDeleteApplicationEntity(u64 application_id);
/**
* @brief DeleteApplicationCompletely
* @param[in] application_id ApplicationId.
*/
Result nsDeleteApplicationCompletely(u64 application_id);
/**
* @brief DeleteRedundantApplicationEntity
*/
Result nsDeleteRedundantApplicationEntity(void);
/**
* @brief IsApplicationEntityMovable
* @param[in] application_id ApplicationId.
* @param[in] storage_id \ref NcmStorageId
* @param[out] out Output flag.
*/
Result nsIsApplicationEntityMovable(u64 application_id, NcmStorageId storage_id, bool *out);
/**
* @brief MoveApplicationEntity
* @param[in] application_id ApplicationId.
* @param[in] storage_id \ref NcmStorageId
*/
Result nsMoveApplicationEntity(u64 application_id, NcmStorageId storage_id);
/**
* @brief RequestApplicationUpdateInfo
* @note \ref nifmInitialize must be used prior to this. Before using the cmd, this calls \ref nifmIsAnyInternetRequestAccepted with the output from \ref nifmGetClientId, an error is returned when that returns false.
* @param[out] a \ref AsyncValue. The data that can be read from this is u8 ApplicationUpdateInfo. qlaunch just checks whether this is 0.
* @param application_id ApplicationId.
*/
Result nsRequestApplicationUpdateInfo(AsyncValue *a, u64 application_id);
/**
* @brief CancelApplicationDownload
* @param[in] application_id ApplicationId.
*/
Result nsCancelApplicationDownload(u64 application_id);
/**
* @brief ResumeApplicationDownload
* @param[in] application_id ApplicationId.
*/
Result nsResumeApplicationDownload(u64 application_id);
/**
* @brief CheckApplicationLaunchVersion
* @param[in] application_id ApplicationId.
*/
Result nsCheckApplicationLaunchVersion(u64 application_id);
/**
* @brief CalculateApplicationApplyDeltaRequiredSize
* @param[in] application_id ApplicationId.
* @param[out] storage_id Output \ref NcmStorageId.
* @param[out] size Output size.
*/
Result nsCalculateApplicationDownloadRequiredSize(u64 application_id, NcmStorageId *storage_id, s64 *size);
/**
* @brief CleanupSdCard
*/
Result nsCleanupSdCard(void);
/**
* @brief GetSdCardMountStatusChangedEvent
* @note The Event must be closed by the user once finished with it.
* @param[out] out_event Output Event with autoclear=false.
*/
Result nsGetSdCardMountStatusChangedEvent(Event* out_event);
/**
* @brief Returns the total storage capacity (used + free) from content manager services.
* @param[in] storage_id \ref NcmStorageId. Must be ::NcmStorageId_SdCard.
* @param[out] size Pointer to output the total storage size to.
*/
Result nsGetTotalSpaceSize(NcmStorageId storage_id, s64 *size);
/**
* @brief Returns the available storage capacity from content manager services.
* @param[in] storage_id \ref NcmStorageId. Must be ::NcmStorageId_SdCard.
* @param[out] size Pointer to output the free storage size to.
*/
Result nsGetFreeSpaceSize(NcmStorageId storage_id, s64 *size);
/**
* @brief GetGameCardUpdateDetectionEvent
* @note The Event must be closed by the user once finished with it.
* @param[out] out_event Output Event with autoclear=false.
*/
Result nsGetGameCardUpdateDetectionEvent(Event* out_event);
/**
* @brief DisableApplicationAutoDelete
* @param[in] application_id ApplicationId.
*/
Result nsDisableApplicationAutoDelete(u64 application_id);
/**
* @brief EnableApplicationAutoDelete
* @param[in] application_id ApplicationId.
*/
Result nsEnableApplicationAutoDelete(u64 application_id);
/**
* @brief SetApplicationTerminateResult
* @param[in] application_id ApplicationId.
* @param[in] res Result.
*/
Result nsSetApplicationTerminateResult(u64 application_id, Result res);
/**
* @brief ClearApplicationTerminateResult
* @param[in] application_id ApplicationId.
*/
Result nsClearApplicationTerminateResult(u64 application_id);
/**
* @brief GetLastSdCardMountUnexpectedResult
*/
Result nsGetLastSdCardMountUnexpectedResult(void);
/**
* @brief Opens a \ref NsRequestServerStopper.
* @note Only available on [2.0.0+].
* @param[out] r \ref NsRequestServerStopper
*/
Result nsGetRequestServerStopper(NsRequestServerStopper *r);
/**
* @brief CancelApplicationApplyDelta
* @note Only available on [3.0.0+].
* @param[in] application_id ApplicationId.
*/
Result nsCancelApplicationApplyDelta(u64 application_id);
/**
* @brief ResumeApplicationApplyDelta
* @note Only available on [3.0.0+].
* @param[in] application_id ApplicationId.
*/
Result nsResumeApplicationApplyDelta(u64 application_id);
/**
* @brief CalculateApplicationApplyDeltaRequiredSize
* @note Only available on [3.0.0+].
* @param[in] application_id ApplicationId.
* @param[out] storage_id Output \ref NcmStorageId.
* @param[out] size Output size.
*/
Result nsCalculateApplicationApplyDeltaRequiredSize(u64 application_id, NcmStorageId *storage_id, s64 *size);
/**
* @brief ResumeAll
* @note Only available on [3.0.0+].
*/
Result nsResumeAll(void);
/**
* @brief Temporarily mounts the specified fs ContentStorage, then uses fs GetTotalSpaceSize/GetFreeSpaceSize with that mounted ContentStorage.
* @note Only available on [3.0.0+].
* @param[in] storage_id \ref NcmStorageId, must be ::NcmStorageId_BuiltInUser or ::NcmStorageId_SdCard.
* @param[out] total_space_size Output from GetTotalSpaceSize.
* @param[out] free_space_size Output from GetFreeSpaceSize.
*/
Result nsGetStorageSize(NcmStorageId storage_id, s64 *total_space_size, s64 *free_space_size);
/**
* @brief RequestUpdateApplication2
* @note \ref nifmInitialize must be used prior to this. Before using the cmd, this calls \ref nifmIsAnyInternetRequestAccepted with the output from \ref nifmGetClientId, an error is returned when that returns false.
* @note Only available on [4.0.0+].
* @param[out] a \ref AsyncResult
* @param[in] application_id ApplicationId.
*/
Result nsRequestUpdateApplication2(AsyncResult *a, u64 application_id);
/**
* @brief DeleteUserSystemSaveData
* @param[in] uid \ref AccountUid
* @param[in] system_save_data_id SystemSaveDataId
*/
Result nsDeleteUserSystemSaveData(AccountUid uid, u64 system_save_data_id);
/**
* @brief DeleteSaveData
* @note Only available on [6.0.0+].
* @param[in] save_data_space_id \ref FsSaveDataSpaceId
* @param[in] save_data_id SaveDataId
*/
Result nsDeleteSaveData(FsSaveDataSpaceId save_data_space_id, u64 save_data_id);
/**
* @brief UnregisterNetworkServiceAccount
* @param[in] uid \ref AccountUid
*/
Result nsUnregisterNetworkServiceAccount(AccountUid uid);
/**
* @brief UnregisterNetworkServiceAccountWithUserSaveDataDeletion
* @note Only available on [6.0.0+].
* @param[in] uid \ref AccountUid
*/
Result nsUnregisterNetworkServiceAccountWithUserSaveDataDeletion(AccountUid uid);
/** /**
* @brief Gets the \ref NsApplicationControlData for the specified application. * @brief Gets the \ref NsApplicationControlData for the specified application.
@ -184,18 +408,156 @@ Result nsListApplicationContentMetaStatus(u64 application_id, s32 index, NsAppli
Result nsGetApplicationControlData(NsApplicationControlSource source, u64 application_id, NsApplicationControlData* buffer, size_t size, u64* actual_size); Result nsGetApplicationControlData(NsApplicationControlSource source, u64 application_id, NsApplicationControlData* buffer, size_t size, u64* actual_size);
/** /**
* @brief Returns the total storage capacity (used + free) from content manager services. * @brief RequestDownloadApplicationControlData
* @param[in] storage_id \ref NcmStorageId. Must be ::NcmStorageId_SdCard. * @note \ref nifmInitialize must be used prior to this. Before using the cmd, this calls \ref nifmIsAnyInternetRequestAccepted with the output from \ref nifmGetClientId, an error is returned when that returns false.
* @param[out] size Pointer to output the total storage size to. * @param[out] a \ref AsyncResult
* @param[in] application_id ApplicationId.
*/ */
Result nsGetTotalSpaceSize(NcmStorageId storage_id, u64 *size); Result nsRequestDownloadApplicationControlData(AsyncResult *a, u64 application_id);
/** /**
* @brief Returns the available storage capacity from content manager services. * @brief RequestCheckGameCardRegistration
* @param[in] storage_id \ref NcmStorageId. Must be ::NcmStorageId_SdCard. * @note \ref nifmInitialize must be used prior to this. Before using the cmd, this calls \ref nifmIsAnyInternetRequestAccepted with the output from \ref nifmGetClientId, an error is returned when that returns false.
* @param[out] size Pointer to output the free storage size to. * @note Only available on [2.0.0+].
* @param[out] a \ref AsyncResult
* @param[in] application_id ApplicationId.
*/ */
Result nsGetFreeSpaceSize(NcmStorageId storage_id, u64 *size); Result nsRequestCheckGameCardRegistration(AsyncResult *a, u64 application_id);
/**
* @brief RequestGameCardRegistrationGoldPoint
* @note \ref nifmInitialize must be used prior to this. Before using the cmd, this calls \ref nifmIsAnyInternetRequestAccepted with the output from \ref nifmGetClientId, an error is returned when that returns false.
* @note Only available on [2.0.0+].
* @param[out] a \ref AsyncValue. The data that can be read from this is 4-bytes.
* @param[in] uid \ref AccountUid
* @param[in] application_id ApplicationId.
*/
Result nsRequestGameCardRegistrationGoldPoint(AsyncValue *a, AccountUid uid, u64 application_id);
/**
* @brief RequestRegisterGameCard
* @note \ref nifmInitialize must be used prior to this. Before using the cmd, this calls \ref nifmIsAnyInternetRequestAccepted with the output from \ref nifmGetClientId, an error is returned when that returns false.
* @note Only available on [2.0.0+].
* @param[out] a \ref AsyncResult
* @param[in] uid \ref AccountUid
* @param[in] application_id ApplicationId.
* @param[in] inval Input value.
*/
Result nsRequestRegisterGameCard(AsyncResult *a, AccountUid uid, u64 application_id, s32 inval);
/**
* @brief GetGameCardMountFailureEvent
* @note The Event must be closed by the user once finished with it.
* @note Only available on [3.0.0+].
* @param[out] out_event Output Event with autoclear=false.
*/
Result nsGetGameCardMountFailureEvent(Event* out_event);
/**
* @brief IsGameCardInserted
* @note Only available on [3.0.0+].
* @param[out] out Output flag.
*/
Result nsIsGameCardInserted(bool *out);
/**
* @brief EnsureGameCardAccess
* @note Only available on [3.0.0+].
*/
Result nsEnsureGameCardAccess(void);
/**
* @brief GetLastGameCardMountFailureResult
* @note Only available on [3.0.0+].
*/
Result nsGetLastGameCardMountFailureResult(void);
/**
* @brief ListApplicationIdOnGameCard
* @note Only available on [5.0.0+].
* @param[out] application_ids Output array of ApplicationIds.
* @param[in] count Size of the application_ids array in entries.
* @param[out] total_out Total output entries.
*/
Result nsListApplicationIdOnGameCard(u64 *application_ids, s32 count, s32 *total_out);
/**
* @brief Gets an listing of \ref NsApplicationContentMetaStatus.
* @note Only available on [2.0.0+].
* @param[in] application_id ApplicationId.
* @param[in] index Starting entry index.
* @param[out] list Output array of \ref NsApplicationContentMetaStatus.
* @param[in] count Size of the list array in entries.
* @param[out] out_entrycount Total output entries.
*/
Result nsListApplicationContentMetaStatus(u64 application_id, s32 index, NsApplicationContentMetaStatus* list, s32 count, s32* out_entrycount);
/**
* @brief TouchApplication
* @note Only available on [2.0.0+].
* @param[in] application_id ApplicationId.
*/
Result nsTouchApplication(u64 application_id);
/**
* @brief IsApplicationUpdateRequested
* @note Only available on [2.0.0+].
* @param[in] application_id ApplicationId.
* @param[out] flag Output flag, indicating whether out is valid.
* @param[out] out Output value.
*/
Result nsIsApplicationUpdateRequested(u64 application_id, bool *flag, u32 *out);
/**
* @brief WithdrawApplicationUpdateRequest
* @note Only available on [2.0.0+].
* @param[in] application_id ApplicationId.
*/
Result nsWithdrawApplicationUpdateRequest(u64 application_id);
/**
* @brief IsAnyApplicationEntityInstalled
* @note Only available on [2.0.0+].
* @param[in] application_id ApplicationId.
* @param[out] out Output flag.
*/
Result nsIsAnyApplicationEntityInstalled(u64 application_id, bool *out);
/**
* @brief CleanupUnavailableAddOnContents
* @note Only available on [6.0.0+].
* @param[in] application_id ApplicationId.
* @param[in] uid \ref AccountUid
*/
Result nsCleanupUnavailableAddOnContents(u64 application_id, AccountUid uid);
/**
* @brief FormatSdCard
* @note Only available on [2.0.0+].
*/
Result nsFormatSdCard(void);
/**
* @brief NeedsSystemUpdateToFormatSdCard
* @note Only available on [2.0.0+].
* @param[out] out Output flag.
*/
Result nsNeedsSystemUpdateToFormatSdCard(bool *out);
/**
* @brief GetLastSdCardFormatUnexpectedResult
* @note Only available on [2.0.0+].
*/
Result nsGetLastSdCardFormatUnexpectedResult(void);
/**
* @brief RequestDownloadApplicationPrepurchasedRights
* @note \ref nifmInitialize must be used prior to this. Before using the cmd, this calls \ref nifmIsAnyInternetRequestAccepted with the output from \ref nifmGetClientId, an error is returned when that returns false.
* @note Only available on [4.0.0+].
* @param[out] a \ref AsyncResult
* @param[in] application_id ApplicationId.
*/
Result nsRequestDownloadApplicationPrepurchasedRights(AsyncResult *a, u64 application_id);
/** /**
* @brief Generates a \ref NsSystemDeliveryInfo using the currently installed SystemUpdate meta. * @brief Generates a \ref NsSystemDeliveryInfo using the currently installed SystemUpdate meta.
@ -376,6 +738,55 @@ Result nsListNotCommittedContentMeta(NcmContentMetaKey *meta, s32 count, u64 app
*/ */
Result nsGetApplicationDeliveryInfoHash(const NsApplicationDeliveryInfo *info, s32 count, u8 *out_hash); Result nsGetApplicationDeliveryInfoHash(const NsApplicationDeliveryInfo *info, s32 count, u8 *out_hash);
/**
* @brief GetApplicationTerminateResult
* @note Only available on [6.0.0+].
* @param[in] application_id ApplicationId.
* @param[out] res Output Result.
*/
Result nsGetApplicationTerminateResult(u64 application_id, Result *res);
/**
* @brief GetApplicationRightsOnClient
* @note Only available on [6.0.0+].
* @param[out] rights Output array of \ref NsApplicationRightsOnClient.
* @param[in] count Size of the rights array in entries. qlaunch uses value 3 for this.
* @param[in] application_id ApplicationId
* @param[in] uid \ref AccountUid, can optionally be all-zero.
* @param[in] flags Flags. Official sw hard-codes this to value 0x3.
* @param[out] total_out Total output entries.
*/
Result nsGetApplicationRightsOnClient(NsApplicationRightsOnClient *rights, s32 count, u64 application_id, AccountUid uid, u32 flags, s32 *total_out);
/**
* @brief RequestNoDownloadRightsErrorResolution
* @note \ref nifmInitialize must be used prior to this. Before using the cmd, this calls \ref nifmIsAnyInternetRequestAccepted with the output from \ref nifmGetClientId, an error is returned when that returns false.
* @note Only available on [9.0.0+].
* @param[out] a \ref AsyncValue. The data that can be read from this is u8 NoDownloadRightsErrorResolution.
* @param application_id ApplicationId.
*/
Result nsRequestNoDownloadRightsErrorResolution(AsyncValue *a, u64 application_id);
/**
* @brief RequestResolveNoDownloadRightsError
* @note \ref nifmInitialize must be used prior to this. Before using the cmd, this calls \ref nifmIsAnyInternetRequestAccepted with the output from \ref nifmGetClientId, an error is returned when that returns false.
* @note Only available on [9.0.0+].
* @param[out] a \ref AsyncValue. The data that can be read from this is u8 NoDownloadRightsErrorResolution.
* @param application_id ApplicationId.
*/
Result nsRequestResolveNoDownloadRightsError(AsyncValue *a, u64 application_id);
///@}
///@name IRequestServerStopper
///@{
/**
* @brief Close a \ref NsRequestServerStopper.
* @param r \ref NsRequestServerStopper
*/
void nsRequestServerStopperClose(NsRequestServerStopper *r);
///@} ///@}
///@name ns:vm ///@name ns:vm

View File

@ -85,10 +85,10 @@ void pmshellExit(void);
Service* pmshellGetServiceSession(void); Service* pmshellGetServiceSession(void);
/// Initialize pm:bm. /// Initialize pm:bm.
Result pmbmInitialize(); Result pmbmInitialize(void);
/// Exit pm:bm. /// Exit pm:bm.
void pmbmExit(); void pmbmExit(void);
/// Gets the Service object for the actual pm:bm service session. /// Gets the Service object for the actual pm:bm service session.
Service* pmbmGetServiceSession(void); Service* pmbmGetServiceSession(void);

View File

@ -105,6 +105,16 @@ static Result _nifmCreateGeneralService(Service* srv_out) {
); );
} }
NifmClientId nifmGetClientId(void) {
NifmClientId id={0};
Result rc = serviceDispatch(&g_nifmIGS, 1,
.buffer_attrs = { SfBufferAttr_FixedSize | SfBufferAttr_HipcPointer | SfBufferAttr_Out },
.buffers = { { &id, sizeof(id) } },
);
if (R_FAILED(rc)) id.id = 0;
return id;
}
Result nifmGetCurrentIpAddress(u32* out) { Result nifmGetCurrentIpAddress(u32* out) {
return _nifmCmdNoInOutU32(&g_nifmIGS, out, 12); return _nifmCmdNoInOutU32(&g_nifmIGS, out, 12);
} }
@ -141,6 +151,15 @@ Result nifmIsEthernetCommunicationEnabled(bool* out) {
return _nifmCmdNoInOutBool(&g_nifmIGS, out, 20); return _nifmCmdNoInOutBool(&g_nifmIGS, out, 20);
} }
bool nifmIsAnyInternetRequestAccepted(NifmClientId id) {
u8 tmp=0;
Result rc = serviceDispatchOut(&g_nifmIGS, 21, tmp,
.buffer_attrs = { SfBufferAttr_FixedSize | SfBufferAttr_HipcPointer | SfBufferAttr_In },
.buffers = { { &id, sizeof(id) } },
);
return R_SUCCEEDED(rc) ? tmp & 1 : 0;
}
Result nifmIsAnyForegroundRequestAccepted(bool* out) { Result nifmIsAnyForegroundRequestAccepted(bool* out) {
return _nifmCmdNoInOutBool(&g_nifmIGS, out, 22); return _nifmCmdNoInOutBool(&g_nifmIGS, out, 22);
} }

View File

@ -4,6 +4,7 @@
#include "runtime/hosversion.h" #include "runtime/hosversion.h"
#include "services/ns.h" #include "services/ns.h"
#include "services/async.h" #include "services/async.h"
#include "services/nifm.h"
static Service g_nsAppManSrv, g_nsGetterSrv; static Service g_nsAppManSrv, g_nsGetterSrv;
static Service g_nsvmSrv; static Service g_nsvmSrv;
@ -109,6 +110,35 @@ static Result _nsCmdNoInOutU64(Service* srv, u64 *out, u32 cmd_id) {
return serviceDispatchOut(srv, cmd_id, *out); return serviceDispatchOut(srv, cmd_id, *out);
} }
static Result _nsCmdInU8U64NoOut(Service* srv, u8 in8, u64 in64, u32 cmd_id) {
const struct {
u8 in8;
u8 pad[7];
u64 in64;
} in = { in8, {0}, in64 };
return serviceDispatchIn(srv, cmd_id, in);
}
static Result _nsCmdInU64OutStorageIdS64(Service* srv, u64 inval, NcmStorageId *storage_id, s64 *outval, u32 cmd_id) {
struct {
u8 storage_id;
u8 pad[7];
s64 outval;
} out;
Result rc = serviceDispatchInOut(srv, cmd_id, inval, out);
if (R_SUCCEEDED(rc)) {
if (storage_id) *storage_id = out.storage_id;
if (outval) *outval = out.outval;
}
return rc;
}
static Result _nsCmdInUidNoOut(Service* srv, AccountUid uid, u32 cmd_id) {
return serviceDispatchIn(srv, cmd_id, uid);
}
static Result _nsCmdNoInOutSystemUpdateProgress(Service* srv, NsSystemUpdateProgress *out, u32 cmd_id) { static Result _nsCmdNoInOutSystemUpdateProgress(Service* srv, NsSystemUpdateProgress *out, u32 cmd_id) {
return serviceDispatchOut(srv, cmd_id, *out); return serviceDispatchOut(srv, cmd_id, *out);
} }
@ -168,6 +198,42 @@ static Result _nsCmdNoInOutAsyncResult(Service* srv, AsyncResult *a, u32 cmd_id)
return rc; return rc;
} }
static Result _nsCmdInU64OutAsyncValue(Service* srv, AsyncValue *a, u64 inval, u32 cmd_id) {
memset(a, 0, sizeof(*a));
Handle event = INVALID_HANDLE;
Result rc = serviceDispatchIn(srv, cmd_id, inval,
.out_num_objects = 1,
.out_objects = &a->s,
.out_handle_attrs = { SfOutHandleAttr_HipcCopy },
.out_handles = &event,
);
if (R_SUCCEEDED(rc))
eventLoadRemote(&a->event, event, false);
return rc;
}
static Result _nsCmdInU64OutAsyncResult(Service* srv, AsyncResult *a, u64 inval, u32 cmd_id) {
memset(a, 0, sizeof(*a));
Handle event = INVALID_HANDLE;
Result rc = serviceDispatchIn(srv, cmd_id, inval,
.out_num_objects = 1,
.out_objects = &a->s,
.out_handle_attrs = { SfOutHandleAttr_HipcCopy },
.out_handles = &event,
);
if (R_SUCCEEDED(rc))
eventLoadRemote(&a->event, event, false);
return rc;
}
static Result _nsCheckNifm(void) {
return nifmIsAnyInternetRequestAccepted(nifmGetClientId()) ? 0 : MAKERESULT(16, 340);
}
Result nsListApplicationRecord(NsApplicationRecord* records, s32 count, s32 entry_offset, s32* out_entrycount) { Result nsListApplicationRecord(NsApplicationRecord* records, s32 count, s32 entry_offset, s32* out_entrycount) {
return serviceDispatchInOut(&g_nsAppManSrv, 0, entry_offset, *out_entrycount, return serviceDispatchInOut(&g_nsAppManSrv, 0, entry_offset, *out_entrycount,
.buffer_attrs = { SfBufferAttr_HipcMapAlias | SfBufferAttr_Out }, .buffer_attrs = { SfBufferAttr_HipcMapAlias | SfBufferAttr_Out },
@ -175,23 +241,204 @@ Result nsListApplicationRecord(NsApplicationRecord* records, s32 count, s32 entr
); );
} }
Result nsListApplicationContentMetaStatus(u64 application_id, s32 index, NsApplicationContentMetaStatus* list, s32 count, s32* out_entrycount) { Result nsGetApplicationRecordUpdateSystemEvent(Event* out_event) {
const struct { return _nsCmdGetEvent(&g_nsAppManSrv, out_event, true, 2);
s32 index; }
u64 application_id;
} in = { index, application_id };
return serviceDispatchInOut(&g_nsAppManSrv, 601, in, *out_entrycount, Result nsDeleteApplicationEntity(u64 application_id) {
.buffer_attrs = { SfBufferAttr_HipcMapAlias | SfBufferAttr_Out }, return _nsCmdInU64(&g_nsAppManSrv, application_id, 4);
.buffers = { { list, count*sizeof(NsApplicationContentMetaStatus) } }, }
);
Result nsDeleteApplicationCompletely(u64 application_id) {
return _nsCmdInU64(&g_nsAppManSrv, application_id, 5);
}
Result nsDeleteRedundantApplicationEntity(void) {
return _nsCmdNoIO(&g_nsAppManSrv, 7);
}
Result nsIsApplicationEntityMovable(u64 application_id, NcmStorageId storage_id, bool *out) {
const struct {
u8 storage_id;
u8 pad[7];
u64 application_id;
} in = { storage_id, {0}, application_id };
u8 tmp=0;
Result rc = serviceDispatchInOut(&g_nsAppManSrv, 8, in, tmp);
if (R_SUCCEEDED(rc) && out) *out = tmp & 1;
return rc;
}
Result nsMoveApplicationEntity(u64 application_id, NcmStorageId storage_id) {
return _nsCmdInU8U64NoOut(&g_nsAppManSrv, storage_id, application_id, 9);
}
Result nsRequestApplicationUpdateInfo(AsyncValue *a, u64 application_id) {
Result rc = _nsCheckNifm();
if (R_FAILED(rc)) return rc;
return _nsCmdInU64OutAsyncValue(&g_nsAppManSrv, a, application_id, 30);
}
Result nsCancelApplicationDownload(u64 application_id) {
return _nsCmdInU64(&g_nsAppManSrv, application_id, 32);
}
Result nsResumeApplicationDownload(u64 application_id) {
return _nsCmdInU64(&g_nsAppManSrv, application_id, 33);
}
Result nsCheckApplicationLaunchVersion(u64 application_id) {
return _nsCmdInU64(&g_nsAppManSrv, application_id, 38);
}
Result nsCalculateApplicationDownloadRequiredSize(u64 application_id, NcmStorageId *storage_id, s64 *size) {
return _nsCmdInU64OutStorageIdS64(&g_nsAppManSrv, application_id, storage_id, size, 41);
}
Result nsCleanupSdCard(void) {
return _nsCmdNoIO(&g_nsAppManSrv, 42);
}
Result nsGetSdCardMountStatusChangedEvent(Event* out_event) {
return _nsCmdGetEvent(&g_nsAppManSrv, out_event, false, 44);
}
Result nsGetTotalSpaceSize(NcmStorageId storage_id, s64 *size) {
return _nsCmdInU64OutU64(&g_nsAppManSrv, storage_id, (u64*)size, 47);
}
Result nsGetFreeSpaceSize(NcmStorageId storage_id, s64 *size) {
return _nsCmdInU64OutU64(&g_nsAppManSrv, storage_id, (u64*)size, 48);
}
Result nsGetGameCardUpdateDetectionEvent(Event* out_event) {
return _nsCmdGetEvent(&g_nsAppManSrv, out_event, false, 52);
}
Result nsDisableApplicationAutoDelete(u64 application_id) {
return _nsCmdInU64(&g_nsAppManSrv, application_id, 53);
}
Result nsEnableApplicationAutoDelete(u64 application_id) {
return _nsCmdInU64(&g_nsAppManSrv, application_id, 54);
}
Result nsSetApplicationTerminateResult(u64 application_id, Result res) {
const struct {
Result res;
u32 pad;
u64 application_id;
} in = { res, 0, application_id };
return serviceDispatchIn(&g_nsAppManSrv, 56, in);
}
Result nsClearApplicationTerminateResult(u64 application_id) {
return _nsCmdInU64(&g_nsAppManSrv, application_id, 57);
}
Result nsGetLastSdCardMountUnexpectedResult(void) {
return _nsCmdNoIO(&g_nsAppManSrv, 58);
}
Result nsGetRequestServerStopper(NsRequestServerStopper *r) {
if (hosversionBefore(2,0,0))
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
return _nsGetSession(&g_nsAppManSrv, &r->s, 65);
}
Result nsCancelApplicationApplyDelta(u64 application_id) {
if (hosversionBefore(3,0,0))
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
return _nsCmdInU64(&g_nsAppManSrv, application_id, 67);
}
Result nsResumeApplicationApplyDelta(u64 application_id) {
if (hosversionBefore(3,0,0))
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
return _nsCmdInU64(&g_nsAppManSrv, application_id, 68);
}
Result nsCalculateApplicationApplyDeltaRequiredSize(u64 application_id, NcmStorageId *storage_id, s64 *size) {
if (hosversionBefore(3,0,0))
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
return _nsCmdInU64OutStorageIdS64(&g_nsAppManSrv, application_id, storage_id, size, 69);
}
Result nsResumeAll(void) {
if (hosversionBefore(3,0,0))
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
return _nsCmdNoIO(&g_nsAppManSrv, 70);
}
Result nsGetStorageSize(NcmStorageId storage_id, s64 *total_space_size, s64 *free_space_size) {
if (hosversionBefore(3,0,0))
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
struct {
s64 total_space_size;
s64 free_space_size;
} out;
u8 tmp = storage_id;
Result rc = serviceDispatchInOut(&g_nsAppManSrv, 71, tmp, out);
if (R_SUCCEEDED(rc)) {
if (total_space_size) *total_space_size = out.total_space_size;
if (free_space_size) *free_space_size = out.free_space_size;
}
return rc;
}
Result nsRequestUpdateApplication2(AsyncResult *a, u64 application_id) {
if (hosversionBefore(4,0,0))
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
Result rc = _nsCheckNifm();
if (R_FAILED(rc)) return rc;
return _nsCmdInU64OutAsyncResult(&g_nsAppManSrv, a, application_id, 85);
}
Result nsDeleteUserSystemSaveData(AccountUid uid, u64 system_save_data_id) {
const struct {
AccountUid uid;
u64 system_save_data_id;
} in = { uid, system_save_data_id };
return serviceDispatchIn(&g_nsAppManSrv, 210, in);
}
Result nsDeleteSaveData(FsSaveDataSpaceId save_data_space_id, u64 save_data_id) {
if (hosversionBefore(6,0,0))
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
return _nsCmdInU8U64NoOut(&g_nsAppManSrv, save_data_space_id, save_data_id, 211);
}
Result nsUnregisterNetworkServiceAccount(AccountUid uid) {
return _nsCmdInUidNoOut(&g_nsAppManSrv, uid, 220);
}
Result nsUnregisterNetworkServiceAccountWithUserSaveDataDeletion(AccountUid uid) {
if (hosversionBefore(6,0,0))
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
return _nsCmdInUidNoOut(&g_nsAppManSrv, uid, 221);
} }
Result nsGetApplicationControlData(NsApplicationControlSource source, u64 application_id, NsApplicationControlData* buffer, size_t size, u64* actual_size) { Result nsGetApplicationControlData(NsApplicationControlSource source, u64 application_id, NsApplicationControlData* buffer, size_t size, u64* actual_size) {
const struct { const struct {
u8 source; u8 source;
u8 pad[7];
u64 application_id; u64 application_id;
} in = { source, application_id }; } in = { source, {0}, application_id };
u32 tmp=0; u32 tmp=0;
@ -203,12 +450,216 @@ Result nsGetApplicationControlData(NsApplicationControlSource source, u64 applic
return rc; return rc;
} }
Result nsGetTotalSpaceSize(NcmStorageId storage_id, u64 *size) { Result nsRequestDownloadApplicationControlData(AsyncResult *a, u64 application_id) {
return _nsCmdInU64OutU64(&g_nsAppManSrv, storage_id, size, 47); Result rc = _nsCheckNifm();
if (R_FAILED(rc)) return rc;
return _nsCmdInU64OutAsyncResult(&g_nsAppManSrv, a, application_id, 402);
} }
Result nsGetFreeSpaceSize(NcmStorageId storage_id, u64 *size) { Result nsRequestCheckGameCardRegistration(AsyncResult *a, u64 application_id) {
return _nsCmdInU64OutU64(&g_nsAppManSrv, storage_id, size, 48); if (hosversionBefore(2,0,0))
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
Result rc = _nsCheckNifm();
if (R_FAILED(rc)) return rc;
return _nsCmdInU64OutAsyncResult(&g_nsAppManSrv, a, application_id, 502);
}
Result nsRequestGameCardRegistrationGoldPoint(AsyncValue *a, AccountUid uid, u64 application_id) {
if (hosversionBefore(2,0,0))
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
Result rc = _nsCheckNifm();
if (R_FAILED(rc)) return rc;
const struct {
AccountUid uid;
u64 application_id;
} in = { uid, application_id };
memset(a, 0, sizeof(*a));
Handle event = INVALID_HANDLE;
rc = serviceDispatchIn(&g_nsAppManSrv, 503, in,
.out_num_objects = 1,
.out_objects = &a->s,
.out_handle_attrs = { SfOutHandleAttr_HipcCopy },
.out_handles = &event,
);
if (R_SUCCEEDED(rc))
eventLoadRemote(&a->event, event, false);
return rc;
}
Result nsRequestRegisterGameCard(AsyncResult *a, AccountUid uid, u64 application_id, s32 inval) {
if (hosversionBefore(2,0,0))
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
Result rc = _nsCheckNifm();
if (R_FAILED(rc)) return rc;
const struct {
s32 inval;
u32 pad;
AccountUid uid;
u64 application_id;
} in = { inval, 0, uid, application_id };
memset(a, 0, sizeof(*a));
Handle event = INVALID_HANDLE;
rc = serviceDispatchIn(&g_nsAppManSrv, 504, in,
.out_num_objects = 1,
.out_objects = &a->s,
.out_handle_attrs = { SfOutHandleAttr_HipcCopy },
.out_handles = &event,
);
if (R_SUCCEEDED(rc))
eventLoadRemote(&a->event, event, false);
return rc;
}
Result nsGetGameCardMountFailureEvent(Event* out_event) {
if (hosversionBefore(3,0,0))
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
return _nsCmdGetEvent(&g_nsAppManSrv, out_event, false, 505);
}
Result nsIsGameCardInserted(bool *out) {
if (hosversionBefore(3,0,0))
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
return _nsCmdNoInOutBool(&g_nsAppManSrv, out, 506);
}
Result nsEnsureGameCardAccess(void) {
if (hosversionBefore(3,0,0))
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
return _nsCmdNoIO(&g_nsAppManSrv, 507);
}
Result nsGetLastGameCardMountFailureResult(void) {
if (hosversionBefore(3,0,0))
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
return _nsCmdNoIO(&g_nsAppManSrv, 508);
}
Result nsListApplicationIdOnGameCard(u64 *application_ids, s32 count, s32 *total_out) {
if (hosversionBefore(5,0,0))
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
return serviceDispatchOut(&g_nsAppManSrv, 509, *total_out,
.buffer_attrs = { SfBufferAttr_HipcMapAlias | SfBufferAttr_Out },
.buffers = { { application_ids, count*sizeof(u64) } },
);
}
Result nsListApplicationContentMetaStatus(u64 application_id, s32 index, NsApplicationContentMetaStatus* list, s32 count, s32* out_entrycount) {
if (hosversionBefore(2,0,0))
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
const struct {
s32 index;
u32 pad;
u64 application_id;
} in = { index, 0, application_id };
return serviceDispatchInOut(&g_nsAppManSrv, 601, in, *out_entrycount,
.buffer_attrs = { SfBufferAttr_HipcMapAlias | SfBufferAttr_Out },
.buffers = { { list, count*sizeof(NsApplicationContentMetaStatus) } },
);
}
Result nsTouchApplication(u64 application_id) {
if (hosversionBefore(2,0,0))
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
return _nsCmdInU64(&g_nsAppManSrv, application_id, 904);
}
Result nsIsApplicationUpdateRequested(u64 application_id, bool *flag, u32 *out) {
if (hosversionBefore(2,0,0))
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
struct {
u8 flag;
u8 pad[3];
u32 out;
} tmpout;
Result rc = serviceDispatchInOut(&g_nsAppManSrv, 906, application_id, tmpout);
if (R_SUCCEEDED(rc)) {
if (flag) *flag = tmpout.flag & 1;
if (out) *out = tmpout.out;
}
return rc;
}
Result nsWithdrawApplicationUpdateRequest(u64 application_id) {
if (hosversionBefore(2,0,0))
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
return _nsCmdInU64(&g_nsAppManSrv, application_id, 907);
}
Result nsIsAnyApplicationEntityInstalled(u64 application_id, bool *out) {
if (hosversionBefore(2,0,0))
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
u8 tmp=0;
Result rc = serviceDispatchInOut(&g_nsAppManSrv, 1300, application_id, tmp);
if (R_SUCCEEDED(rc) && out) *out = tmp & 1;
return rc;
}
Result nsCleanupUnavailableAddOnContents(u64 application_id, AccountUid uid) {
if (hosversionBefore(6,0,0))
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
const struct {
u64 application_id;
AccountUid uid;
} in = { application_id, uid };
return serviceDispatchIn(&g_nsAppManSrv, 1309, in);
}
Result nsFormatSdCard(void) {
if (hosversionBefore(2,0,0))
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
return _nsCmdNoIO(&g_nsAppManSrv, 1500);
}
Result nsNeedsSystemUpdateToFormatSdCard(bool *out) {
if (hosversionBefore(2,0,0))
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
return _nsCmdNoInOutBool(&g_nsAppManSrv, out, 1501);
}
Result nsGetLastSdCardFormatUnexpectedResult(void) {
if (hosversionBefore(2,0,0))
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
return _nsCmdNoIO(&g_nsAppManSrv, 1502);
}
Result nsRequestDownloadApplicationPrepurchasedRights(AsyncResult *a, u64 application_id) {
if (hosversionBefore(4,0,0))
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
Result rc = _nsCheckNifm();
if (R_FAILED(rc)) return rc;
return _nsCmdInU64OutAsyncResult(&g_nsAppManSrv, a, application_id, 1901);
} }
Result nsGetSystemDeliveryInfo(NsSystemDeliveryInfo *info) { Result nsGetSystemDeliveryInfo(NsSystemDeliveryInfo *info) {
@ -482,6 +933,56 @@ Result nsGetApplicationDeliveryInfoHash(const NsApplicationDeliveryInfo *info, s
return rc; return rc;
} }
Result nsGetApplicationTerminateResult(u64 application_id, Result *res) {
if (hosversionBefore(6,0,0))
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
return serviceDispatchInOut(&g_nsAppManSrv, 2100, application_id, *res);
}
Result nsGetApplicationRightsOnClient(NsApplicationRightsOnClient *rights, s32 count, u64 application_id, AccountUid uid, u32 flags, s32 *total_out) {
if (hosversionBefore(6,0,0))
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
const struct {
u32 flags;
u32 pad;
u64 application_id;
AccountUid uid;
} in = { flags, 0, application_id, uid };
return serviceDispatchInOut(&g_nsAppManSrv, 2050, in, *total_out,
.buffer_attrs = { SfBufferAttr_HipcMapAlias | SfBufferAttr_Out },
.buffers = { { rights, count*sizeof(NsApplicationRightsOnClient) } },
);
}
Result nsRequestNoDownloadRightsErrorResolution(AsyncValue *a, u64 application_id) {
if (hosversionBefore(9,0,0))
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
Result rc = _nsCheckNifm();
if (R_FAILED(rc)) return rc;
return _nsCmdInU64OutAsyncValue(&g_nsAppManSrv, a, application_id, 2351);
}
Result nsRequestResolveNoDownloadRightsError(AsyncValue *a, u64 application_id) {
if (hosversionBefore(9,0,0))
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
Result rc = _nsCheckNifm();
if (R_FAILED(rc)) return rc;
return _nsCmdInU64OutAsyncValue(&g_nsAppManSrv, a, application_id, 2352);
}
// IRequestServerStopper
void nsRequestServerStopperClose(NsRequestServerStopper *r) {
serviceClose(&r->s);
}
// ns:vm // ns:vm
NX_GENERATE_SERVICE_GUARD(nsvm); NX_GENERATE_SERVICE_GUARD(nsvm);