mirror of
https://github.com/switchbrew/libnx.git
synced 2025-06-21 12:32:40 +02:00
Added support for capsu. Updated caps.h. Improved docs. Added enum CapsContentType. Added structs CapsScreenShotAttributeForApplication, CapsScreenShotDecodeOption, CapsApplicationAlbumFileEntry, and CapsLoadAlbumScreenShotImageOutputForApplication. Added capsGetDefaultStartDateTime, capsGetDefaultEndDateTime, capsConvertApplicationAlbumFileEntryToApplicationAlbumEntry, and capsConvertApplicationAlbumEntryToApplicationAlbumFileEntry.
This commit is contained in:
parent
7d71d4f3a1
commit
b7311b6ab1
@ -85,6 +85,7 @@ extern "C" {
|
||||
#include "switch/services/ncm.h"
|
||||
#include "switch/services/psc.h"
|
||||
#include "switch/services/caps.h"
|
||||
#include "switch/services/capsu.h"
|
||||
#include "switch/services/capssc.h"
|
||||
#include "switch/services/capssu.h"
|
||||
#include "switch/services/nfc.h"
|
||||
|
@ -25,6 +25,13 @@ typedef enum {
|
||||
AlbumReportOption_Unknown3 = 3, ///< Unknown.
|
||||
} AlbumReportOption;
|
||||
|
||||
/// ContentType
|
||||
typedef enum {
|
||||
CapsContentType_Screenshot = 0, ///< Album screenshots.
|
||||
CapsContentType_Movie = 1, ///< Album videos.
|
||||
CapsContentType_ExtraMovie = 3, ///< Videos recorded by the current Application host title via \ref grcCreateMovieMaker.
|
||||
} CapsContentType;
|
||||
|
||||
/// ScreenShotAttribute
|
||||
typedef struct {
|
||||
u32 unk_x0; ///< Always set to 0 by official sw.
|
||||
@ -34,11 +41,36 @@ typedef struct {
|
||||
u8 unk_x10[0x30]; ///< Always set to 0 by official sw.
|
||||
} CapsScreenShotAttribute;
|
||||
|
||||
/// ScreenShotAttributeForApplication. Only unk_x0 is used by official sw.
|
||||
typedef struct {
|
||||
u32 unk_x0; ///< Unknown.
|
||||
u8 unk_x4; ///< Unknown.
|
||||
u8 unk_x5; ///< Unknown.
|
||||
u8 unk_x6; ///< Unknown.
|
||||
u8 pad; ///< Unknown.
|
||||
u32 unk_x8; ///< Unknown.
|
||||
u32 unk_xc; ///< Unknown.
|
||||
u32 unk_x10; ///< Unknown.
|
||||
u32 unk_x14; ///< Unknown.
|
||||
u32 unk_x18; ///< Unknown.
|
||||
u32 unk_x1c; ///< Unknown.
|
||||
u16 unk_x20; ///< Unknown.
|
||||
u16 unk_x22; ///< Unknown.
|
||||
u16 unk_x24; ///< Unknown.
|
||||
u16 unk_x26; ///< Unknown.
|
||||
u8 reserved[0x18]; ///< Always zero.
|
||||
} CapsScreenShotAttributeForApplication;
|
||||
|
||||
/// ScreenShotDecodeOption
|
||||
typedef struct {
|
||||
u8 unk_x0[0x20]; ///< Unknown. Set to all-zero by official sw.
|
||||
} CapsScreenShotDecodeOption;
|
||||
|
||||
/// 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.
|
||||
u8 day; ///< Day of the month.
|
||||
u8 hour; ///< Hour.
|
||||
u8 minute; ///< Minute.
|
||||
u8 second; ///< Second.
|
||||
@ -56,15 +88,35 @@ typedef struct {
|
||||
|
||||
/// AlbumEntry
|
||||
typedef struct {
|
||||
u8 unk_x0[0x8];
|
||||
CapsAlbumEntryId id;
|
||||
u8 unk_x0[0x8]; ///< Unknown.
|
||||
CapsAlbumEntryId id; ///< \ref CapsAlbumEntryId
|
||||
} CapsAlbumEntry;
|
||||
|
||||
/// ApplicationAlbumEntry
|
||||
typedef struct {
|
||||
u8 data[0x20];
|
||||
union {
|
||||
u8 data[0x20]; ///< Data.
|
||||
|
||||
struct {
|
||||
u8 unk_x0[0x20]; ///< Unknown.
|
||||
} v0; ///< Pre-7.0.0
|
||||
|
||||
struct {
|
||||
u8 unk_x0[0x8]; ///< Unknown.
|
||||
u8 unk_x8[0x8]; ///< Unknown.
|
||||
CapsAlbumFileDateTime datetime; ///< \ref CapsAlbumFileDateTime
|
||||
u8 unk_x18[0x8]; ///< Unknown.
|
||||
} v1; ///< [7.0.0+]
|
||||
};
|
||||
} CapsApplicationAlbumEntry;
|
||||
|
||||
/// ApplicationAlbumFileEntry
|
||||
typedef struct {
|
||||
CapsApplicationAlbumEntry entry; ///< \ref CapsApplicationAlbumEntry
|
||||
CapsAlbumFileDateTime datetime; ///< \ref CapsAlbumFileDateTime
|
||||
u64 unk_x28; ///< Unknown.
|
||||
} CapsApplicationAlbumFileEntry;
|
||||
|
||||
/// ApplicationData
|
||||
typedef struct {
|
||||
u8 userdata[0x400]; ///< UserData.
|
||||
@ -78,6 +130,37 @@ typedef struct {
|
||||
u8 pad[7]; ///< Padding.
|
||||
} CapsUserIdList;
|
||||
|
||||
// Get the ShimLibraryVersion.
|
||||
/// LoadAlbumScreenShotImageOutputForApplication
|
||||
typedef struct {
|
||||
s64 width; ///< Width. Official sw copies this to a s32 output field.
|
||||
s64 height; ///< Height. Official sw copies this to a s32 output field.
|
||||
CapsScreenShotAttributeForApplication attr; ///< \ref CapsScreenShotAttributeForApplication
|
||||
CapsApplicationData appdata; ///< \ref CapsApplicationData
|
||||
u8 reserved[0xac]; ///< Unused.
|
||||
} CapsLoadAlbumScreenShotImageOutputForApplication;
|
||||
|
||||
/// Gets the ShimLibraryVersion.
|
||||
u64 capsGetShimLibraryVersion(void);
|
||||
|
||||
/// Gets the default start_datetime.
|
||||
static inline CapsAlbumFileDateTime capsGetDefaultStartDateTime(void) {
|
||||
return (CapsAlbumFileDateTime){.year = 1970, .month = 1, .day = 1};
|
||||
}
|
||||
|
||||
/// Gets the default end_datetime.
|
||||
static inline CapsAlbumFileDateTime capsGetDefaultEndDateTime(void) {
|
||||
return (CapsAlbumFileDateTime){.year = 3000, .month = 1, .day = 1};
|
||||
}
|
||||
|
||||
/// Convert a \ref CapsApplicationAlbumFileEntry to \ref CapsApplicationAlbumEntry.
|
||||
static inline void capsConvertApplicationAlbumFileEntryToApplicationAlbumEntry(CapsApplicationAlbumEntry *out, CapsApplicationAlbumFileEntry *in) {
|
||||
*out = in->entry;
|
||||
}
|
||||
|
||||
/// Convert a \ref CapsApplicationAlbumEntry to \ref CapsApplicationAlbumFileEntry. Should only be used on [7.0.0+].
|
||||
static inline void capsConvertApplicationAlbumEntryToApplicationAlbumFileEntry(CapsApplicationAlbumFileEntry *out, CapsApplicationAlbumEntry *in) {
|
||||
out->entry = *in;
|
||||
out->datetime = in->v1.datetime;
|
||||
out->unk_x28 = 0;
|
||||
}
|
||||
|
||||
|
@ -11,7 +11,11 @@
|
||||
|
||||
/// Initialize caps:sc. Only available on [2.0.0+].
|
||||
Result capsscInitialize(void);
|
||||
|
||||
/// Exit caps:sc.
|
||||
void capsscExit(void);
|
||||
|
||||
/// Gets the Service for caps:sc.
|
||||
Service* capsscGetServiceSession(void);
|
||||
|
||||
/**
|
||||
|
@ -74,7 +74,7 @@ Result capssuSaveScreenShotEx0(const void* buffer, size_t size, const CapsScreen
|
||||
* @param[in] size Size of the buffer, must be at least 0x384000.
|
||||
* @param[in] attr \ref CapsScreenShotAttribute
|
||||
* @param[in] reportoption \ref AlbumReportOption
|
||||
* @parma[in] appdata \ref CapsApplicationData
|
||||
* @param[in] appdata \ref CapsApplicationData
|
||||
* @param[out] out \ref CapsApplicationAlbumEntry. Optional, can be NULL.
|
||||
*/
|
||||
Result capssuSaveScreenShotEx1(const void* buffer, size_t size, const CapsScreenShotAttribute *attr, AlbumReportOption reportoption, CapsApplicationData *appdata, CapsApplicationAlbumEntry *out);
|
||||
@ -86,7 +86,7 @@ Result capssuSaveScreenShotEx1(const void* buffer, size_t size, const CapsScreen
|
||||
* @param[in] size Size of the buffer, must be at least 0x384000.
|
||||
* @param[in] attr \ref CapsScreenShotAttribute
|
||||
* @param[in] reportoption \ref AlbumReportOption
|
||||
* @parma[in] list \ref CapsUserIdList
|
||||
* @param[in] list \ref CapsUserIdList
|
||||
* @param[out] out \ref CapsApplicationAlbumEntry. Optional, can be NULL.
|
||||
*/
|
||||
Result capssuSaveScreenShotEx2(const void* buffer, size_t size, const CapsScreenShotAttribute *attr, AlbumReportOption reportoption, CapsUserIdList *list, CapsApplicationAlbumEntry *out);
|
||||
|
172
nx/include/switch/services/capsu.h
Normal file
172
nx/include/switch/services/capsu.h
Normal file
@ -0,0 +1,172 @@
|
||||
/**
|
||||
* @file capsu.h
|
||||
* @brief Application Album (caps:u) service IPC wrapper.
|
||||
* This is only usable with AlbumFiles associated with the current Application host title.
|
||||
* @author yellows8
|
||||
* @copyright libnx Authors
|
||||
*/
|
||||
#pragma once
|
||||
#include "../types.h"
|
||||
#include "../services/sm.h"
|
||||
#include "../services/caps.h"
|
||||
|
||||
/// Initialize caps:u. Only available on [5.0.0+].
|
||||
Result capsuInitialize(void);
|
||||
|
||||
/// Exit caps:u.
|
||||
void capsuExit(void);
|
||||
|
||||
/// Gets the Service for caps:u.
|
||||
Service* capsuGetServiceSession(void);
|
||||
|
||||
/// Gets the Service for IAlbumAccessorApplicationSession, only initialized after \ref capsuOpenAlbumMovieStream (unaffected by using \ref capsuCloseAlbumMovieStream).
|
||||
Service* capsuGetServiceSession_Accessor(void);
|
||||
|
||||
/**
|
||||
* @brief Gets a listing of \ref CapsApplicationAlbumFileEntry.
|
||||
* @note On [6.0.0+] this uses GetAlbumFileList1AafeAruidDeprecated, otherwise this uses GetAlbumFileList0AafeAruidDeprecated.
|
||||
* @note This is an old version of \ref capsuGetAlbumFileList3.
|
||||
* @param[out] entries Output array of \ref CapsApplicationAlbumFileEntry.
|
||||
* @param[in] count Max size of the output array in entries.
|
||||
* @param[in] type \ref CapsContentType
|
||||
* @param[in] start_datetime Start \ref CapsAlbumFileDateTime, when NULL the default is used.
|
||||
* @param[in] end_datetime End \ref CapsAlbumFileDateTime, when NULL the default is used.
|
||||
* @param[out] total_entries Total output entries.
|
||||
*/
|
||||
Result capsuGetAlbumFileListDeprecated1(CapsApplicationAlbumFileEntry *entries, size_t count, CapsContentType type, const CapsAlbumFileDateTime *start_datetime, const CapsAlbumFileDateTime *end_datetime, u64 *total_entries);
|
||||
|
||||
/**
|
||||
* @brief Gets a listing of \ref CapsApplicationAlbumFileEntry, where the AlbumFile has an UserId which matches the input one. See also \ref capssuSaveScreenShotWithUserIds.
|
||||
* @note Only available on [6.0.0+].
|
||||
* @note This is an old version of \ref capsuGetAlbumFileList4.
|
||||
* @param[out] entries Output array of \ref CapsApplicationAlbumFileEntry.
|
||||
* @param[in] count Max size of the output array in entries.
|
||||
* @param[in] type \ref CapsContentType
|
||||
* @param[in] start_datetime Start \ref CapsAlbumFileDateTime, when NULL the default is used.
|
||||
* @param[in] end_datetime End \ref CapsAlbumFileDateTime, when NULL the default is used.
|
||||
* @param[in] userID userID.
|
||||
* @param[out] total_entries Total output entries.
|
||||
*/
|
||||
Result capsuGetAlbumFileListDeprecated2(CapsApplicationAlbumFileEntry *entries, size_t count, CapsContentType type, const CapsAlbumFileDateTime *start_datetime, const CapsAlbumFileDateTime *end_datetime, u128 userID, u64 *total_entries);
|
||||
|
||||
/**
|
||||
* @brief Gets a listing of \ref CapsApplicationAlbumEntry.
|
||||
* @note Only available on [7.0.0+], on prior sysvers use \ref capsuGetAlbumFileListDeprecated1 instead.
|
||||
* @param[out] entries Output array of \ref CapsApplicationAlbumEntry.
|
||||
* @param[in] count Max size of the output array in entries.
|
||||
* @param[in] type \ref CapsContentType
|
||||
* @param[in] start_datetime Start \ref CapsAlbumFileDateTime, when NULL the default is used.
|
||||
* @param[in] end_datetime End \ref CapsAlbumFileDateTime, when NULL the default is used.
|
||||
* @param[out] total_entries Total output entries.
|
||||
*/
|
||||
Result capsuGetAlbumFileList3(CapsApplicationAlbumEntry *entries, size_t count, CapsContentType type, const CapsAlbumFileDateTime *start_datetime, const CapsAlbumFileDateTime *end_datetime, u64 *total_entries);
|
||||
|
||||
/**
|
||||
* @brief Gets a listing of \ref CapsApplicationAlbumEntry, where the AlbumFile has an UserId which matches the input one. See also \ref capssuSaveScreenShotWithUserIds.
|
||||
* @note Only available on [7.0.0+], on prior sysvers use \ref capsuGetAlbumFileListDeprecated2 instead.
|
||||
* @param[out] entries Output array of \ref CapsApplicationAlbumEntry.
|
||||
* @param[in] count Max size of the output array in entries.
|
||||
* @param[in] type \ref CapsContentType
|
||||
* @param[in] start_datetime Start \ref CapsAlbumFileDateTime, when NULL the default is used.
|
||||
* @param[in] end_datetime End \ref CapsAlbumFileDateTime, when NULL the default is used.
|
||||
* @param[in] userID userID.
|
||||
* @param[out] total_entries Total output entries.
|
||||
*/
|
||||
Result capsuGetAlbumFileList4(CapsApplicationAlbumEntry *entries, size_t count, CapsContentType type, const CapsAlbumFileDateTime *start_datetime, const CapsAlbumFileDateTime *end_datetime, u128 userID, u64 *total_entries);
|
||||
|
||||
/**
|
||||
* @brief Deletes the specified AlbumFile.
|
||||
* @param[in] type \ref CapsContentType, must match ::CapsContentType_ExtraMovie.
|
||||
* @param[in] entry \ref CapsApplicationAlbumFileEntry
|
||||
*/
|
||||
Result capsuDeleteAlbumFile(CapsContentType type, const CapsApplicationAlbumFileEntry *entry);
|
||||
|
||||
/**
|
||||
* @brief Gets the filesize for the entire specified AlbumFile.
|
||||
* @param[in] entry \ref CapsApplicationAlbumFileEntry
|
||||
* @param[out] size Output filesize.
|
||||
*/
|
||||
Result capsuGetAlbumFileSize(const CapsApplicationAlbumFileEntry *entry, u64 *size);
|
||||
|
||||
/**
|
||||
* @brief Load the ScreenShotImage for the specified AlbumFile.
|
||||
* @param[out] width Output image width. Optional, can be NULL.
|
||||
* @param[out] height Output image height. Optional, can be NULL.
|
||||
* @param[out] attr \ref CapsScreenShotAttributeForApplication
|
||||
* @param[out] userdata Output buffer containing the UserData. Optional, can be NULL. This buffer is cleared to 0 using userdata_maxsize, prior to doing the memcpy.
|
||||
* @param[in] userdata_maxsize Max size of the userdata buffer. Optional, can be 0.
|
||||
* @param[out] userdata_size Userdata size field, clamped to max size sizeof(CapsApplicationData::userdata) when needed.
|
||||
* @param[out] image RGBA8 image output buffer.
|
||||
* @param[out] image_size Image buffer size, should be at least large enough for RGBA8 1280x720.
|
||||
* @param[out] workbuf Work buffer, cleared to 0 by the cmd before it returns.
|
||||
* @param[out] workbuf_size Work buffer size, must be at least the size of the JPEG within the AlbumFile.
|
||||
* @param[in] entry \ref CapsApplicationAlbumFileEntry
|
||||
* @param[in] option \ref CapsScreenShotDecodeOption
|
||||
*/
|
||||
Result capsuLoadAlbumScreenShotImage(s32 *width, s32 *height, CapsScreenShotAttributeForApplication *attr, void* userdata, size_t userdata_maxsize, u32 *userdata_size, void* image, size_t image_size, void* workbuf, size_t workbuf_size, const CapsApplicationAlbumFileEntry *entry, const CapsScreenShotDecodeOption *option);
|
||||
|
||||
/**
|
||||
* @brief Load the ScreenShotThumbnailImage for the specified AlbumFile.
|
||||
* @param[out] width Output image width. Optional, can be NULL.
|
||||
* @param[out] height Output image height. Optional, can be NULL.
|
||||
* @param[out] attr \ref CapsScreenShotAttributeForApplication
|
||||
* @param[out] userdata Output buffer containing the UserData. Optional, can be NULL. This buffer is cleared to 0 using userdata_maxsize, prior to doing the memcpy.
|
||||
* @param[in] userdata_maxsize Max size of the userdata buffer. Optional, can be 0.
|
||||
* @param[out] userdata_size Userdata size field, clamped to max size sizeof(CapsApplicationData::userdata) when needed.
|
||||
* @param[out] image RGBA8 image output buffer.
|
||||
* @param[out] image_size Image buffer size, should be at least large enough for RGBA8 320x180.
|
||||
* @param[out] workbuf Work buffer, cleared to 0 by the cmd before it returns.
|
||||
* @param[out] workbuf_size Work buffer size, must be at least the size of the JPEG within the AlbumFile.
|
||||
* @param[in] entry \ref CapsApplicationAlbumFileEntry
|
||||
* @param[in] option \ref CapsScreenShotDecodeOption
|
||||
*/
|
||||
Result capsuLoadAlbumScreenShotThumbnailImage(s32 *width, s32 *height, CapsScreenShotAttributeForApplication *attr, void* userdata, size_t userdata_maxsize, u32 *userdata_size, void* image, size_t image_size, void* workbuf, size_t workbuf_size, const CapsApplicationAlbumFileEntry *entry, const CapsScreenShotDecodeOption *option);
|
||||
|
||||
/**
|
||||
* @brief PrecheckToCreateContents. Official sw only uses this with ::CapsContentType_ExtraMovie.
|
||||
* @param[in] type \ref CapsContentType
|
||||
* @param[in] unk Unknown.
|
||||
*/
|
||||
Result capsuPrecheckToCreateContents(CapsContentType type, u64 unk);
|
||||
|
||||
/**
|
||||
* @brief Opens an AlbumMovieStream.
|
||||
* @note This opens IAlbumAccessorApplicationSession if not previously opened, it's closed during \ref capsuExit.
|
||||
* @note Up to 4 streams can be open at the same time. Multiple streams can be open at the same time for the same \ref CapsApplicationAlbumFileEntry.
|
||||
* @param[out] stream Stream handle.
|
||||
* @param[in] entry \ref CapsApplicationAlbumFileEntry
|
||||
*/
|
||||
Result capsuOpenAlbumMovieStream(u64 *stream, const CapsApplicationAlbumFileEntry *entry);
|
||||
|
||||
/**
|
||||
* @brief Closes an AlbumMovieStream.
|
||||
* @param[in] stream Stream handle.
|
||||
*/
|
||||
Result capsuCloseAlbumMovieStream(u64 stream);
|
||||
|
||||
/**
|
||||
* @brief Gets the data size of an AlbumMovieStream.
|
||||
* @param[in] stream Stream handle.
|
||||
* @param[out] size Size of the actual MP4, without the JPEG at the end.
|
||||
*/
|
||||
Result capsuGetAlbumMovieStreamSize(u64 stream, u64 *size);
|
||||
|
||||
/**
|
||||
* @brief Reads data from an AlbumMovieStream.
|
||||
* @note offset(+size) must not be negative. offset and size must be aligned to 0x40000-bytes.
|
||||
* @note When offset(+size) goes beyond the size from \ref capsuGetAlbumMovieStreamSize, the regions of the buffer which goes beyond that are cleared to 0, and actual_size is still set to the input size.
|
||||
* @param[in] stream Stream handle.
|
||||
* @param[in] offset Offset.
|
||||
* @param[out] Output data buffer.
|
||||
* @param[in] size Data buffer size.
|
||||
* @param[out] actual_size Actual read size.
|
||||
*/
|
||||
Result capsuReadAlbumMovieStream(u64 stream, s64 offset, void* buffer, size_t size, u64 *actual_size);
|
||||
|
||||
/**
|
||||
* @brief Gets the BrokenReason for an AlbumMovieStream.
|
||||
* @note Official sw doesn't use this.
|
||||
* @param[in] stream Stream handle.
|
||||
*/
|
||||
Result capsuGetAlbumMovieStreamBrokenReason(u64 stream);
|
||||
|
761
nx/source/services/capsu.c
Normal file
761
nx/source/services/capsu.c
Normal file
@ -0,0 +1,761 @@
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include "types.h"
|
||||
#include "result.h"
|
||||
#include "arm/atomics.h"
|
||||
#include "kernel/ipc.h"
|
||||
#include "runtime/hosversion.h"
|
||||
#include "services/applet.h"
|
||||
#include "services/caps.h"
|
||||
#include "services/capsu.h"
|
||||
#include "services/sm.h"
|
||||
|
||||
static Service g_capsuSrv;
|
||||
static Service g_capsuAccessor;
|
||||
static u64 g_capsuRefCnt;
|
||||
|
||||
static Result _capsuSetShimLibraryVersion(u64 version);
|
||||
|
||||
Result capsuInitialize(void) {
|
||||
Result rc=0;
|
||||
|
||||
atomicIncrement64(&g_capsuRefCnt);
|
||||
|
||||
if (serviceIsActive(&g_capsuSrv))
|
||||
return 0;
|
||||
|
||||
if (hosversionBefore(5,0,0))
|
||||
rc = MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
|
||||
|
||||
if (R_SUCCEEDED(rc)) rc = smGetService(&g_capsuSrv, "caps:u");
|
||||
|
||||
if (R_SUCCEEDED(rc) && hosversionAtLeast(7,0,0)) rc = _capsuSetShimLibraryVersion(capsGetShimLibraryVersion());
|
||||
|
||||
if (R_FAILED(rc)) capsuExit();
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
void capsuExit(void) {
|
||||
if (atomicDecrement64(&g_capsuRefCnt) == 0) {
|
||||
serviceClose(&g_capsuAccessor);
|
||||
serviceClose(&g_capsuSrv);
|
||||
}
|
||||
}
|
||||
|
||||
Service* capsuGetServiceSession(void) {
|
||||
return &g_capsuSrv;
|
||||
}
|
||||
|
||||
Service* capsuGetServiceSession_Accessor(void) {
|
||||
return &g_capsuAccessor;
|
||||
}
|
||||
|
||||
static Result _capsuCmdInU64(Service* srv, u64 inval, u64 cmd_id) {
|
||||
IpcCommand c;
|
||||
ipcInitialize(&c);
|
||||
|
||||
struct {
|
||||
u64 magic;
|
||||
u64 cmd_id;
|
||||
u64 inval;
|
||||
} *raw;
|
||||
|
||||
raw = serviceIpcPrepareHeader(srv, &c, sizeof(*raw));
|
||||
|
||||
raw->magic = SFCI_MAGIC;
|
||||
raw->cmd_id = cmd_id;
|
||||
raw->inval = inval;
|
||||
|
||||
Result rc = serviceIpcDispatch(srv);
|
||||
|
||||
if (R_SUCCEEDED(rc)) {
|
||||
IpcParsedCommand r;
|
||||
struct {
|
||||
u64 magic;
|
||||
u64 result;
|
||||
} *resp;
|
||||
|
||||
serviceIpcParse(srv, &r, sizeof(*resp));
|
||||
resp = r.Raw;
|
||||
|
||||
rc = resp->result;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static Result _capsuSetShimLibraryVersion(u64 version) {
|
||||
if (hosversionBefore(7,0,0))
|
||||
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
|
||||
|
||||
u64 AppletResourceUserId = 0;
|
||||
appletGetAppletResourceUserId(&AppletResourceUserId);
|
||||
|
||||
IpcCommand c;
|
||||
ipcInitialize(&c);
|
||||
|
||||
struct {
|
||||
u64 magic;
|
||||
u64 cmd_id;
|
||||
u64 version;
|
||||
u64 AppletResourceUserId;
|
||||
} *raw;
|
||||
|
||||
ipcSendPid(&c);
|
||||
|
||||
raw = serviceIpcPrepareHeader(&g_capsuSrv, &c, sizeof(*raw));
|
||||
|
||||
raw->magic = SFCI_MAGIC;
|
||||
raw->cmd_id = 32;
|
||||
raw->version = version;
|
||||
raw->AppletResourceUserId = AppletResourceUserId;
|
||||
|
||||
Result rc = serviceIpcDispatch(&g_capsuSrv);
|
||||
|
||||
if (R_SUCCEEDED(rc)) {
|
||||
IpcParsedCommand r;
|
||||
struct {
|
||||
u64 magic;
|
||||
u64 result;
|
||||
} *resp;
|
||||
|
||||
serviceIpcParse(&g_capsuSrv, &r, sizeof(*resp));
|
||||
resp = r.Raw;
|
||||
|
||||
rc = resp->result;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static Result _capsuGetAlbumFileList0AafeAruidDeprecated(void* entries, size_t entrysize, size_t count, u8 type, u64 start_timestamp, u64 end_timestamp, u64 *total_entries) {
|
||||
u64 AppletResourceUserId = 0;
|
||||
appletGetAppletResourceUserId(&AppletResourceUserId);
|
||||
|
||||
IpcCommand c;
|
||||
ipcInitialize(&c);
|
||||
|
||||
struct {
|
||||
u64 magic;
|
||||
u64 cmd_id;
|
||||
u8 type;
|
||||
u64 start_timestamp;
|
||||
u64 end_timestamp;
|
||||
u64 AppletResourceUserId;
|
||||
} *raw;
|
||||
|
||||
ipcSendPid(&c);
|
||||
ipcAddRecvBuffer(&c, entries, count*entrysize, BufferType_Normal);
|
||||
|
||||
raw = serviceIpcPrepareHeader(&g_capsuSrv, &c, sizeof(*raw));
|
||||
|
||||
raw->magic = SFCI_MAGIC;
|
||||
raw->cmd_id = 102;
|
||||
raw->type = type;
|
||||
raw->start_timestamp = start_timestamp;
|
||||
raw->end_timestamp = end_timestamp;
|
||||
raw->AppletResourceUserId = AppletResourceUserId;
|
||||
|
||||
Result rc = serviceIpcDispatch(&g_capsuSrv);
|
||||
|
||||
if (R_SUCCEEDED(rc)) {
|
||||
IpcParsedCommand r;
|
||||
struct {
|
||||
u64 magic;
|
||||
u64 result;
|
||||
u64 total_entries;
|
||||
} *resp;
|
||||
|
||||
serviceIpcParse(&g_capsuSrv, &r, sizeof(*resp));
|
||||
resp = r.Raw;
|
||||
|
||||
rc = resp->result;
|
||||
|
||||
if (R_SUCCEEDED(rc) && total_entries) *total_entries = resp->total_entries;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static Result _capsuDeleteAlbumFileByAruid(u64 cmd_id, u8 type, const CapsApplicationAlbumFileEntry *entry) {
|
||||
u64 AppletResourceUserId = 0;
|
||||
appletGetAppletResourceUserId(&AppletResourceUserId);
|
||||
|
||||
IpcCommand c;
|
||||
ipcInitialize(&c);
|
||||
|
||||
struct {
|
||||
u64 magic;
|
||||
u64 cmd_id;
|
||||
u8 type;
|
||||
CapsApplicationAlbumFileEntry entry;
|
||||
u64 AppletResourceUserId;
|
||||
} *raw;
|
||||
|
||||
ipcSendPid(&c);
|
||||
|
||||
raw = serviceIpcPrepareHeader(&g_capsuSrv, &c, sizeof(*raw));
|
||||
|
||||
raw->magic = SFCI_MAGIC;
|
||||
raw->cmd_id = cmd_id;
|
||||
raw->type = type;
|
||||
raw->entry = *entry;
|
||||
raw->AppletResourceUserId = AppletResourceUserId;
|
||||
|
||||
Result rc = serviceIpcDispatch(&g_capsuSrv);
|
||||
|
||||
if (R_SUCCEEDED(rc)) {
|
||||
IpcParsedCommand r;
|
||||
struct {
|
||||
u64 magic;
|
||||
u64 result;
|
||||
} *resp;
|
||||
|
||||
serviceIpcParse(&g_capsuSrv, &r, sizeof(*resp));
|
||||
resp = r.Raw;
|
||||
|
||||
rc = resp->result;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static Result _capsuGetAlbumFileSizeByAruid(const CapsApplicationAlbumFileEntry *entry, u64 *size) {
|
||||
u64 AppletResourceUserId = 0;
|
||||
appletGetAppletResourceUserId(&AppletResourceUserId);
|
||||
|
||||
IpcCommand c;
|
||||
ipcInitialize(&c);
|
||||
|
||||
struct {
|
||||
u64 magic;
|
||||
u64 cmd_id;
|
||||
CapsApplicationAlbumFileEntry entry;
|
||||
u64 AppletResourceUserId;
|
||||
} *raw;
|
||||
|
||||
ipcSendPid(&c);
|
||||
|
||||
raw = serviceIpcPrepareHeader(&g_capsuSrv, &c, sizeof(*raw));
|
||||
|
||||
raw->magic = SFCI_MAGIC;
|
||||
raw->cmd_id = 104;
|
||||
raw->entry = *entry;
|
||||
raw->AppletResourceUserId = AppletResourceUserId;
|
||||
|
||||
Result rc = serviceIpcDispatch(&g_capsuSrv);
|
||||
|
||||
if (R_SUCCEEDED(rc)) {
|
||||
IpcParsedCommand r;
|
||||
struct {
|
||||
u64 magic;
|
||||
u64 result;
|
||||
u64 size;
|
||||
} *resp;
|
||||
|
||||
serviceIpcParse(&g_capsuSrv, &r, sizeof(*resp));
|
||||
resp = r.Raw;
|
||||
|
||||
rc = resp->result;
|
||||
|
||||
if (R_SUCCEEDED(rc) && size) *size = resp->size;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static Result _capsuPrecheckToCreateContentsByAruid(u8 type, u64 unk) {
|
||||
u64 AppletResourceUserId = 0;
|
||||
appletGetAppletResourceUserId(&AppletResourceUserId);
|
||||
|
||||
IpcCommand c;
|
||||
ipcInitialize(&c);
|
||||
|
||||
struct {
|
||||
u64 magic;
|
||||
u64 cmd_id;
|
||||
u8 type;
|
||||
u64 unk;
|
||||
u64 AppletResourceUserId;
|
||||
} *raw;
|
||||
|
||||
ipcSendPid(&c);
|
||||
|
||||
raw = serviceIpcPrepareHeader(&g_capsuSrv, &c, sizeof(*raw));
|
||||
|
||||
raw->magic = SFCI_MAGIC;
|
||||
raw->cmd_id = 130;
|
||||
raw->type = type;
|
||||
raw->unk = unk;
|
||||
raw->AppletResourceUserId = AppletResourceUserId;
|
||||
|
||||
Result rc = serviceIpcDispatch(&g_capsuSrv);
|
||||
|
||||
if (R_SUCCEEDED(rc)) {
|
||||
IpcParsedCommand r;
|
||||
struct {
|
||||
u64 magic;
|
||||
u64 result;
|
||||
} *resp;
|
||||
|
||||
serviceIpcParse(&g_capsuSrv, &r, sizeof(*resp));
|
||||
resp = r.Raw;
|
||||
|
||||
rc = resp->result;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static Result _capsuLoadAlbumScreenShotImageByAruid(u64 cmd_id, CapsLoadAlbumScreenShotImageOutputForApplication *out, void* image, size_t image_size, void* workbuf, size_t workbuf_size, const CapsApplicationAlbumFileEntry *entry, const CapsScreenShotDecodeOption *option) {
|
||||
u64 AppletResourceUserId = 0;
|
||||
appletGetAppletResourceUserId(&AppletResourceUserId);
|
||||
|
||||
IpcCommand c;
|
||||
ipcInitialize(&c);
|
||||
|
||||
struct {
|
||||
u64 magic;
|
||||
u64 cmd_id;
|
||||
CapsApplicationAlbumFileEntry entry;
|
||||
CapsScreenShotDecodeOption option;
|
||||
u64 AppletResourceUserId;
|
||||
} *raw;
|
||||
|
||||
ipcSendPid(&c);
|
||||
ipcAddRecvBuffer(&c, out, sizeof(*out), BufferType_Normal);
|
||||
ipcAddRecvBuffer(&c, image, image_size, BufferType_Type1);
|
||||
ipcAddRecvBuffer(&c, workbuf, workbuf_size, BufferType_Normal);
|
||||
|
||||
raw = serviceIpcPrepareHeader(&g_capsuSrv, &c, sizeof(*raw));
|
||||
|
||||
raw->magic = SFCI_MAGIC;
|
||||
raw->cmd_id = cmd_id;
|
||||
raw->entry = *entry;
|
||||
raw->option = *option;
|
||||
raw->AppletResourceUserId = AppletResourceUserId;
|
||||
|
||||
Result rc = serviceIpcDispatch(&g_capsuSrv);
|
||||
|
||||
if (R_SUCCEEDED(rc)) {
|
||||
IpcParsedCommand r;
|
||||
struct {
|
||||
u64 magic;
|
||||
u64 result;
|
||||
} *resp;
|
||||
|
||||
serviceIpcParse(&g_capsuSrv, &r, sizeof(*resp));
|
||||
resp = r.Raw;
|
||||
|
||||
rc = resp->result;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static Result _capsuGetAlbumFileListAaeAruid(u64 cmd_id, void* entries, size_t entrysize, size_t count, u8 type, const CapsAlbumFileDateTime *start_datetime, const CapsAlbumFileDateTime *end_datetime, u64 *total_entries) {
|
||||
u64 AppletResourceUserId = 0;
|
||||
appletGetAppletResourceUserId(&AppletResourceUserId);
|
||||
|
||||
IpcCommand c;
|
||||
ipcInitialize(&c);
|
||||
|
||||
struct {
|
||||
u64 magic;
|
||||
u64 cmd_id;
|
||||
u8 type;
|
||||
CapsAlbumFileDateTime start_datetime;
|
||||
CapsAlbumFileDateTime end_datetime;
|
||||
u64 AppletResourceUserId;
|
||||
} *raw;
|
||||
|
||||
ipcSendPid(&c);
|
||||
ipcAddRecvBuffer(&c, entries, count*entrysize, BufferType_Normal);
|
||||
|
||||
raw = serviceIpcPrepareHeader(&g_capsuSrv, &c, sizeof(*raw));
|
||||
|
||||
raw->magic = SFCI_MAGIC;
|
||||
raw->cmd_id = cmd_id;
|
||||
raw->type = type;
|
||||
raw->start_datetime = *start_datetime;
|
||||
raw->end_datetime = *end_datetime;
|
||||
raw->AppletResourceUserId = AppletResourceUserId;
|
||||
|
||||
Result rc = serviceIpcDispatch(&g_capsuSrv);
|
||||
|
||||
if (R_SUCCEEDED(rc)) {
|
||||
IpcParsedCommand r;
|
||||
struct {
|
||||
u64 magic;
|
||||
u64 result;
|
||||
u64 total_entries;
|
||||
} *resp;
|
||||
|
||||
serviceIpcParse(&g_capsuSrv, &r, sizeof(*resp));
|
||||
resp = r.Raw;
|
||||
|
||||
rc = resp->result;
|
||||
|
||||
if (R_SUCCEEDED(rc) && total_entries) *total_entries = resp->total_entries;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static Result _capsuGetAlbumFileListAaeUidAruid(u64 cmd_id, void* entries, size_t entrysize, size_t count, u8 type, const CapsAlbumFileDateTime *start_datetime, const CapsAlbumFileDateTime *end_datetime, u128 userID, u64 *total_entries) {
|
||||
u64 AppletResourceUserId = 0;
|
||||
appletGetAppletResourceUserId(&AppletResourceUserId);
|
||||
|
||||
IpcCommand c;
|
||||
ipcInitialize(&c);
|
||||
|
||||
struct {
|
||||
u64 magic;
|
||||
u64 cmd_id;
|
||||
u8 type;
|
||||
CapsAlbumFileDateTime start_datetime;
|
||||
CapsAlbumFileDateTime end_datetime;
|
||||
u8 pad[6];
|
||||
union { u128 userID; } PACKED;
|
||||
u64 AppletResourceUserId;
|
||||
} *raw;
|
||||
|
||||
ipcSendPid(&c);
|
||||
ipcAddRecvBuffer(&c, entries, count*entrysize, BufferType_Normal);
|
||||
|
||||
raw = serviceIpcPrepareHeader(&g_capsuSrv, &c, sizeof(*raw));
|
||||
|
||||
raw->magic = SFCI_MAGIC;
|
||||
raw->cmd_id = cmd_id;
|
||||
raw->type = type;
|
||||
raw->start_datetime = *start_datetime;
|
||||
raw->end_datetime = *end_datetime;
|
||||
raw->userID = userID;
|
||||
raw->AppletResourceUserId = AppletResourceUserId;
|
||||
|
||||
Result rc = serviceIpcDispatch(&g_capsuSrv);
|
||||
|
||||
if (R_SUCCEEDED(rc)) {
|
||||
IpcParsedCommand r;
|
||||
struct {
|
||||
u64 magic;
|
||||
u64 result;
|
||||
u64 total_entries;
|
||||
} *resp;
|
||||
|
||||
serviceIpcParse(&g_capsuSrv, &r, sizeof(*resp));
|
||||
resp = r.Raw;
|
||||
|
||||
rc = resp->result;
|
||||
|
||||
if (R_SUCCEEDED(rc) && total_entries) *total_entries = resp->total_entries;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static Result _capsuOpenAccessorSessionForApplication(Service* srv_out, const CapsApplicationAlbumFileEntry *entry) {
|
||||
u64 AppletResourceUserId = 0;
|
||||
appletGetAppletResourceUserId(&AppletResourceUserId);
|
||||
|
||||
IpcCommand c;
|
||||
ipcInitialize(&c);
|
||||
|
||||
struct {
|
||||
u64 magic;
|
||||
u64 cmd_id;
|
||||
CapsApplicationAlbumFileEntry entry;
|
||||
u64 AppletResourceUserId;
|
||||
} *raw;
|
||||
|
||||
ipcSendPid(&c);
|
||||
|
||||
raw = serviceIpcPrepareHeader(&g_capsuSrv, &c, sizeof(*raw));
|
||||
|
||||
raw->magic = SFCI_MAGIC;
|
||||
raw->cmd_id = 60002;
|
||||
raw->entry = *entry;
|
||||
raw->AppletResourceUserId = AppletResourceUserId;
|
||||
|
||||
Result rc = serviceIpcDispatch(&g_capsuSrv);
|
||||
|
||||
if (R_SUCCEEDED(rc)) {
|
||||
IpcParsedCommand r;
|
||||
struct {
|
||||
u64 magic;
|
||||
u64 result;
|
||||
} *resp;
|
||||
|
||||
serviceIpcParse(&g_capsuSrv, &r, sizeof(*resp));
|
||||
resp = r.Raw;
|
||||
|
||||
rc = resp->result;
|
||||
|
||||
if (R_SUCCEEDED(rc) && srv_out) {
|
||||
serviceCreateSubservice(srv_out, &g_capsuSrv, &r, 0);
|
||||
}
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static Result _capsuOpenAlbumMovieReadStream(u64 *stream, const CapsApplicationAlbumFileEntry *entry) {
|
||||
u64 AppletResourceUserId = 0;
|
||||
appletGetAppletResourceUserId(&AppletResourceUserId);
|
||||
|
||||
IpcCommand c;
|
||||
ipcInitialize(&c);
|
||||
|
||||
struct {
|
||||
u64 magic;
|
||||
u64 cmd_id;
|
||||
CapsApplicationAlbumFileEntry entry;
|
||||
u64 AppletResourceUserId;
|
||||
} *raw;
|
||||
|
||||
ipcSendPid(&c);
|
||||
|
||||
raw = serviceIpcPrepareHeader(&g_capsuAccessor, &c, sizeof(*raw));
|
||||
|
||||
raw->magic = SFCI_MAGIC;
|
||||
raw->cmd_id = 2001;
|
||||
raw->entry = *entry;
|
||||
raw->AppletResourceUserId = AppletResourceUserId;
|
||||
|
||||
Result rc = serviceIpcDispatch(&g_capsuAccessor);
|
||||
|
||||
if (R_SUCCEEDED(rc)) {
|
||||
IpcParsedCommand r;
|
||||
struct {
|
||||
u64 magic;
|
||||
u64 result;
|
||||
u64 stream;
|
||||
} *resp;
|
||||
|
||||
serviceIpcParse(&g_capsuAccessor, &r, sizeof(*resp));
|
||||
resp = r.Raw;
|
||||
|
||||
rc = resp->result;
|
||||
|
||||
if (R_SUCCEEDED(rc) && stream) *stream = resp->stream;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static Result _capsuGetAlbumMovieReadStreamMovieDataSize(u64 stream, u64 *size) {
|
||||
IpcCommand c;
|
||||
ipcInitialize(&c);
|
||||
|
||||
struct {
|
||||
u64 magic;
|
||||
u64 cmd_id;
|
||||
u64 stream;
|
||||
} *raw;
|
||||
|
||||
raw = serviceIpcPrepareHeader(&g_capsuAccessor, &c, sizeof(*raw));
|
||||
|
||||
raw->magic = SFCI_MAGIC;
|
||||
raw->cmd_id = 2003;
|
||||
raw->stream = stream;
|
||||
|
||||
Result rc = serviceIpcDispatch(&g_capsuAccessor);
|
||||
|
||||
if (R_SUCCEEDED(rc)) {
|
||||
IpcParsedCommand r;
|
||||
struct {
|
||||
u64 magic;
|
||||
u64 result;
|
||||
u64 size;
|
||||
} *resp;
|
||||
|
||||
serviceIpcParse(&g_capsuAccessor, &r, sizeof(*resp));
|
||||
resp = r.Raw;
|
||||
|
||||
rc = resp->result;
|
||||
|
||||
if (R_SUCCEEDED(rc) && size) *size = resp->size;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static Result _capsuReadMovieDataFromAlbumMovieReadStream(u64 stream, s64 offset, void* buffer, size_t size, u64 *actual_size) {
|
||||
IpcCommand c;
|
||||
ipcInitialize(&c);
|
||||
|
||||
struct {
|
||||
u64 magic;
|
||||
u64 cmd_id;
|
||||
u64 stream;
|
||||
s64 offset;
|
||||
} *raw;
|
||||
|
||||
ipcAddRecvBuffer(&c, buffer, size, BufferType_Normal);
|
||||
|
||||
raw = serviceIpcPrepareHeader(&g_capsuAccessor, &c, sizeof(*raw));
|
||||
|
||||
raw->magic = SFCI_MAGIC;
|
||||
raw->cmd_id = 2004;
|
||||
raw->stream = stream;
|
||||
raw->offset = offset;
|
||||
|
||||
Result rc = serviceIpcDispatch(&g_capsuAccessor);
|
||||
|
||||
if (R_SUCCEEDED(rc)) {
|
||||
IpcParsedCommand r;
|
||||
struct {
|
||||
u64 magic;
|
||||
u64 result;
|
||||
u64 actual_size;
|
||||
} *resp;
|
||||
|
||||
serviceIpcParse(&g_capsuAccessor, &r, sizeof(*resp));
|
||||
resp = r.Raw;
|
||||
|
||||
rc = resp->result;
|
||||
|
||||
if (R_SUCCEEDED(rc) && actual_size) *actual_size = resp->actual_size;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static inline u64 _capsuMakeTimestamp(const CapsAlbumFileDateTime *datetime) {
|
||||
struct tm tmptm = {.tm_sec = datetime->second, .tm_min = datetime->minute, .tm_hour = datetime->hour,
|
||||
.tm_mday = datetime->day, .tm_mon = datetime->month, .tm_year = datetime->year - 1900};
|
||||
|
||||
return mktime(&tmptm);
|
||||
}
|
||||
|
||||
Result capsuGetAlbumFileListDeprecated1(CapsApplicationAlbumFileEntry *entries, size_t count, CapsContentType type, const CapsAlbumFileDateTime *start_datetime, const CapsAlbumFileDateTime *end_datetime, u64 *total_entries) {
|
||||
u64 start_timestamp = 0x386BF200;
|
||||
u64 end_timestamp = 0xF4865700;
|
||||
|
||||
CapsAlbumFileDateTime default_start = capsGetDefaultStartDateTime();
|
||||
CapsAlbumFileDateTime default_end = capsGetDefaultEndDateTime();
|
||||
|
||||
if (hosversionBefore(6,0,0)) { // GetAlbumFileListDeprecated0
|
||||
if (start_datetime) start_timestamp = _capsuMakeTimestamp(start_datetime);
|
||||
if (end_datetime) end_timestamp = _capsuMakeTimestamp(end_datetime);
|
||||
return _capsuGetAlbumFileList0AafeAruidDeprecated(entries, sizeof(CapsApplicationAlbumFileEntry), count, type, start_timestamp, end_timestamp, total_entries);
|
||||
}
|
||||
|
||||
return _capsuGetAlbumFileListAaeAruid(140, entries, sizeof(CapsApplicationAlbumFileEntry), count, type, start_datetime ? start_datetime : &default_start, end_datetime ? end_datetime : &default_end, total_entries);
|
||||
}
|
||||
|
||||
Result capsuGetAlbumFileListDeprecated2(CapsApplicationAlbumFileEntry *entries, size_t count, CapsContentType type, const CapsAlbumFileDateTime *start_datetime, const CapsAlbumFileDateTime *end_datetime, u128 userID, u64 *total_entries) {
|
||||
if (hosversionBefore(6,0,0))
|
||||
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
|
||||
|
||||
CapsAlbumFileDateTime default_start = capsGetDefaultStartDateTime();
|
||||
CapsAlbumFileDateTime default_end = capsGetDefaultEndDateTime();
|
||||
|
||||
return _capsuGetAlbumFileListAaeUidAruid(141, entries, sizeof(CapsApplicationAlbumFileEntry), count, type, start_datetime ? start_datetime : &default_start, end_datetime ? end_datetime : &default_end, userID, total_entries);
|
||||
}
|
||||
|
||||
Result capsuGetAlbumFileList3(CapsApplicationAlbumEntry *entries, size_t count, CapsContentType type, const CapsAlbumFileDateTime *start_datetime, const CapsAlbumFileDateTime *end_datetime, u64 *total_entries) {
|
||||
if (hosversionBefore(7,0,0))
|
||||
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
|
||||
|
||||
CapsAlbumFileDateTime default_start = capsGetDefaultStartDateTime();
|
||||
CapsAlbumFileDateTime default_end = capsGetDefaultEndDateTime();
|
||||
|
||||
return _capsuGetAlbumFileListAaeAruid(142, entries, sizeof(CapsApplicationAlbumEntry), count, type, start_datetime ? start_datetime : &default_start, end_datetime ? end_datetime : &default_end, total_entries);
|
||||
}
|
||||
|
||||
Result capsuGetAlbumFileList4(CapsApplicationAlbumEntry *entries, size_t count, CapsContentType type, const CapsAlbumFileDateTime *start_datetime, const CapsAlbumFileDateTime *end_datetime, u128 userID, u64 *total_entries) {
|
||||
if (hosversionBefore(7,0,0))
|
||||
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
|
||||
|
||||
CapsAlbumFileDateTime default_start = capsGetDefaultStartDateTime();
|
||||
CapsAlbumFileDateTime default_end = capsGetDefaultEndDateTime();
|
||||
|
||||
return _capsuGetAlbumFileListAaeUidAruid(143, entries, sizeof(CapsApplicationAlbumEntry), count, type, start_datetime ? start_datetime : &default_start, end_datetime ? end_datetime : &default_end, userID, total_entries);
|
||||
}
|
||||
|
||||
Result capsuDeleteAlbumFile(CapsContentType type, const CapsApplicationAlbumFileEntry *entry) {
|
||||
return _capsuDeleteAlbumFileByAruid(103, type, entry);
|
||||
}
|
||||
|
||||
Result capsuGetAlbumFileSize(const CapsApplicationAlbumFileEntry *entry, u64 *size) {
|
||||
return _capsuGetAlbumFileSizeByAruid(entry, size);
|
||||
}
|
||||
|
||||
static void _capsuProcessImageOutput(CapsLoadAlbumScreenShotImageOutputForApplication *out, s32 *width, s32 *height, CapsScreenShotAttributeForApplication *attr, void* userdata, size_t userdata_maxsize, u32 *userdata_size) {
|
||||
if (out==NULL) return;
|
||||
|
||||
if (width) *width = out->width;
|
||||
if (height) *height = out->height;
|
||||
if (attr) memcpy(attr, &out->attr, sizeof(out->attr));
|
||||
|
||||
if (userdata && userdata_maxsize) {
|
||||
memset(userdata, 0, userdata_maxsize);
|
||||
if (userdata_maxsize > sizeof(out->appdata.userdata)) userdata_maxsize = sizeof(out->appdata.userdata);
|
||||
if (userdata_maxsize > out->appdata.size) userdata_maxsize = out->appdata.size;
|
||||
memcpy(userdata, out->appdata.userdata, userdata_maxsize);
|
||||
}
|
||||
if (userdata_size) *userdata_size = out->appdata.size > sizeof(out->appdata.userdata) ? sizeof(out->appdata.userdata) : out->appdata.size;
|
||||
}
|
||||
|
||||
Result capsuLoadAlbumScreenShotImage(s32 *width, s32 *height, CapsScreenShotAttributeForApplication *attr, void* userdata, size_t userdata_maxsize, u32 *userdata_size, void* image, size_t image_size, void* workbuf, size_t workbuf_size, const CapsApplicationAlbumFileEntry *entry, const CapsScreenShotDecodeOption *option) {
|
||||
Result rc=0;
|
||||
CapsLoadAlbumScreenShotImageOutputForApplication out={0};
|
||||
|
||||
rc = _capsuLoadAlbumScreenShotImageByAruid(110, &out, image, image_size, workbuf, workbuf_size, entry, option);
|
||||
if (R_SUCCEEDED(rc)) _capsuProcessImageOutput(&out, width, height, attr, userdata, userdata_maxsize, userdata_size);
|
||||
return rc;
|
||||
}
|
||||
|
||||
Result capsuLoadAlbumScreenShotThumbnailImage(s32 *width, s32 *height, CapsScreenShotAttributeForApplication *attr, void* userdata, size_t userdata_maxsize, u32 *userdata_size, void* image, size_t image_size, void* workbuf, size_t workbuf_size, const CapsApplicationAlbumFileEntry *entry, const CapsScreenShotDecodeOption *option) {
|
||||
Result rc=0;
|
||||
CapsLoadAlbumScreenShotImageOutputForApplication out={0};
|
||||
|
||||
rc = _capsuLoadAlbumScreenShotImageByAruid(120, &out, image, image_size, workbuf, workbuf_size, entry, option);
|
||||
if (R_SUCCEEDED(rc)) _capsuProcessImageOutput(&out, width, height, attr, userdata, userdata_maxsize, userdata_size);
|
||||
return rc;
|
||||
}
|
||||
|
||||
Result capsuPrecheckToCreateContents(CapsContentType type, u64 unk) {
|
||||
return _capsuPrecheckToCreateContentsByAruid(type, unk);
|
||||
}
|
||||
|
||||
Result capsuOpenAlbumMovieStream(u64 *stream, const CapsApplicationAlbumFileEntry *entry) {
|
||||
Result rc=0;
|
||||
|
||||
if (!serviceIsActive(&g_capsuAccessor)) rc =_capsuOpenAccessorSessionForApplication(&g_capsuAccessor, entry);
|
||||
|
||||
if (R_SUCCEEDED(rc)) rc = _capsuOpenAlbumMovieReadStream(stream, entry);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
Result capsuCloseAlbumMovieStream(u64 stream) {
|
||||
if (!serviceIsActive(&g_capsuAccessor))
|
||||
return MAKERESULT(Module_Libnx, LibnxError_NotInitialized);
|
||||
|
||||
return _capsuCmdInU64(&g_capsuAccessor, stream, 2002);
|
||||
}
|
||||
|
||||
Result capsuGetAlbumMovieStreamSize(u64 stream, u64 *size) {
|
||||
if (!serviceIsActive(&g_capsuAccessor))
|
||||
return MAKERESULT(Module_Libnx, LibnxError_NotInitialized);
|
||||
|
||||
return _capsuGetAlbumMovieReadStreamMovieDataSize(stream, size);
|
||||
}
|
||||
|
||||
Result capsuReadAlbumMovieStream(u64 stream, s64 offset, void* buffer, size_t size, u64 *actual_size) {
|
||||
if (!serviceIsActive(&g_capsuAccessor))
|
||||
return MAKERESULT(Module_Libnx, LibnxError_NotInitialized);
|
||||
|
||||
return _capsuReadMovieDataFromAlbumMovieReadStream(stream, offset, buffer, size, actual_size);
|
||||
}
|
||||
|
||||
Result capsuGetAlbumMovieStreamBrokenReason(u64 stream) {
|
||||
if (!serviceIsActive(&g_capsuAccessor))
|
||||
return MAKERESULT(Module_Libnx, LibnxError_NotInitialized);
|
||||
|
||||
return _capsuCmdInU64(&g_capsuAccessor, stream, 2005);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user