From 88cffe7703ea67bad7926f802e655de721f55a77 Mon Sep 17 00:00:00 2001 From: Steven Smith Date: Sat, 16 Apr 2016 00:08:49 -0700 Subject: [PATCH] Fix FSUSER_GetArchiveResource, add more AM commands. --- libctru/include/3ds/services/am.h | 165 +++++++++++++- libctru/include/3ds/services/fs.h | 13 +- libctru/source/services/am.c | 357 +++++++++++++++++++++++++++++- libctru/source/services/fs.c | 2 +- 4 files changed, 521 insertions(+), 16 deletions(-) diff --git a/libctru/include/3ds/services/am.h b/libctru/include/3ds/services/am.h index 9a7b8b1..926409e 100644 --- a/libctru/include/3ds/services/am.h +++ b/libctru/include/3ds/services/am.h @@ -34,11 +34,11 @@ typedef enum // Contains basic information about a pending title. typedef struct { - u64 titleId; ///< Title ID - u16 version; ///< Version - u16 status; ///< @ref AM_InstallStatus - u32 titleType; ///< Title Type - u8 unk[0x8]; ///< Unknown + u64 titleId; ///< Title ID + u16 version; ///< Version + u16 status; ///< @ref AM_InstallStatus + u32 titleType; ///< Title Type + u8 unk[0x8]; ///< Unknown } AM_PendingTitleEntry; /// Pending title deletion flags. @@ -48,6 +48,14 @@ enum AM_DELETE_PENDING_SYSTEM = BIT(1) ///< System titles. }; +/// Information about the TWL NAND partition. +typedef struct { + u64 capacity; ///< Total capacity. + u64 freeSpace; ///< Total free space. + u64 titlesCapacity; ///< Capacity for titles. + u64 titlesFreeSpace; ///< Free space for titles. +} AM_TWLPartitionInfo; + /// Initializes AM. Result amInit(void); @@ -130,6 +138,12 @@ Result AM_GetPendingTitleInfo(u32 titleCount, FS_MediaType mediatype, u64 *title */ Result AM_GetDeviceId(u32 *deviceID); +/** + * @brief Retrieves information about the NAND TWL partition. + * @param[out] info Pointer to output the TWL partition info to. + */ +Result AM_GetTWLPartitionInfo(AM_TWLPartitionInfo *info); + /** * @brief Initializes the CIA install process, returning a handle to write CIA data to. * @param mediatype Media type to install the CIA to. @@ -224,10 +238,54 @@ Result AM_GetTitleExtDataId(u64 *extDataId, FS_MediaType mediatype, u64 titleId) * @brief Gets an AM_TitleEntry instance for a CIA file. * @param mediatype Media type that this CIA would be installed to. * @param[out] titleEntry Pointer to write the AM_TitleEntry instance to. - * @param fileHandle Handle of the CIA file to read. + * @param fileHandle Handle of the CIA file. */ Result AM_GetCiaFileInfo(FS_MediaType mediatype, AM_TitleEntry *titleEntry, Handle fileHandle); +/** + * @brief Gets the SMDH icon data of a CIA file. + * @param icon Buffer to store the icon data in. Must be of size 0x36C0 bytes. + * @param fileHandle Handle of the CIA file. + */ +Result AM_GetCiaIcon(void *icon, Handle fileHandle); + +/** + * @brief Gets the title ID dependency list of a CIA file. + * @param dependencies Buffer to store dependency title IDs in. Must be of size 0x300 bytes. + * @param fileHandle Handle of the CIA file. + */ +Result AM_GetCiaDependencies(u64 *dependencies, Handle fileHandle); + +/** + * @brief Gets the meta section offset of a CIA file. + * @param[out] metaOffset Pointer to output the meta section offset to. + * @param fileHandle Handle of the CIA file. + */ +Result AM_GetCiaMetaOffset(u64 *metaOffset, Handle fileHandle); + +/** + * @brief Gets the core version of a CIA file. + * @param[out] coreVersion Pointer to output the core version to. + * @param fileHandle Handle of the CIA file. + */ +Result AM_GetCiaCoreVersion(u32 *coreVersion, Handle fileHandle); + +/** + * @brief Gets the free space, in bytes, required to install a CIA file. + * @param[out] requiredSpace Pointer to output the required free space to. + * @param mediaType Media type to check free space needed to install to. + * @param fileHandle Handle of the CIA file. + */ +Result AM_GetCiaRequiredSpace(u64 *requiredSpace, FS_MediaType mediaType, Handle fileHandle); + +/** + * @brief Gets the full meta section of a CIA file. + * @param meta Buffer to store the meta section in. + * @param size Size of the buffer. Must be greater than or equal to the actual section data's size. + * @param fileHandle Handle of the CIA file. + */ +Result AM_GetCiaMetaSection(void *meta, u32 size, Handle fileHandle); + /** * @brief Initializes the external (SD) title database. * @param overwrite Overwrites the database if it already exists. @@ -239,3 +297,98 @@ Result AM_InitializeExternalTitleDatabase(bool overwrite); * @param[out] available Pointer to output the availability status to. */ Result AM_QueryAvailableExternalTitleDatabase(bool* available); + +/** + * @brief Begins installing a ticket. + * @param[out] ticketHandle Pointer to output a handle to write ticket data to. + */ +Result AM_InstallTicketBegin(Handle *ticketHandle); + +/** + * @brief Aborts installing a ticket. + * @param ticketHandle Handle of the installation to abort. + */ +Result AM_InstallTicketAbort(Handle ticketHandle); + +/** + * @brief Finalizes installing a ticket. + * @param ticketHandle Handle of the installation to finalize. + */ +Result AM_InstallTicketFinalize(Handle ticketHandle); + +/** + * @brief Begins installing a title. + * @param mediaType Destination to install to. + * @param titleId ID of the title to install. + */ +Result AM_InstallTitleBegin(FS_MediaType mediaType, u64 titleId); + +/// Aborts installing a title. +Result AM_InstallTitleAbort(); + +/** + * @brief Resumes installing a title. + * @param mediaType Destination to install to. + * @param titleId ID of the title to install. + */ +Result AM_InstallTitleResume(FS_MediaType mediaType, u64 titleId); + +/// Aborts installing a title due to a TMD error. +Result AM_InstallTitleAbortTMD(); + +/// Finishes installing a title. +Result AM_InstallTitleFinish(); + +/** + * @brief Begins installing a TMD. + * @param[out] tmdHandle Pointer to output a handle to write TMD data to. + */ +Result AM_InstallTmdBegin(Handle *tmdHandle); + +/** + * @brief Aborts installing a TMD. + * @param tmdHandle Handle of the installation to abort. + */ +Result AM_InstallTmdAbort(Handle tmdHandle); + +/** + * @brief Finalizes installing a TMD. + * @param tmdHandle Handle of the installation to finalize. + */ +Result AM_InstallTmdFinalize(Handle tmdHandle); + +/** + * @brief Begins installing title content. + * @param[out] contentHandle Pointer to output a handle to write content data to. + * @param index Index of the content to install. + */ +Result AM_InstallContentBegin(Handle *contentHandle, u16 index); + +/** + * @brief Aborts installing title content. + * @param contentHandle Handle of the installation to abort. + */ +Result AM_InstallContentAbort(Handle contentHandle); + +/** + * @brief Resumes installing title content. + * @param[out] contentHandle Pointer to output a handle to write content data to. + * @param[out] resumeOffset Pointer to write the offset to resume content installation at to. + * @param index Index of the content to install. + */ +Result AM_InstallContentResume(Handle *contentHandle, u64* resumeOffset, u16 index); + +/** + * @brief Finalizes installing title content. + * @param contentHandle Handle of the installation to finalize. + */ +Result AM_InstallContentFinalize(Handle contentHandle); + +/** + * @brief Finalizes the installation of one or more titles. + * @param mediaType Location of the titles to finalize. + * @param titleCount Number of titles to finalize. + * @param temp Whether the titles being finalized are in the temporary database. + * @param titleIds Title IDs to finalize. + */ +Result AM_InstallTitlesFinish(FS_MediaType mediaType, u32 titleCount, bool temp, u64* titleIds); diff --git a/libctru/include/3ds/services/fs.h b/libctru/include/3ds/services/fs.h index 821eebe..2db8f81 100644 --- a/libctru/include/3ds/services/fs.h +++ b/libctru/include/3ds/services/fs.h @@ -38,6 +38,15 @@ typedef enum MEDIATYPE_GAME_CARD = 2, ///< Game card. } FS_MediaType; +/// System media types. +typedef enum +{ + SYSTEM_MEDIATYPE_CTR_NAND = 0, ///< CTR NAND. + SYSTEM_MEDIATYPE_TWL_NAND = 1, ///< TWL NAND. + SYSTEM_MEDIATYPE_SD = 2, ///< SD card. + SYSTEM_MEDIATYPE_TWL_PHOTO = 3, ///< TWL Photo. +} FS_SystemMediaType; + /// Archive IDs. typedef enum { @@ -690,9 +699,9 @@ Result FSUSER_GetSdmcCtrRootPath(u8* out, u32 length); /** * @brief Gets an archive's resource information. * @param archiveResource Pointer to output the archive resource information to. - * @param mediaType Media type to check. + * @param mediaType System media type to check. */ -Result FSUSER_GetArchiveResource(FS_ArchiveResource* archiveResource, FS_MediaType mediaType); +Result FSUSER_GetArchiveResource(FS_ArchiveResource* archiveResource, FS_SystemMediaType mediaType); /** * @brief Exports the integrity verification seed. diff --git a/libctru/source/services/am.c b/libctru/source/services/am.c index cdcf0b2..b40975f 100644 --- a/libctru/source/services/am.c +++ b/libctru/source/services/am.c @@ -47,7 +47,7 @@ Result AM_GetTitleCount(FS_MediaType mediatype, u32 *count) if(R_FAILED(ret = svcSendSyncRequest(amHandle))) return ret; - *count = cmdbuf[2]; + if(count) *count = cmdbuf[2]; return (Result)cmdbuf[1]; } @@ -97,7 +97,7 @@ Result AM_GetTicketCount(u32 *count) if(R_FAILED(ret = svcSendSyncRequest(amHandle))) return ret; - *count = cmdbuf[2]; + if(count) *count = cmdbuf[2]; return (Result)cmdbuf[1]; } @@ -131,7 +131,7 @@ Result AM_GetPendingTitleCount(u32 *count, FS_MediaType mediatype, u32 statusMas if(R_FAILED(ret = svcSendSyncRequest(amHandle))) return ret; - *count = cmdbuf[2]; + if(count) *count = cmdbuf[2]; return (Result)cmdbuf[1]; } @@ -182,11 +182,25 @@ Result AM_GetDeviceId(u32 *deviceID) if(R_FAILED(ret = svcSendSyncRequest(amHandle))) return ret; - *deviceID = cmdbuf[3]; + if(deviceID) *deviceID = cmdbuf[3]; return (Result)cmdbuf[1]; } +Result AM_GetTWLPartitionInfo(AM_TWLPartitionInfo *info) +{ + Result ret = 0; + u32 *cmdbuf = getThreadCommandBuffer(); + + cmdbuf[0] = IPC_MakeHeader(0x20,0,0); // 0x00200000 + + if(R_FAILED(ret = svcSendSyncRequest(amHandle))) return ret; + + if(info) memcpy(info, &cmdbuf[2], sizeof(AM_TWLPartitionInfo)); + + return (Result)cmdbuf[1]; +} + Result AM_StartCiaInstall(FS_MediaType mediatype, Handle *ciaHandle) { Result ret = 0; @@ -197,7 +211,7 @@ Result AM_StartCiaInstall(FS_MediaType mediatype, Handle *ciaHandle) if(R_FAILED(ret = svcSendSyncRequest(amHandle))) return ret; - *ciaHandle = cmdbuf[3]; + if(ciaHandle) *ciaHandle = cmdbuf[3]; return (Result)cmdbuf[1]; } @@ -211,7 +225,7 @@ Result AM_StartDlpChildCiaInstall(Handle *ciaHandle) if(R_FAILED(ret = svcSendSyncRequest(amHandle))) return ret; - *ciaHandle = cmdbuf[3]; + if(ciaHandle) *ciaHandle = cmdbuf[3]; return (Result)cmdbuf[1]; } @@ -385,7 +399,7 @@ Result AM_GetTitleExtDataId(u64 *extDataId, FS_MediaType mediatype, u64 titleId) if(R_FAILED(ret = svcSendSyncRequest(amHandle))) return ret; - if(extDataId) *extDataId = (u64) cmdbuf[2] | ((u64) cmdbuf[3] << 32); + if(extDataId) *extDataId = (u64)cmdbuf[2] | ((u64)cmdbuf[3] << 32); return (Result)cmdbuf[1]; } @@ -407,6 +421,107 @@ Result AM_GetCiaFileInfo(FS_MediaType mediatype, AM_TitleEntry *titleEntry, Hand return (Result)cmdbuf[1]; } +Result AM_GetCiaIcon(void *icon, Handle fileHandle) +{ + Result ret = 0; + u32 *cmdbuf = getThreadCommandBuffer(); + + cmdbuf[0] = IPC_MakeHeader(0x409,0,4); // 0x04090004 + cmdbuf[1] = IPC_Desc_SharedHandles(1); + cmdbuf[2] = fileHandle; + cmdbuf[3] = IPC_Desc_Buffer(0x36C0, IPC_BUFFER_W); + cmdbuf[4] = (u32)icon; + + if(R_FAILED(ret = svcSendSyncRequest(*amGetSessionHandle()))) return ret; + + return (Result)cmdbuf[1]; +} + +Result AM_GetCiaDependencies(u64 *dependencies, Handle fileHandle) +{ + Result ret = 0; + u32 *cmdbuf = getThreadCommandBuffer(); + + cmdbuf[0] = IPC_MakeHeader(0x40A,0,2); // 0x040A0002 + cmdbuf[1] = IPC_Desc_SharedHandles(1); + cmdbuf[2] = fileHandle; + + u32 *staticbuf = getThreadStaticBuffers(); + + staticbuf[0] = IPC_Desc_StaticBuffer(0x300, 0); + staticbuf[1] = (u32)dependencies; + + if(R_FAILED(ret = svcSendSyncRequest(*amGetSessionHandle()))) return ret; + + return (Result)cmdbuf[1]; +} + +Result AM_GetCiaMetaOffset(u64 *metaOffset, Handle fileHandle) +{ + Result ret = 0; + u32 *cmdbuf = getThreadCommandBuffer(); + + cmdbuf[0] = IPC_MakeHeader(0x40B,0,2); // 0x040B0002 + cmdbuf[1] = IPC_Desc_SharedHandles(1); + cmdbuf[2] = fileHandle; + + if(R_FAILED(ret = svcSendSyncRequest(*amGetSessionHandle()))) return ret; + + if(metaOffset) *metaOffset = cmdbuf[2] | ((u64)cmdbuf[3] << 32); + + return (Result)cmdbuf[1]; +} + +Result AM_GetCiaCoreVersion(u32 *coreVersion, Handle fileHandle) +{ + Result ret = 0; + u32 *cmdbuf = getThreadCommandBuffer(); + + cmdbuf[0] = IPC_MakeHeader(0x40C,0,2); // 0x040C0002 + cmdbuf[1] = IPC_Desc_SharedHandles(1); + cmdbuf[2] = fileHandle; + + if(R_FAILED(ret = svcSendSyncRequest(*amGetSessionHandle()))) return ret; + + if(coreVersion) *coreVersion = cmdbuf[2]; + + return (Result)cmdbuf[1]; +} + +Result AM_GetCiaRequiredSpace(u64 *requiredSpace, FS_MediaType mediaType, Handle fileHandle) +{ + Result ret = 0; + u32 *cmdbuf = getThreadCommandBuffer(); + + cmdbuf[0] = IPC_MakeHeader(0x40D,1,2); // 0x040D0042 + cmdbuf[1] = mediaType; + cmdbuf[2] = IPC_Desc_SharedHandles(1); + cmdbuf[3] = fileHandle; + + if(R_FAILED(ret = svcSendSyncRequest(*amGetSessionHandle()))) return ret; + + if(requiredSpace) *requiredSpace = cmdbuf[2] | ((u64)cmdbuf[3] << 32); + + return (Result)cmdbuf[1]; +} + +Result AM_GetCiaMetaSection(void *meta, u32 size, Handle fileHandle) +{ + Result ret = 0; + u32 *cmdbuf = getThreadCommandBuffer(); + + cmdbuf[0] = IPC_MakeHeader(0x414,1,4); // 0x04140044 + cmdbuf[1] = size; + cmdbuf[2] = IPC_Desc_SharedHandles(1); + cmdbuf[3] = fileHandle; + cmdbuf[4] = IPC_Desc_Buffer(size, IPC_BUFFER_W); + cmdbuf[5] = (u32)meta; + + if(R_FAILED(ret = svcSendSyncRequest(amHandle))) return ret; + + return (Result)cmdbuf[1]; +} + Result AM_InitializeExternalTitleDatabase(bool overwrite) { Result ret = 0; @@ -437,3 +552,231 @@ Result AM_QueryAvailableExternalTitleDatabase(bool* available) return ret; } + +Result AM_InstallTicketBegin(Handle *ticketHandle) +{ + Result ret = 0; + u32 *cmdbuf = getThreadCommandBuffer(); + + cmdbuf[0] = IPC_MakeHeader(0x801,0,0); // 0x08010000 + + if(R_FAILED(ret = svcSendSyncRequest(amHandle))) return ret; + + if(ticketHandle) *ticketHandle = cmdbuf[3]; + + return (Result)cmdbuf[1]; +} + +Result AM_InstallTicketAbort(Handle ticketHandle) +{ + Result ret = 0; + u32 *cmdbuf = getThreadCommandBuffer(); + + cmdbuf[0] = IPC_MakeHeader(0x802,0,2); // 0x08020002 + cmdbuf[1] = IPC_Desc_MoveHandles(1); + cmdbuf[2] = ticketHandle; + + if(R_FAILED(ret = svcSendSyncRequest(amHandle))) return ret; + + return (Result)cmdbuf[1]; +} + +Result AM_InstallTicketFinalize(Handle ticketHandle) +{ + Result ret = 0; + u32 *cmdbuf = getThreadCommandBuffer(); + + cmdbuf[0] = IPC_MakeHeader(0x803,0,2); // 0x08030002 + cmdbuf[1] = IPC_Desc_MoveHandles(1); + cmdbuf[2] = ticketHandle; + + if(R_FAILED(ret = svcSendSyncRequest(amHandle))) return ret; + + return (Result)cmdbuf[1]; +} + +Result AM_InstallTitleBegin(FS_MediaType mediaType, u64 titleId) +{ + Result ret = 0; + u32 *cmdbuf = getThreadCommandBuffer(); + + cmdbuf[0] = IPC_MakeHeader(0x804,4,0); // 0x08040100 + cmdbuf[1] = mediaType; + cmdbuf[2] = (u32) (titleId & 0xFFFFFFFF); + cmdbuf[3] = (u32) ((titleId >> 32) & 0xFFFFFFFF); + cmdbuf[4] = 0; + + if(R_FAILED(ret = svcSendSyncRequest(amHandle))) return ret; + + return (Result)cmdbuf[1]; +} + +Result AM_InstallTitleAbort() +{ + Result ret = 0; + u32 *cmdbuf = getThreadCommandBuffer(); + + cmdbuf[0] = IPC_MakeHeader(0x805,0,0); // 0x08050000 + + if(R_FAILED(ret = svcSendSyncRequest(amHandle))) return ret; + + return (Result)cmdbuf[1]; +} + +Result AM_InstallTitleResume(FS_MediaType mediaType, u64 titleId) +{ + Result ret = 0; + u32 *cmdbuf = getThreadCommandBuffer(); + + cmdbuf[0] = IPC_MakeHeader(0x806,3,0); // 0x080600C0 + cmdbuf[1] = mediaType; + cmdbuf[2] = (u32) (titleId & 0xFFFFFFFF); + cmdbuf[3] = (u32) ((titleId >> 32) & 0xFFFFFFFF); + + if(R_FAILED(ret = svcSendSyncRequest(amHandle))) return ret; + + return (Result)cmdbuf[1]; +} + +Result AM_InstallTitleAbortTMD() +{ + Result ret = 0; + u32 *cmdbuf = getThreadCommandBuffer(); + + cmdbuf[0] = IPC_MakeHeader(0x807,0,0); // 0x08070000 + + if(R_FAILED(ret = svcSendSyncRequest(amHandle))) return ret; + + return (Result)cmdbuf[1]; +} + +Result AM_InstallTitleFinish() +{ + Result ret = 0; + u32 *cmdbuf = getThreadCommandBuffer(); + + cmdbuf[0] = IPC_MakeHeader(0x808,0,0); // 0x08080000 + + if(R_FAILED(ret = svcSendSyncRequest(amHandle))) return ret; + + return (Result)cmdbuf[1]; +} + +Result AM_InstallTmdBegin(Handle *tmdHandle) +{ + Result ret = 0; + u32 *cmdbuf = getThreadCommandBuffer(); + + cmdbuf[0] = IPC_MakeHeader(0x80A,0,0); // 0x080A0000 + + if(R_FAILED(ret = svcSendSyncRequest(amHandle))) return ret; + + if(tmdHandle) *tmdHandle = cmdbuf[3]; + + return (Result)cmdbuf[1]; +} + +Result AM_InstallTmdAbort(Handle tmdHandle) +{ + Result ret = 0; + u32 *cmdbuf = getThreadCommandBuffer(); + + cmdbuf[0] = IPC_MakeHeader(0x80B,0,2); // 0x080B0002 + cmdbuf[1] = IPC_Desc_MoveHandles(1); + cmdbuf[2] = tmdHandle; + + if(R_FAILED(ret = svcSendSyncRequest(amHandle))) return ret; + + return (Result)cmdbuf[1]; +} + +Result AM_InstallTmdFinalize(Handle tmdHandle) +{ + Result ret = 0; + u32 *cmdbuf = getThreadCommandBuffer(); + + cmdbuf[0] = IPC_MakeHeader(0x80C,1,2); // 0x080C0042 + cmdbuf[1] = 1; + cmdbuf[2] = IPC_Desc_MoveHandles(1); + cmdbuf[3] = tmdHandle; + + if(R_FAILED(ret = svcSendSyncRequest(amHandle))) return ret; + + return (Result)cmdbuf[1]; +} + +Result AM_InstallContentBegin(Handle *contentHandle, u16 index) +{ + Result ret = 0; + u32 *cmdbuf = getThreadCommandBuffer(); + + cmdbuf[0] = IPC_MakeHeader(0x80E,1,0); // 0x080E0040 + cmdbuf[1] = index; + + if(R_FAILED(ret = svcSendSyncRequest(amHandle))) return ret; + + if(contentHandle) *contentHandle = cmdbuf[3]; + + return (Result)cmdbuf[1]; +} + +Result AM_InstallContentAbort(Handle contentHandle) +{ + Result ret = 0; + u32 *cmdbuf = getThreadCommandBuffer(); + + cmdbuf[0] = IPC_MakeHeader(0x80F,0,2); // 0x080F0002 + cmdbuf[1] = IPC_Desc_MoveHandles(1); + cmdbuf[2] = contentHandle; + + if(R_FAILED(ret = svcSendSyncRequest(amHandle))) return ret; + + return (Result)cmdbuf[1]; +} + +Result AM_InstallContentResume(Handle *contentHandle, u64* resumeOffset, u16 index) +{ + Result ret = 0; + u32 *cmdbuf = getThreadCommandBuffer(); + + cmdbuf[0] = IPC_MakeHeader(0x810,1,0); // 0x08100040 + cmdbuf[1] = index; + + if(R_FAILED(ret = svcSendSyncRequest(amHandle))) return ret; + + if(contentHandle) *contentHandle = cmdbuf[5]; + if(resumeOffset) *resumeOffset = cmdbuf[2] | ((u64)cmdbuf[3] << 32); + + return (Result)cmdbuf[1]; +} + +Result AM_InstallContentFinalize(Handle contentHandle) +{ + Result ret = 0; + u32 *cmdbuf = getThreadCommandBuffer(); + + cmdbuf[0] = IPC_MakeHeader(0x812,0,2); // 0x08120002 + cmdbuf[1] = IPC_Desc_MoveHandles(1); + cmdbuf[2] = contentHandle; + + if(R_FAILED(ret = svcSendSyncRequest(amHandle))) return ret; + + return (Result)cmdbuf[1]; +} + +Result AM_InstallTitlesFinish(FS_MediaType mediaType, u32 titleCount, bool temp, u64* titleIds) +{ + Result ret = 0; + u32 *cmdbuf = getThreadCommandBuffer(); + + cmdbuf[0] = IPC_MakeHeader(0x81B,3,2); // 0x081B00C2 + cmdbuf[1] = mediaType; + cmdbuf[2] = titleCount; + cmdbuf[3] = temp ? 1 : 0; + cmdbuf[4] = IPC_Desc_Buffer(titleCount * 8, IPC_BUFFER_R); + cmdbuf[5] = (u32)titleIds; + + if(R_FAILED(ret = svcSendSyncRequest(amHandle))) return ret; + + return (Result)cmdbuf[1]; +} diff --git a/libctru/source/services/fs.c b/libctru/source/services/fs.c index 93e3e55..fb622f3 100644 --- a/libctru/source/services/fs.c +++ b/libctru/source/services/fs.c @@ -1080,7 +1080,7 @@ Result FSUSER_GetSdmcCtrRootPath(u8* out, u32 length) return cmdbuf[1]; } -Result FSUSER_GetArchiveResource(FS_ArchiveResource* archiveResource, FS_MediaType mediaType) +Result FSUSER_GetArchiveResource(FS_ArchiveResource* archiveResource, FS_SystemMediaType mediaType) { u32 *cmdbuf = getThreadCommandBuffer();