// 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.
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);
*/
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.
* @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.
* @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);
if(R_FAILED(ret = svcSendSyncRequest(amHandle))) return ret;
- *count = cmdbuf[2];
+ if(count) *count = cmdbuf[2];
return (Result)cmdbuf[1];
}
if(R_FAILED(ret = svcSendSyncRequest(amHandle))) return ret;
- *count = cmdbuf[2];
+ if(count) *count = cmdbuf[2];
return (Result)cmdbuf[1];
}
if(R_FAILED(ret = svcSendSyncRequest(amHandle))) return ret;
- *count = cmdbuf[2];
+ if(count) *count = cmdbuf[2];
return (Result)cmdbuf[1];
}
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;
if(R_FAILED(ret = svcSendSyncRequest(amHandle))) return ret;
- *ciaHandle = cmdbuf[3];
+ if(ciaHandle) *ciaHandle = cmdbuf[3];
return (Result)cmdbuf[1];
}
if(R_FAILED(ret = svcSendSyncRequest(amHandle))) return ret;
- *ciaHandle = cmdbuf[3];
+ if(ciaHandle) *ciaHandle = cmdbuf[3];
return (Result)cmdbuf[1];
}
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];
}
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;
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];
+}