From 01199f43b2580294aaba18bcb4167c9e95f9a44d Mon Sep 17 00:00:00 2001 From: HookedBehemoth Date: Wed, 8 Jan 2020 00:40:26 +0100 Subject: [PATCH] update --- nx/include/switch/services/caps.h | 7 +- nx/include/switch/services/capsa.h | 21 ++-- nx/source/services/capsa.c | 148 +++++++++++++++++------------ 3 files changed, 105 insertions(+), 71 deletions(-) diff --git a/nx/include/switch/services/caps.h b/nx/include/switch/services/caps.h index fcfebf9c..e0a1fd91 100644 --- a/nx/include/switch/services/caps.h +++ b/nx/include/switch/services/caps.h @@ -84,14 +84,14 @@ typedef struct { u64 application_id; ///< ApplicationId CapsAlbumFileDateTime datetime; ///< \ref CapsAlbumFileDateTime u8 storage; ///< AlbumStorage - u8 contentsType; ///< FileContentsType + u8 content; ///< FileContentsType u32 pad_x12; ///< Set to 0 by official software u16 pad_x16; ///< Set to 0 by official software -} CapsAlbumFileId; +} PACKED CapsAlbumFileId; /// AlbumEntry typedef struct { - u8 unk_x0[0x8]; ///< Unknown. + u64 size; ///< Unknown. CapsAlbumFileId file_id; ///< \ref CapsAlbumFileId } CapsAlbumEntry; @@ -143,6 +143,7 @@ typedef struct { s64 size; u32 flags; u8 file_contents; + u8 pad_x15[0x3]; } CapsAlbumContentsUsage; typedef struct { diff --git a/nx/include/switch/services/capsa.h b/nx/include/switch/services/capsa.h index 1e782d31..bf7037e7 100644 --- a/nx/include/switch/services/capsa.h +++ b/nx/include/switch/services/capsa.h @@ -17,27 +17,30 @@ void capsaExit(void); /// Gets the Service for caps:a. Service* capsaGetServiceSession(void); -// 0-8 Result capsaGetAlbumFileCount(CapsAlbumStorage storage, u64* count); -Result capsaGetAlbumFileList(CapsAlbumStorage storage, u64* count, CapsApplicationAlbumEntry* buffer, u64 size); -Result capsaLoadAlbumFile(CapsAlbumFileId file_id, u64 *out_size, void* jpeg_buffer, u64 jpeg_buffer_size); +Result capsaGetAlbumFileList(CapsAlbumStorage storage, u64* count, CapsAlbumEntry* buffer, u64 size); +Result capsaLoadAlbumFile(CapsAlbumFileId file_id, u64 *out_size, void* workbuf, u64 workbuf_size); Result capsaDeleteAlbumFile(CapsAlbumFileId file_id); Result capsaStorageCopyAlbumFile(CapsAlbumFileId file_id, CapsAlbumStorage dst_storage); Result capsaIsAlbumMounted(CapsAlbumStorage storage, bool* is_mounted); Result capsaGetAlbumUsage(CapsAlbumStorage storage, CapsAlbumUsage2 *out); Result capsaGetAlbumFileSize(CapsAlbumFileId file_id, u64* size); -Result capsaLoadAlbumFileThumbnail(CapsAlbumFileId file_id, u64 *out_size, void* jpeg_buffer, u64 jpeg_buffer_size); -// 15-18 +Result capsaLoadAlbumFileThumbnail(CapsAlbumFileId file_id, u64 *out_size, void* workbuf, u64 workbuf_size); +/// Only available on [2.0.0+]. +Result capsaLoadAlbumScreenShotImage(u64* width, u64* height, CapsAlbumFileId file_id, void* workbuf, u64 workbuf_size, void* rawbuf, u64 rawbuf_size); +Result capsaLoadAlbumScreenShotThumbnailImage(u64* width, u64* height, CapsAlbumFileId file_id, void* workbuf, u64 workbuf_size, void* rawbuf, u64 rawbuf_size); +/// Only available on [3.0.0+]. +Result capsaLoadAlbumScreenShotImageEx(u64* width, u64* height, CapsAlbumFileId file_id, CapsScreenShotDecodeOption opts, void* workbuf, u64 workbuf_size, void* rawbuf, u64 rawbuf_size); +Result capsaLoadAlbumScreenShotThumbnailImageEx(u64* width, u64* height, CapsAlbumFileId file_id, CapsScreenShotDecodeOption opts, void* workbuf, u64 workbuf_size, void* rawbuf, u64 rawbuf_size); +/// Only available on [4.0.0+]. Result capsaGetAlbumUsage3(CapsAlbumStorage storage, CapsAlbumUsage3 *out); Result capsaGetAlbumMountResult(CapsAlbumStorage storage); Result capsaGetAlbumUsage16(CapsAlbumStorage storage, CapsAlbumUsage16 *out); Result capsaGetAutoSavingStorage(CapsAlbumStorage* storage); Result capsaGetRequiredStorageSpaceSizeToCopyAll(CapsAlbumStorage dst_storage, CapsAlbumStorage src_storage, u64* out); - -Result capsaLoadAlbumScreenShotThumbnailImage(u64* width, u64* height, CapsAlbumFileId file_id, void* jpeg_buffer, u64 jpeg_buffer_size, void* buffer, u64 buffer_size); -Result capsaLoadAlbumScreenShotThumbnailImageEx(u64* width, u64* height, CapsAlbumFileId file_id, void* jpeg_buffer, u64 jpeg_buffer_size, void* buffer, u64 buffer_size); -Result capsaLoadAlbumScreenShotThumbnailImageEx1(CapsAlbumFileId file_id, void* jpeg_buffer, u64 jpeg_buffer_size, void* buffer, u64 buffer_size, void* out, u64 out_size); +/// Only available on [4.0.0+]. +Result capsaLoadAlbumScreenShotThumbnailImageEx1(CapsAlbumFileId file_id, CapsScreenShotDecodeOption opts, void* workbuf, u64 workbuf_size, void* rawbuf, u64 rawbuf_size, void* out, u64 out_size); Result capsaForceAlbumUnmounted(CapsAlbumStorage storage); Result capsaResetAlbumMountStatus(CapsAlbumStorage storage); diff --git a/nx/source/services/capsa.c b/nx/source/services/capsa.c index f6ff2e6c..24cdcd56 100644 --- a/nx/source/services/capsa.c +++ b/nx/source/services/capsa.c @@ -22,21 +22,27 @@ Service* capsaGetServiceSession(void) { return &g_capsaSrv; } -Result capsaGetAlbumFileCount(CapsAlbumStorage storage, u64* count) { - return serviceDispatchInOut(&g_capsaSrv, 0, storage, *count); +static Result _capsaCmdInU8NoOut(Service* srv, u8 inval, u32 cmd_id) { + return serviceDispatchIn(srv, cmd_id, inval); } -Result capsaGetAlbumFileList(CapsAlbumStorage storage, u64* count, CapsApplicationAlbumEntry* buffer, u64 buffer_size) { - return serviceDispatchInOut(&g_capsaSrv, 1, storage, *count, +Result capsaGetAlbumFileCount(CapsAlbumStorage storage, u64* count) { + u8 inval = storage; + return serviceDispatchInOut(&g_capsaSrv, 0, inval, *count); +} + +Result capsaGetAlbumFileList(CapsAlbumStorage storage, u64* count, CapsAlbumEntry* buffer, u64 buffer_size) { + u8 inval = storage; + return serviceDispatchInOut(&g_capsaSrv, 1, inval, *count, .buffer_attrs = { SfBufferAttr_HipcMapAlias | SfBufferAttr_Out }, .buffers = { { buffer, buffer_size } }, ); } -Result capsaLoadAlbumFile(CapsAlbumFileId file_id, u64 *out_size, void* jpeg_buffer, u64 jpeg_buffer_size) { +Result capsaLoadAlbumFile(CapsAlbumFileId file_id, u64 *out_size, void* workbuf, u64 workbuf_size) { return serviceDispatchInOut(&g_capsaSrv, 2, file_id, *out_size, .buffer_attrs = { SfBufferAttr_HipcMapAlias | SfBufferAttr_Out }, - .buffers = { { jpeg_buffer, jpeg_buffer_size } }, + .buffers = { { workbuf, workbuf_size } }, ); } @@ -45,116 +51,140 @@ Result capsaDeleteAlbumFile(CapsAlbumFileId file_id) { } Result capsaStorageCopyAlbumFile(CapsAlbumFileId file_id, CapsAlbumStorage dst_storage) { - return serviceDispatchIn(&g_capsaSrv, 4, dst_storage); + struct { + u8 storage; + u8 pad_x1[0x7]; + CapsAlbumFileId file_id; + } in = { dst_storage, {0}, file_id }; + return serviceDispatchIn(&g_capsaSrv, 4, in); } Result capsaIsAlbumMounted(CapsAlbumStorage storage, bool* is_mounted) { - return serviceDispatchInOut(&g_capsaSrv, 5, storage, *is_mounted); + u8 inval = storage; + return serviceDispatchInOut(&g_capsaSrv, 5, inval, *is_mounted); } Result capsaGetAlbumUsage(CapsAlbumStorage storage, CapsAlbumUsage2 *out) { - return serviceDispatchInOut(&g_capsaSrv, 6, storage, *out); + u8 inval = storage; + return serviceDispatchInOut(&g_capsaSrv, 6, inval, *out); } Result capsaGetAlbumFileSize(CapsAlbumFileId file_id, u64* size) { return serviceDispatchInOut(&g_capsaSrv, 7, file_id, *size); } -Result capsaLoadAlbumFileThumbnail(CapsAlbumFileId file_id, u64 *out_size, void* jpeg_buffer, u64 jpeg_buffer_size) { +Result capsaLoadAlbumFileThumbnail(CapsAlbumFileId file_id, u64 *out_size, void* workbuf, u64 workbuf_size) { return serviceDispatchInOut(&g_capsaSrv, 8, file_id, *out_size, .buffer_attrs = { SfBufferAttr_HipcMapAlias | SfBufferAttr_Out }, - .buffers = { { jpeg_buffer, jpeg_buffer_size } }, + .buffers = { { workbuf, workbuf_size } }, ); } +static Result _capsaLoadAlbumScreenshot(u64* width, u64* height, CapsAlbumFileId file_id, void* workbuf, u64 workbuf_size, void* rawbuf, u64 rawbuf_size, u32 cmd_id) { + if (hosversionBefore(2,0,0)) + return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); + struct { + u64 width; + u64 height; + } out; + Result rc = serviceDispatchInOut(&g_capsaSrv, cmd_id, file_id, out, + .buffer_attrs = { SfBufferAttr_HipcMapAlias | SfBufferAttr_Out | SfBufferAttr_HipcMapTransferAllowsNonSecure, SfBufferAttr_HipcMapAlias | SfBufferAttr_Out }, + .buffers = { { rawbuf, rawbuf_size }, { workbuf, workbuf_size } }, + ); + *width = out.width; + *height = out.height; + return rc; +} + +Result capsaLoadAlbumScreenShotImage(u64* width, u64* height, CapsAlbumFileId file_id, void* workbuf, u64 workbuf_size, void* rawbuf, u64 rawbuf_size) { + return _capsaLoadAlbumScreenshot(width, height, file_id, workbuf, workbuf_size, rawbuf, rawbuf_size, 9); +} + +Result capsaLoadAlbumScreenShotThumbnailImage(u64* width, u64* height, CapsAlbumFileId file_id, void* workbuf, u64 workbuf_size, void* rawbuf, u64 rawbuf_size) { + return _capsaLoadAlbumScreenshot(width, height, file_id, workbuf, workbuf_size, rawbuf, rawbuf_size, 10); +} + +static Result _capsaLoadAlbumScreenshotEx(u64* width, u64* height, CapsAlbumFileId file_id, CapsScreenShotDecodeOption opts, void* workbuf, u64 workbuf_size, void* rawbuf, u64 rawbuf_size, u32 cmd_id) { + if (hosversionBefore(3,0,0)) + return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); + struct { + CapsAlbumFileId file_id; + CapsScreenShotDecodeOption opts; + } in = { file_id, opts }; + struct { + u64 width; + u64 height; + } out; + Result rc = serviceDispatchInOut(&g_capsaSrv, cmd_id, in, out, + .buffer_attrs = { SfBufferAttr_HipcMapAlias | SfBufferAttr_Out | SfBufferAttr_HipcMapTransferAllowsNonSecure, SfBufferAttr_HipcMapAlias | SfBufferAttr_Out }, + .buffers = { { rawbuf, rawbuf_size }, { workbuf, workbuf_size } }, + ); + *width = out.width; + *height = out.height; + return rc; +} + +Result capsaLoadAlbumScreenShotImageEx(u64* width, u64* height, CapsAlbumFileId file_id, CapsScreenShotDecodeOption opts, void* workbuf, u64 workbuf_size, void* rawbuf, u64 rawbuf_size) { + return _capsaLoadAlbumScreenshotEx(width, height, file_id, opts, workbuf, workbuf_size, rawbuf, rawbuf_size, 12); +} + +Result capsaLoadAlbumScreenShotThumbnailImageEx(u64* width, u64* height, CapsAlbumFileId file_id, CapsScreenShotDecodeOption opts, void* workbuf, u64 workbuf_size, void* rawbuf, u64 rawbuf_size) { + return _capsaLoadAlbumScreenshotEx(width, height, file_id, opts, workbuf, workbuf_size, rawbuf, rawbuf_size, 13); +} + Result capsaGetAlbumUsage3(CapsAlbumStorage storage, CapsAlbumUsage3 *out) { if (hosversionBefore(4,0,0)) return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); - return serviceDispatchInOut(&g_capsaSrv, 15, storage, *out); + u8 inval = storage; + return serviceDispatchInOut(&g_capsaSrv, 15, inval, *out); } Result capsaGetAlbumMountResult(CapsAlbumStorage storage) { if (hosversionBefore(4,0,0)) return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); - return serviceDispatchIn(&g_capsaSrv, 17, storage); + return _capsaCmdInU8NoOut(&g_capsaSrv, storage, 16); } Result capsaGetAlbumUsage16(CapsAlbumStorage storage, CapsAlbumUsage16 *out) { if (hosversionBefore(4,0,0)) return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); - return serviceDispatchInOut(&g_capsaSrv, 17, storage, *out); + u8 inval = storage; + return serviceDispatchInOut(&g_capsaSrv, 17, inval, *out); } - Result capsaGetAutoSavingStorage(CapsAlbumStorage* storage) { return serviceDispatchOut(&g_capsaSrv, 401, *storage); } Result capsaGetRequiredStorageSpaceSizeToCopyAll(CapsAlbumStorage dst_storage, CapsAlbumStorage src_storage, u64* out) { struct { - CapsAlbumStorage dest; - CapsAlbumStorage src; + u8 dest; + u8 src; } in = { dst_storage, src_storage }; return serviceDispatchInOut(&g_capsaSrv, 501, in, *out); } -Result capsaLoadAlbumScreenShotThumbnailImage(u64* width, u64* height, CapsAlbumFileId file_id, void* jpeg_buffer, u64 jpeg_buffer_size, void* buffer, u64 buffer_size) { - if (hosversionBefore(2,0,0)) - return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); - struct { - u64 width; - u64 height; - } out; - Result rc = serviceDispatchInOut(&g_capsaSrv, 10, file_id, out, - .buffer_attrs = { SfBufferAttr_HipcMapAlias | SfBufferAttr_Out | SfBufferAttr_HipcMapTransferAllowsNonSecure, SfBufferAttr_HipcMapAlias | SfBufferAttr_Out }, - .buffers = { { buffer, buffer_size }, { jpeg_buffer, jpeg_buffer_size } }, - ); - *width = out.width; - *height = out.height; - return rc; -} - -Result capsaLoadAlbumScreenShotThumbnailImageEx(u64* width, u64* height, CapsAlbumFileId file_id, void* jpeg_buffer, u64 jpeg_buffer_size, void* buffer, u64 buffer_size) { - if (hosversionBefore(3,0,0)) - return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); - struct { - CapsAlbumFileId file_id; - CapsScreenShotDecodeOption opts; - } in = { file_id, {{0}} }; - struct { - u64 width; - u64 height; - } out; - Result rc = serviceDispatchInOut(&g_capsaSrv, 13, in, out, - .buffer_attrs = { SfBufferAttr_HipcMapAlias | SfBufferAttr_Out | SfBufferAttr_HipcMapTransferAllowsNonSecure, SfBufferAttr_HipcMapAlias | SfBufferAttr_Out }, - .buffers = { { buffer, buffer_size }, { jpeg_buffer, jpeg_buffer_size } }, - ); - *width = out.width; - *height = out.height; - return rc; -} - -Result capsaLoadAlbumScreenShotThumbnailImageEx1(CapsAlbumFileId file_id, void* jpeg_buffer, u64 jpeg_buffer_size, void* buffer, u64 buffer_size, void* out, u64 out_size) { +Result capsaLoadAlbumScreenShotThumbnailImageEx1(CapsAlbumFileId file_id, CapsScreenShotDecodeOption opts, void* work_buffer, u64 work_buffer_size, void* raw_buffer, u64 raw_buffer_size, void* out, u64 out_size) { if (hosversionBefore(4,0,0)) return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer); struct { CapsAlbumFileId file_id; CapsScreenShotDecodeOption opts; - } in = { file_id, {{0}} }; + } in = { file_id, opts }; return serviceDispatchIn(&g_capsaSrv, 1003, in, .buffer_attrs = { SfBufferAttr_HipcMapAlias | SfBufferAttr_Out | SfBufferAttr_FixedSize, SfBufferAttr_HipcMapAlias | SfBufferAttr_Out | SfBufferAttr_HipcMapTransferAllowsNonSecure, SfBufferAttr_HipcMapAlias | SfBufferAttr_Out }, - .buffers = { { out, out_size }, { buffer, buffer_size }, { jpeg_buffer, jpeg_buffer_size } }, + .buffers = { { out, out_size }, { raw_buffer, raw_buffer_size }, { work_buffer, work_buffer_size } }, ); } Result capsaForceAlbumUnmounted(CapsAlbumStorage storage) { - return serviceDispatchIn(&g_capsaSrv, 8001, storage); + return _capsaCmdInU8NoOut(&g_capsaSrv, storage, 8001); } Result capsaResetAlbumMountStatus(CapsAlbumStorage storage) { - return serviceDispatchIn(&g_capsaSrv, 8002, storage); + return _capsaCmdInU8NoOut(&g_capsaSrv, storage, 8002); } Result capsaRefreshAlbumCache(CapsAlbumStorage storage) { - return serviceDispatchIn(&g_capsaSrv, 8011, storage); + return _capsaCmdInU8NoOut(&g_capsaSrv, storage, 8011); }