From d23427a24a598b818d8fc6ce962a03208ce960af Mon Sep 17 00:00:00 2001 From: HookedBehemoth Date: Tue, 14 Jan 2020 03:05:47 +0100 Subject: [PATCH] add more calls, add structs and add doc --- nx/include/switch/services/caps.h | 80 +++++++++++++++++------------- nx/include/switch/services/capsa.h | 64 ++++++++++++++++++++++++ nx/source/services/capsa.c | 78 ++++++++++++++++++++++++++++- 3 files changed, 187 insertions(+), 35 deletions(-) diff --git a/nx/include/switch/services/caps.h b/nx/include/switch/services/caps.h index c145fba0..5a4c3024 100644 --- a/nx/include/switch/services/caps.h +++ b/nx/include/switch/services/caps.h @@ -18,13 +18,13 @@ typedef enum { /// AlbumReportOption typedef enum { - AlbumReportOption_Disable = 0, ///< Don't display the screenshot-taken Overlay-applet notification. - AlbumReportOption_Enable = 1, ///< Display the screenshot-taken Overlay notification. + AlbumReportOption_Disable = 0, ///< Don't display the screenshot-taken Overlay-applet notification. + AlbumReportOption_Enable = 1, ///< Display the screenshot-taken Overlay notification. } AlbumReportOption; typedef enum { - CapsAlbumStorage_Nand = 0, ///< Nand - CapsAlbumStorage_Sd = 1, ///< Sd + CapsAlbumStorage_Nand = 0, ///< Nand + CapsAlbumStorage_Sd = 1, ///< Sd } CapsAlbumStorage; /// ContentType @@ -70,38 +70,38 @@ typedef struct { /// AlbumFileDateTime. This corresponds to each field in the Album entry filename, prior to the "-": "YYYYMMDDHHMMSSII". typedef struct { - u16 year; ///< Year. - u8 month; ///< Month. - u8 day; ///< Day of the month. - u8 hour; ///< Hour. - u8 minute; ///< Minute. - u8 second; ///< Second. - u8 id; ///< Unique ID for when there's multiple Album files with the same timestamp. + u16 year; ///< Year. + u8 month; ///< Month. + u8 day; ///< Day of the month. + u8 hour; ///< Hour. + u8 minute; ///< Minute. + u8 second; ///< Second. + u8 id; ///< Unique ID for when there's multiple Album files with the same timestamp. } CapsAlbumFileDateTime; /// AlbumEntryId typedef struct { - u64 application_id; ///< ApplicationId - CapsAlbumFileDateTime datetime; ///< \ref CapsAlbumFileDateTime - u8 storage; ///< \ref CapsAlbumStorage - u8 content; ///< \ref CapsAlbumFileContents - u32 pad_x12; ///< Set to 0 by official software - u16 pad_x16; ///< Set to 0 by official software + u64 application_id; ///< ApplicationId + CapsAlbumFileDateTime datetime; ///< \ref CapsAlbumFileDateTime + u8 storage; ///< \ref CapsAlbumStorage + u8 content; ///< \ref CapsAlbumFileContents + u32 pad_x12; ///< Set to 0 by official software + u16 pad_x16; ///< Set to 0 by official software } PACKED CapsAlbumFileId; /// AlbumEntry typedef struct { - u64 size; ///< Size. - CapsAlbumFileId file_id; ///< \ref CapsAlbumFileId + u64 size; ///< Size. + CapsAlbumFileId file_id; ///< \ref CapsAlbumFileId } CapsAlbumEntry; /// ApplicationAlbumEntry typedef struct { union { - u8 data[0x20]; ///< Data. + u8 data[0x20]; ///< Data. struct { - u8 unk_x0[0x20]; ///< Unknown. + u8 unk_x0[0x20]; ///< Unknown. } v0; ///< Pre-7.0.0 struct { @@ -115,15 +115,15 @@ typedef struct { /// ApplicationAlbumFileEntry typedef struct { - CapsApplicationAlbumEntry entry; ///< \ref CapsApplicationAlbumEntry - CapsAlbumFileDateTime datetime; ///< \ref CapsAlbumFileDateTime - u64 unk_x28; ///< Unknown. + CapsApplicationAlbumEntry entry; ///< \ref CapsApplicationAlbumEntry + CapsAlbumFileDateTime datetime; ///< \ref CapsAlbumFileDateTime + u64 unk_x28; ///< Unknown. } CapsApplicationAlbumFileEntry; /// ApplicationData typedef struct { - u8 userdata[0x400]; ///< UserData. - u32 size; ///< UserData size. + u8 userdata[0x400]; ///< UserData. + u32 size; ///< UserData size. } CapsApplicationData; /// AlbumFileContents @@ -140,25 +140,31 @@ typedef enum { } CapsAlbumContentsUsageFlag; typedef struct { - s64 count; - s64 size; - u32 flags; - u8 file_contents; - u8 pad_x15[0x3]; + s64 count; ///< Count. + s64 size; ///< Size. Used storage space. + u32 flags; ///< \ref CapsAlbumContentsUsageFlag + u8 file_contents; ///< \ref CapsAlbumFileContents + u8 pad_x15[0x3]; ///< Unused } CapsAlbumContentsUsage; typedef struct { - CapsAlbumContentsUsage usages[2]; + CapsAlbumContentsUsage usages[2]; ///< \ref CapsAlbumContentsUsage } CapsAlbumUsage2; typedef struct { - CapsAlbumContentsUsage usages[3]; + CapsAlbumContentsUsage usages[3]; ///< \ref CapsAlbumContentsUsage } CapsAlbumUsage3; typedef struct { - CapsAlbumContentsUsage usages[16]; + CapsAlbumContentsUsage usages[16]; ///< \ref CapsAlbumContentsUsage } CapsAlbumUsage16; +/// OverlayThumbnailData +typedef struct { + CapsAlbumFileId file_id; ///< \ref CapsAlbumFileId + u64 size; ///< Size. +} CapsOverlayThumbnailData; + /// UserIdList typedef struct { AccountUid uids[ACC_USER_LIST_SIZE]; ///< \ref AccountUid @@ -183,6 +189,12 @@ typedef struct { u8 unk_x50[0x400]; ///< Unused. } CapsLoadAlbumScreenShotImageOutput; +/// AlbumCache +typedef struct { + u64 count; ///< Count + u8 unk_x8[8]; ///< Unknown +} CapsAlbumCache; + /// Gets the ShimLibraryVersion. u64 capsGetShimLibraryVersion(void); diff --git a/nx/include/switch/services/capsa.h b/nx/include/switch/services/capsa.h index ce615e94..200507d7 100644 --- a/nx/include/switch/services/capsa.h +++ b/nx/include/switch/services/capsa.h @@ -169,6 +169,7 @@ Result capsaGetAlbumUsage3(CapsAlbumStorage storage, CapsAlbumUsage3 *out); /** * @brief Returns the result for a AlbumStorage mount. + * @note Only available on [4.0.0+]. * @param[in] storage \ref CapsAlbumStorage */ Result capsaGetAlbumMountResult(CapsAlbumStorage storage); @@ -181,6 +182,52 @@ Result capsaGetAlbumMountResult(CapsAlbumStorage storage); */ Result capsaGetAlbumUsage16(CapsAlbumStorage storage, CapsAlbumUsage16 *out); +/** + * @brief Returns the start and end of the Applet Id range. + * @note Only available on [6.0.0+]. + * @param[out] success Returns bool over wether the call was handled or not. + * @param[out] min Mimimum applet id. Always 0x0100000000001000 + * @param[out] max Maximum applet id. Always 0x0100000000001FFF + */ +Result capsaGetMinMaxAppletId(bool* success, u64* min, u64* max); + +/** + * @brief Gets the amount of files of the specified type at a AlbumStorage. + * @note Only available on [5.0.0+]. + * @param[in] storage \ref CapsAlbumStorage + * @param[in] contents \ref CapsAlbumFileContents + * @param[out] count Amount of files. + */ +Result capsaGetAlbumFileCountEx0(CapsAlbumStorage storage, CapsAlbumFileContents contents, u64 *count); + +/** + * @brief Gets a listing of \ref CapsAlbumEntry, where the AlbumFile's storage and type matches the input one. + * @note Only available on [5.0.0+]. + * @param[in] storage \ref CapsAlbumStorage + * @param[in] contents \ref CapsAlbumFileContents + * @param[out] count Total output entries. + * @param[out] entries Output array of \ref CapsAlbumEntry. + * @param[in] size Reserved size at entries + */ +Result capsaGetAlbumFileListEx0(CapsAlbumStorage storage, CapsAlbumFileContents contents, u64 *count, CapsAlbumEntry *entries, u64 size); + +/** + * @brief Returns the image from the last shown ScreenShot Overlay. + * @param[out] data \ref CapsOverlayThumbnailData + * @param[out] image RGBA8 image output buffer. + * @param[in] image_size Image buffer size, should be at least large enough for RGBA8 96×54. + */ +Result capsaGetLastOverlayScreenShotThumbnail(CapsOverlayThumbnailData *data, void* image, u64 image_size); + +/** + * @brief Returns the image from the last shown Movie Overlay. + * @note Only available on [4.0.0+]. + * @param[out] data \ref CapsOverlayThumbnailData + * @param[out] image RGBA8 image output buffer. + * @param[in] image_size Image buffer size, should be at least large enough for RGBA8 96×54. + */ +Result capsaGetLastOverlayMovieThumbnail(CapsOverlayThumbnailData *data, void* image, u64 image_size); + /** * @brief Gets the currently set autosaving storage. * @note Wrapper around setsysGetPrimaryAlbumStorage but defaults to NAND if SD isn't available. @@ -256,6 +303,23 @@ Result capsaResetAlbumMountStatus(CapsAlbumStorage storage); */ Result capsaRefreshAlbumCache(CapsAlbumStorage storage); +/** + * @brief Gets the AlbumCache of the specified AlbumStorage. + * @note use \ref capsaGetAlbumCacheEx instead. + * @param[in] storage \ref CapsAlbumStorage + * @param[out] cache \ref CapsAlbumCache + */ +Result capsaGetAlbumCache(CapsAlbumStorage storage, CapsAlbumCache *cache); + +/** + * @brief Gets the AlbumCache for the specified type of the specified AlbumStorage. + * @note Stubbed on [4.0.0+]. + * @param[in] storage \ref CapsAlbumStorage + * @param[in] contents \ref CapsAlbumFileContents + * @param[out] cache \ref CapsAlbumCache + */ +Result capsaGetAlbumCacheEx(CapsAlbumStorage storage, CapsAlbumFileContents contents, CapsAlbumCache *cache); + /** * @brief Opens an AlbumMovieStream. * @note This opens IAlbumAccessorSession if not previously opened, it's closed during \ref capsaExit. diff --git a/nx/source/services/capsa.c b/nx/source/services/capsa.c index 89b6ab66..e9f95c69 100644 --- a/nx/source/services/capsa.c +++ b/nx/source/services/capsa.c @@ -139,7 +139,7 @@ Result capsaLoadAlbumScreenShotThumbnailImageEx(u64 *width, u64 *height, const C } Result _capsaLoadAlbumScreenShotEx0(u64 *width, u64 *height, CapsScreenShotAttributeForApplication *attr, const CapsAlbumFileId *file_id, const CapsScreenShotDecodeOption *opts, void* image, u64 image_size, void* workbuf, u64 workbuf_size, u32 cmd_id) { - if (hosversionBefore(4,0,0)) + if (hosversionBefore(3,0,0)) return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); const struct { CapsAlbumFileId file_id; @@ -184,6 +184,68 @@ Result capsaGetAlbumUsage16(CapsAlbumStorage storage, CapsAlbumUsage16 *out) { return serviceDispatchInOut(&g_capsaSrv, 17, inval, *out); } +Result capsaGetMinMaxAppletId(bool *success, u64* min, u64* max) { + if (hosversionBefore(6,0,0)) + return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); + u64 app_ids[2]; + struct { + bool success; + u8 pad[0x3]; + } out; + Result rc = serviceDispatchOut(&g_capsaSrv, 18, out, + .buffer_attrs = { SfBufferAttr_HipcMapAlias | SfBufferAttr_Out | SfBufferAttr_HipcMapTransferAllowsNonSecure, }, + .buffers = { { app_ids, sizeof(app_ids) }, }, + ); + *min = app_ids[0]; + *max = app_ids[1]; + *success = out.success; + return rc; +} + +Result capsaGetAlbumFileCountEx0(CapsAlbumStorage storage, CapsAlbumFileContents contents, u64 *count) { + if (hosversionBefore(5,0,0)) + return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); + struct { + CapsAlbumStorage storage; + u8 pad_x1[0x7]; + CapsAlbumFileContents contents; + u8 pad_x9[0x7]; + } in = { storage, {0}, contents, {0} }; + return serviceDispatchInOut(&g_capsaSrv, 100, in, *count); +} + +Result capsaGetAlbumFileListEx0(CapsAlbumStorage storage, CapsAlbumFileContents contents, u64 *count, CapsAlbumEntry *entries, u64 size) { + if (hosversionBefore(5,0,0)) + return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); + struct { + CapsAlbumStorage storage; + u8 pad_x1[0x7]; + CapsAlbumFileContents contents; + u8 pad_x9[0x7]; + } in = { storage, {0}, contents, {0} }; + return serviceDispatchInOut(&g_capsaSrv, 101, in, *count, + .buffer_attrs = { SfBufferAttr_HipcMapAlias | SfBufferAttr_Out }, + .buffers = { { entries, size } }, + ); +} + +Result _capsaGetLastOverlayThumbnail(CapsOverlayThumbnailData *data, void* image, u64 image_size, u32 cmd_id) { + return serviceDispatchOut(&g_capsaSrv, cmd_id, *data, + .buffer_attrs = { SfBufferAttr_HipcMapAlias | SfBufferAttr_Out, }, + .buffers = { { image, image_size }, }, + ); +} + +Result capsaGetLastOverlayScreenShotThumbnail(CapsOverlayThumbnailData *data, void* image, u64 image_size) { + return _capsaGetLastOverlayThumbnail(data, image, image_size, 301); +} + +Result capsaGetLastOverlayMovieThumbnail(CapsOverlayThumbnailData *data, void* image, u64 image_size) { + if (hosversionBefore(4,0,0)) + return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); + return _capsaGetLastOverlayThumbnail(data, image, image_size, 302); +} + Result capsaGetAutoSavingStorage(CapsAlbumStorage *storage) { u8 tmpval = 0; Result rc = serviceDispatchOut(&g_capsaSrv, 401, tmpval); @@ -236,6 +298,20 @@ Result capsaRefreshAlbumCache(CapsAlbumStorage storage) { return _capsaCmdInU8NoOut(&g_capsaSrv, storage, 8011); } +Result capsaGetAlbumCache(CapsAlbumStorage storage, CapsAlbumCache *cache) { + return serviceDispatchInOut(&g_capsaSrv, 8012, storage, *cache); +} + +Result capsaGetAlbumCacheEx(CapsAlbumStorage storage, CapsAlbumFileContents contents, CapsAlbumCache *cache) { + if (hosversionBefore(4,0,0)) + return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); + struct { + u8 storage; + u8 contents; + } in = { storage, contents }; + return serviceDispatchInOut(&g_capsaSrv, 8013, in, *cache); +} + static Result _capsaOpenAccessorSession(Service *srv_out) { u64 AppletResourceUserId = 0; appletGetAppletResourceUserId(&AppletResourceUserId);