Fix FSUSER_GetArchiveResource, add more AM commands.

This commit is contained in:
Steven Smith 2016-04-16 00:08:49 -07:00
parent 2f03d17a68
commit 88cffe7703
4 changed files with 521 additions and 16 deletions

View File

@ -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);

View File

@ -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.

View File

@ -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,7 +182,21 @@ 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];
}
@ -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];
}

View File

@ -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();