From 5f13628dac75206f0c97d29a7427ce8284d910f1 Mon Sep 17 00:00:00 2001 From: LiquidFenrir Date: Tue, 21 Dec 2021 23:38:40 +0100 Subject: [PATCH] add DLC title content-info count and data accessors Named specially to indicate they require amAppInit instead of amInit --- libctru/include/3ds/services/am.h | 36 +++++++++++++++++++++++++++++ libctru/source/services/am.c | 38 +++++++++++++++++++++++++++++++ 2 files changed, 74 insertions(+) diff --git a/libctru/include/3ds/services/am.h b/libctru/include/3ds/services/am.h index 50931d2..1d83942 100644 --- a/libctru/include/3ds/services/am.h +++ b/libctru/include/3ds/services/am.h @@ -56,6 +56,23 @@ typedef struct { u64 titlesFreeSpace; ///< Free space for titles. } AM_TWLPartitionInfo; +/// Contains information about a title's content. +typedef struct { + u16 index; ///< Index of the content in the title. + u16 type; ///< ? + u32 contentId; ///< ID of the content in the title. + u64 size; ///< Size of the content in the title. + u8 flags; ///< @ref AM_ContentInfoFlags + u8 padding[7]; ///< Padding +} AM_ContentInfo; + +/// Title ContentInfo flags. +typedef enum +{ + AM_CONTENT_DOWNLOADED = BIT(0), ///< ? + AM_CONTENT_OWNED = BIT(1) ///< ? +} AM_ContentInfoFlags; + /// Initializes AM. This doesn't initialize with "am:app", see amAppInit(). Result amInit(void); @@ -500,3 +517,22 @@ Result AM_DeleteAllExpiredTitles(FS_MediaType mediatype); /// Deletes all TWL titles. Result AM_DeleteAllTwlTitles(void); + +/** + * @brief Gets the number of content index installed under the specified DLC title. + * @param[out] count Pointer to output the number of content indices to. + * @param mediatype Media type of the title. + * @param titleID Title ID to retrieve the count for (high-id is 0x0004008C). + */ +Result AMAPP_GetDLCContentInfoCount(u32* count, FS_MediaType mediatype, u64 titleID); + +/** + * @brief Gets content infos installed under the specified DLC title. + * @param[out] contentInfoRead Pointer to output the number of content infos read to. + * @param mediatype Media type of the title. + * @param titleID Title ID to retrieve the content infos for (high-id is 0x0004008C). + * @param contentInfoCount Number of content infos to retrieve. + * @param offset Offset from the first content index the count starts at. + * @param[out] contentInfos Pointer to output the content infos read to. + */ +Result AMAPP_ListDLCContentInfos(u32* contentInfoRead, FS_MediaType mediatype, u64 titleID, u32 contentInfoCount, u32 offset, AM_ContentInfo* contentInfos); diff --git a/libctru/source/services/am.c b/libctru/source/services/am.c index 9fc5cfd..7e791ab 100644 --- a/libctru/source/services/am.c +++ b/libctru/source/services/am.c @@ -1031,3 +1031,41 @@ Result AM_DeleteAllTwlTitles(void) return (Result)cmdbuf[1]; } + +Result AMAPP_GetDLCContentInfoCount(u32* count, FS_MediaType mediatype, u64 titleID) +{ + Result ret = 0; + u32 *cmdbuf = getThreadCommandBuffer(); + + cmdbuf[0] = IPC_MakeHeader(0x1001,3,0); // 0x100100C0 + cmdbuf[1] = (u32)mediatype; + cmdbuf[2] = titleID & 0xffffffff; + cmdbuf[3] = (u32)(titleID >> 32); + + if(R_FAILED(ret = svcSendSyncRequest(amHandle))) return ret; + + *count = cmdbuf[2]; + + return (Result)cmdbuf[1]; +} + +Result AMAPP_ListDLCContentInfos(u32* contentInfoRead, FS_MediaType mediatype, u64 titleID, u32 contentInfoCount, u32 offset, AM_ContentInfo* contentInfos) +{ + Result ret = 0; + u32 *cmdbuf = getThreadCommandBuffer(); + + cmdbuf[0] = (IPC_MakeHeader(0x1003,5,2)); // 0x10030142 + cmdbuf[1] = contentInfoCount; + cmdbuf[2] = (u32)mediatype; + cmdbuf[3] = titleID & 0xffffffff; + cmdbuf[4] = (u32)(titleID >> 32); + cmdbuf[5] = offset; + cmdbuf[6] = IPC_Desc_Buffer(contentInfoCount * 0x18, IPC_BUFFER_W); + cmdbuf[7] = (u32)contentInfos; + + if(R_FAILED(ret = svcSendSyncRequest(amHandle))) return ret; + + *contentInfoRead = cmdbuf[2]; + + return (Result)cmdbuf[1]; +}