diff --git a/nx/include/switch/services/ns.h b/nx/include/switch/services/ns.h index e21b7315..5cd13794 100644 --- a/nx/include/switch/services/ns.h +++ b/nx/include/switch/services/ns.h @@ -74,6 +74,11 @@ typedef struct { u8 icon[0x20000]; ///< JPEG } NsApplicationControlData; +/// ApplicationOccupiedSize +typedef struct { + u8 unk_x0[0x80]; ///< Unknown. +} NsApplicationOccupiedSize; + /// NsApplicationContentMetaStatus typedef struct { u8 meta_type; ///< \ref NcmContentMetaType @@ -235,8 +240,13 @@ Service* nsGetServiceSession_GetterInterface(void); Service* nsGetServiceSession_ApplicationManagerInterface(void); /// Gets the Service object for IFactoryResetInterface via the cmd for that. +/// Only available on [3.0.0+]. Result nsGetFactoryResetInterface(Service* srv_out); +/// Gets the Service object for IContentManagementInterface via the cmd for that. +/// Only available on [3.0.0+]. +Result nsGetContentManagementInterface(Service* srv_out); + ///@} ///@name IFactoryResetInterface @@ -381,20 +391,6 @@ Result nsCleanupSdCard(void); */ 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. @@ -631,17 +627,6 @@ Result nsGetLastGameCardMountFailureResult(void); */ 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+]. @@ -982,6 +967,69 @@ Result nsGetPromotionInfo(NsPromotionInfo *promotion, u64 application_id, Accoun ///@} +///@name IContentManagementInterface +///@{ + +/** + * @brief CalculateApplicationOccupiedSize + * @note Uses \ref nsGetContentManagementInterface on [3.0.0+], otherwise IApplicationManagerInterface is used. + * @param[in] application_id ApplicationId. + * @param[out] out \ref NsApplicationOccupiedSize + */ +Result nsCalculateApplicationOccupiedSize(u64 application_id, NsApplicationOccupiedSize *out); + +/** + * @brief CheckSdCardMountStatus + * @note Uses \ref nsGetContentManagementInterface on [3.0.0+], otherwise IApplicationManagerInterface is used. + */ +Result nsCheckSdCardMountStatus(void); + +/** + * @brief Returns the total storage capacity (used + free) from content manager services. + * @note Uses \ref nsGetContentManagementInterface on [3.0.0+], otherwise IApplicationManagerInterface is used. + * @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. + * @note Uses \ref nsGetContentManagementInterface on [3.0.0+], otherwise IApplicationManagerInterface is used. + * @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 CountApplicationContentMeta + * @note Uses \ref nsGetContentManagementInterface on [3.0.0+], otherwise IApplicationManagerInterface is used. + * @note Only available on [2.0.0+]. + * @param[in] application_id ApplicationId. + * @param[out] out Output count. + */ +Result nsCountApplicationContentMeta(u64 application_id, s32 *out); + +/** + * @brief Gets an listing of \ref NsApplicationContentMetaStatus. + * @note Uses \ref nsGetContentManagementInterface on [3.0.0+], otherwise IApplicationManagerInterface is used. + * @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 IsAnyApplicationRunning + * @note Only available on [3.0.0+]. + * @param[out] out Output flag. + */ +Result nsIsAnyApplicationRunning(bool *out); + +///@} + ///@name IRequestServerStopper ///@{ diff --git a/nx/source/services/ns.c b/nx/source/services/ns.c index bbc430f1..4f8ec96b 100644 --- a/nx/source/services/ns.c +++ b/nx/source/services/ns.c @@ -47,9 +47,19 @@ Service* nsGetServiceSession_ApplicationManagerInterface(void) { } Result nsGetFactoryResetInterface(Service* srv_out) { + if (hosversionBefore(3,0,0)) + return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); + return _nsGetSession(&g_nsGetterSrv, srv_out, 7994); } +Result nsGetContentManagementInterface(Service* srv_out) { + if (hosversionBefore(3,0,0)) + return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); + + return _nsGetSession(&g_nsGetterSrv, srv_out, 7998); +} + static Result _nsGetSession(Service* srv, Service* srv_out, u32 cmd_id) { return serviceDispatch(srv, cmd_id, .out_num_objects = 1, @@ -397,14 +407,6 @@ 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); } @@ -713,22 +715,6 @@ Result nsListApplicationIdOnGameCard(u64 *application_ids, s32 count, s32 *total ); } -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); @@ -1271,6 +1257,120 @@ Result nsGetPromotionInfo(NsPromotionInfo *promotion, u64 application_id, Accoun ); } +// IContentManagementInterface + +Result nsCalculateApplicationOccupiedSize(u64 application_id, NsApplicationOccupiedSize *out) { + Service srv={0}, *srv_ptr = &srv; + Result rc=0; + if (hosversionAtLeast(3,0,0)) + rc = nsGetContentManagementInterface(&srv); + else + srv_ptr = &g_nsAppManSrv; + + if (R_SUCCEEDED(rc)) rc = serviceDispatchInOut(srv_ptr, 11, application_id, *out); + + serviceClose(&srv); + return rc; +} + +Result nsCheckSdCardMountStatus(void) { + Service srv={0}, *srv_ptr = &srv; + Result rc=0; + if (hosversionAtLeast(3,0,0)) + rc = nsGetContentManagementInterface(&srv); + else + srv_ptr = &g_nsAppManSrv; + + if (R_SUCCEEDED(rc)) rc = _nsCmdNoIO(srv_ptr, 43); + + serviceClose(&srv); + return rc; +} + +Result nsGetTotalSpaceSize(NcmStorageId storage_id, s64 *size) { + Service srv={0}, *srv_ptr = &srv; + Result rc=0; + if (hosversionAtLeast(3,0,0)) + rc = nsGetContentManagementInterface(&srv); + else + srv_ptr = &g_nsAppManSrv; + + if (R_SUCCEEDED(rc)) rc = _nsCmdInU64OutU64(srv_ptr, storage_id, (u64*)size, 47); + + serviceClose(&srv); + return rc; +} + +Result nsGetFreeSpaceSize(NcmStorageId storage_id, s64 *size) { + Service srv={0}, *srv_ptr = &srv; + Result rc=0; + if (hosversionAtLeast(3,0,0)) + rc = nsGetContentManagementInterface(&srv); + else + srv_ptr = &g_nsAppManSrv; + + if (R_SUCCEEDED(rc)) rc = _nsCmdInU64OutU64(srv_ptr, storage_id, (u64*)size, 48); + + serviceClose(&srv); + return rc; +} + +Result nsCountApplicationContentMeta(u64 application_id, s32 *out) { + if (hosversionBefore(2,0,0)) + return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); + + Service srv={0}, *srv_ptr = &srv; + Result rc=0; + if (hosversionAtLeast(3,0,0)) + rc = nsGetContentManagementInterface(&srv); + else + srv_ptr = &g_nsAppManSrv; + + if (R_SUCCEEDED(rc)) rc = serviceDispatchInOut(srv_ptr, 600, application_id, *out); + + serviceClose(&srv); + return rc; +} + +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); + + Service srv={0}, *srv_ptr = &srv; + Result rc=0; + if (hosversionAtLeast(3,0,0)) + rc = nsGetContentManagementInterface(&srv); + else + srv_ptr = &g_nsAppManSrv; + + const struct { + s32 index; + u32 pad; + u64 application_id; + } in = { index, 0, application_id }; + + if (R_SUCCEEDED(rc)) rc = serviceDispatchInOut(srv_ptr, 601, in, *out_entrycount, + .buffer_attrs = { SfBufferAttr_HipcMapAlias | SfBufferAttr_Out }, + .buffers = { { list, count*sizeof(NsApplicationContentMetaStatus) } }, + ); + + serviceClose(&srv); + return rc; +} + +Result nsIsAnyApplicationRunning(bool *out) { + if (hosversionBefore(3,0,0)) + return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); + + Service srv={0}; + Result rc = nsGetContentManagementInterface(&srv); + + if (R_SUCCEEDED(rc)) rc = _nsCmdNoInOutBool(&srv, out, 607); + + serviceClose(&srv); + return rc; +} + // IRequestServerStopper void nsRequestServerStopperClose(NsRequestServerStopper *r) {