From c998b5d035b3b43aa8142873e3e09d142919664e Mon Sep 17 00:00:00 2001 From: profi200 Date: Sun, 1 Mar 2015 19:49:38 +0100 Subject: [PATCH 1/4] Added AM_ListTitles(), removed nonsense bitwise ands, replaced sprint() with memcpy() (overflow safe) and made utf.h aveilable for apps. --- libctru/include/3ds.h | 1 + libctru/include/3ds/services/am.h | 43 +++++++++++++------ libctru/source/services/am.c | 71 ++++++++++++++++++++----------- 3 files changed, 78 insertions(+), 37 deletions(-) diff --git a/libctru/include/3ds.h b/libctru/include/3ds.h index 741ad03..325f491 100644 --- a/libctru/include/3ds.h +++ b/libctru/include/3ds.h @@ -13,6 +13,7 @@ extern "C" { #include <3ds/os.h> #include <3ds/gfx.h> #include <3ds/console.h> +#include <3ds/utils/utf.h> #include <3ds/services/ac.h> #include <3ds/services/am.h> diff --git a/libctru/include/3ds/services/am.h b/libctru/include/3ds/services/am.h index 34620d3..b1d5db2 100644 --- a/libctru/include/3ds/services/am.h +++ b/libctru/include/3ds/services/am.h @@ -4,6 +4,16 @@ Requires access to "am:net" or "am:u" service */ + +typedef struct +{ + u64 titleID; + u64 unknown; + u16 titleVersion; + u8 unknown2[6]; +} TitleList; + + Result amInit(); Result amExit(); @@ -20,16 +30,26 @@ About: Writes a titleid list for a mediatype to a buffer mediatype mediatype to get list from count number of titleids to get - buffer buffer to write titleids to + titleIDs buffer to write titleids to */ -Result AM_GetTitleList(u8 mediatype, u32 count, void *buffer); +Result AM_GetTitleIdList(u8 mediatype, u32 count, u64 *titleIDs); /* AM_GetDeviceId() About: Gets a 32bit device id, it's used for some key slot inits device_id ptr to where the device id is written to */ -Result AM_GetDeviceId(u32 *deviceid); +Result AM_GetDeviceId(u32 *deviceID); + +/* AM_ListTitles() +About: Get a list with details about the installed titles + + mediatype mediatype of title + titleCount number of titles to list + titleIdList pointer to a title ID list + titleList pointer for the output TitleList array +*/ +Result AM_ListTitles(u8 mediatype, u32 titleCount, u64 *titleIdList, TitleList *titleList); /**** Title Install Methods ****/ /* AM_StartCiaInstall() @@ -38,7 +58,7 @@ About: Inits CIA install process, the returned ciahandle is where the data for C mediatype mediatype to install CIA to ciahandle ptr to where the handle should be written to */ -Result AM_StartCiaInstall(u8 mediatype, Handle *ciahandle); +Result AM_StartCiaInstall(u8 mediatype, Handle *ciaHandle); /* AM_StartDlpChildCiaInstall() About: Inits CIA install process, the returned ciahandle is where the data for CIA should be written to @@ -46,14 +66,14 @@ Note: This is for installing DLP CIAs only, mediatype is hardcoded to be NAND ciahandle ptr to where the handle should be written to */ -Result AM_StartDlpChildCiaInstall(Handle *ciahandle); +Result AM_StartDlpChildCiaInstall(Handle *ciaHandle); /* AM_CancelCIAInstall() About: Abort CIA install process ciahandle ptr to cia Handle provided by AM */ -Result AM_CancelCIAInstall(Handle *ciahandle); +Result AM_CancelCIAInstall(Handle *ciaHandle); /* AM_FinishCiaInstall() About: Once all data is written to the cia handle, this command signals AM to proceed with CIA install. @@ -62,7 +82,7 @@ Note: AM closes the cia handle provided here mediatype same mediatype specified ciahandle was obtained ciahandle ptr to cia Handle provided by AM */ -Result AM_FinishCiaInstall(u8 mediatype, Handle *ciahandle); +Result AM_FinishCiaInstall(u8 mediatype, Handle *ciaHandle); /**** Title Delete Methods ****/ /* AM_DeleteTitle() @@ -72,7 +92,7 @@ Note: AM closes the cia handle provided here mediatype mediatype of title titleid title id of title */ -Result AM_DeleteTitle(u8 mediatype, u64 titleid); +Result AM_DeleteTitle(u8 mediatype, u64 titleID); /* AM_DeleteAppTitle() About: Deletes any title on NAND/SDMC @@ -81,7 +101,7 @@ Note: If the title has the system category bit set, this will fail mediatype mediatype of title titleid title id of title */ -Result AM_DeleteAppTitle(u8 mediatype, u64 titleid); +Result AM_DeleteAppTitle(u8 mediatype, u64 titleID); /* AM_InstallFIRM() About: Installs FIRM to NAND (firm0:/ & firm1:/) from a CXI @@ -90,7 +110,7 @@ Note: The title must have the uniqueid: 0x00000, otherwise this will fail. mediatype mediatype of title titleid title id of title */ -Result AM_InstallFIRM(u8 mediatype, u64 titleid); +Result AM_InstallFIRM(u8 mediatype, u64 titleID); /* AM_GetTitleProductCode() About: Gets the product code of a title based on its title id. @@ -99,5 +119,4 @@ About: Gets the product code of a title based on its title id. titleid title id of title productcode buffer to output the product code to (should have a length of 16) */ -Result AM_GetTitleProductCode(u8 mediatype, u64 titleid, char* productcode); - +Result AM_GetTitleProductCode(u8 mediatype, u64 titleID, char* productCode); diff --git a/libctru/source/services/am.c b/libctru/source/services/am.c index 56f3448..2671e55 100644 --- a/libctru/source/services/am.c +++ b/libctru/source/services/am.c @@ -1,4 +1,5 @@ #include +#include #include #include <3ds/types.h> #include <3ds/svc.h> @@ -35,7 +36,7 @@ Result AM_GetTitleCount(u8 mediatype, u32 *count) return (Result)cmdbuf[1]; } -Result AM_GetTitleList(u8 mediatype, u32 count, void *buffer) +Result AM_GetTitleIdList(u8 mediatype, u32 count, u64 *titleIDs) { Result ret = 0; u32 *cmdbuf = getThreadCommandBuffer(); @@ -44,14 +45,32 @@ Result AM_GetTitleList(u8 mediatype, u32 count, void *buffer) cmdbuf[1] = count; cmdbuf[2] = mediatype; cmdbuf[3] = ((count*8) << 4) | 12; - cmdbuf[4] = (u32)buffer; + cmdbuf[4] = (u32)titleIDs; if((ret = svcSendSyncRequest(amHandle))!=0) return ret; return (Result)cmdbuf[1]; } -Result AM_GetDeviceId(u32 *deviceid) +Result AM_ListTitles(u8 mediatype, u32 titleCount, u64 *titleIdList, TitleList *titleList) +{ + Result ret = 0; + u32 *cmdbuf = getThreadCommandBuffer(); + + cmdbuf[0] = 0x00030084; + cmdbuf[1] = mediatype; + cmdbuf[2] = titleCount; + cmdbuf[3] = ((titleCount*8)<<4) | 10; + cmdbuf[4] = (u32)titleIdList; + cmdbuf[5] = ((sizeof(TitleList)*titleCount)<<4) | 12; + cmdbuf[6] = (u32)titleList; + + if((ret = svcSendSyncRequest(amHandle))!=0) return ret; + + return (Result)cmdbuf[1]; +} + +Result AM_GetDeviceId(u32 *deviceID) { Result ret = 0; u32 *cmdbuf = getThreadCommandBuffer(); @@ -60,12 +79,12 @@ Result AM_GetDeviceId(u32 *deviceid) if((ret = svcSendSyncRequest(amHandle))!=0) return ret; - *deviceid = cmdbuf[3]; + *deviceID = cmdbuf[3]; return (Result)cmdbuf[1]; } -Result AM_StartCiaInstall(u8 mediatype, Handle *ciahandle) +Result AM_StartCiaInstall(u8 mediatype, Handle *ciaHandle) { Result ret = 0; u32 *cmdbuf = getThreadCommandBuffer(); @@ -75,12 +94,12 @@ Result AM_StartCiaInstall(u8 mediatype, Handle *ciahandle) if((ret = svcSendSyncRequest(amHandle))!=0) return ret; - *ciahandle = cmdbuf[3]; + *ciaHandle = cmdbuf[3]; return (Result)cmdbuf[1]; } -Result AM_StartDlpChildCiaInstall(Handle *ciahandle) +Result AM_StartDlpChildCiaInstall(Handle *ciaHandle) { Result ret = 0; u32 *cmdbuf = getThreadCommandBuffer(); @@ -89,96 +108,98 @@ Result AM_StartDlpChildCiaInstall(Handle *ciahandle) if((ret = svcSendSyncRequest(amHandle))!=0) return ret; - *ciahandle = cmdbuf[3]; + *ciaHandle = cmdbuf[3]; return (Result)cmdbuf[1]; } -Result AM_CancelCIAInstall(Handle *ciahandle) +Result AM_CancelCIAInstall(Handle *ciaHandle) { Result ret = 0; u32 *cmdbuf = getThreadCommandBuffer(); cmdbuf[0] = 0x04040002; cmdbuf[1] = 0x10; - cmdbuf[2] = *ciahandle; + cmdbuf[2] = *ciaHandle; if((ret = svcSendSyncRequest(amHandle))!=0) return ret; return (Result)cmdbuf[1]; } -Result AM_FinishCiaInstall(u8 mediatype, Handle *ciahandle) +Result AM_FinishCiaInstall(u8 mediatype, Handle *ciaHandle) { Result ret = 0; u32 *cmdbuf = getThreadCommandBuffer(); cmdbuf[0] = 0x04050002; cmdbuf[1] = 0x10; - cmdbuf[2] = *ciahandle; + cmdbuf[2] = *ciaHandle; if((ret = svcSendSyncRequest(amHandle))!=0) return ret; return (Result)cmdbuf[1]; } -Result AM_DeleteTitle(u8 mediatype, u64 titleid) +Result AM_DeleteTitle(u8 mediatype, u64 titleID) { Result ret = 0; u32 *cmdbuf = getThreadCommandBuffer(); cmdbuf[0] = 0x041000C0; cmdbuf[1] = mediatype; - cmdbuf[2] = titleid & 0xffffffff; - cmdbuf[3] = (titleid >> 32) & 0xffffffff; + cmdbuf[2] = titleID & 0xffffffff; + cmdbuf[3] = (u32)(titleID >> 32); if((ret = svcSendSyncRequest(amHandle))!=0) return ret; return (Result)cmdbuf[1]; } -Result AM_DeleteAppTitle(u8 mediatype, u64 titleid) +Result AM_DeleteAppTitle(u8 mediatype, u64 titleID) { Result ret = 0; u32 *cmdbuf = getThreadCommandBuffer(); cmdbuf[0] = 0x000400C0; cmdbuf[1] = mediatype; - cmdbuf[2] = titleid & 0xffffffff; - cmdbuf[3] = (titleid >> 32) & 0xffffffff; + cmdbuf[2] = titleID & 0xffffffff; + cmdbuf[3] = (u32)(titleID >> 32); if((ret = svcSendSyncRequest(amHandle))!=0) return ret; return (Result)cmdbuf[1]; } -Result AM_InstallFIRM(u8 mediatype, u64 titleid) +Result AM_InstallFIRM(u8 mediatype, u64 titleID) { Result ret = 0; u32 *cmdbuf = getThreadCommandBuffer(); cmdbuf[0] = 0x000400C0; cmdbuf[1] = mediatype; - cmdbuf[2] = titleid & 0xffffffff; - cmdbuf[3] = (titleid >> 32) & 0xffffffff; + cmdbuf[2] = titleID & 0xffffffff; + cmdbuf[3] = (u32)(titleID >> 32); if((ret = svcSendSyncRequest(amHandle))!=0) return ret; return (Result)cmdbuf[1]; } -Result AM_GetTitleProductCode(u8 mediatype, u64 titleid, char* productcode) +Result AM_GetTitleProductCode(u8 mediatype, u64 titleID, char* productCode) { Result ret = 0; u32 *cmdbuf = getThreadCommandBuffer(); cmdbuf[0] = 0x000500C0; cmdbuf[1] = mediatype; - cmdbuf[2] = titleid & 0xffffffff; - cmdbuf[3] = (titleid >> 32) & 0xffffffff; + cmdbuf[2] = titleID & 0xffffffff; + cmdbuf[3] = (u32)(titleID >> 32); if((ret = svcSendSyncRequest(amHandle))!=0) return ret; - snprintf(productcode, 16, "%s", (char*)(&cmdbuf[2])); + // The product code string can use the full 16 bytes without NULL terminator + if(productCode) memcpy(productCode, &cmdbuf[2], 16); + return (Result)cmdbuf[1]; } From a2d2df17f9bf36dd38f2ca378b16b2d1eac88c77 Mon Sep 17 00:00:00 2001 From: profi200 Date: Sun, 1 Mar 2015 19:57:57 +0100 Subject: [PATCH 2/4] Minifix. --- libctru/include/3ds.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libctru/include/3ds.h b/libctru/include/3ds.h index 325f491..3012764 100644 --- a/libctru/include/3ds.h +++ b/libctru/include/3ds.h @@ -13,7 +13,7 @@ extern "C" { #include <3ds/os.h> #include <3ds/gfx.h> #include <3ds/console.h> -#include <3ds/utils/utf.h> +#include <3ds/util/utf.h> #include <3ds/services/ac.h> #include <3ds/services/am.h> From 02b68eb1ae915d2e4a70e1b2ba87e4c87def54ba Mon Sep 17 00:00:00 2001 From: profi200 Date: Sun, 1 Mar 2015 20:28:22 +0100 Subject: [PATCH 3/4] Change it back to snprintf(). --- libctru/source/services/am.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libctru/source/services/am.c b/libctru/source/services/am.c index 2671e55..e6c84a8 100644 --- a/libctru/source/services/am.c +++ b/libctru/source/services/am.c @@ -199,7 +199,7 @@ Result AM_GetTitleProductCode(u8 mediatype, u64 titleID, char* productCode) if((ret = svcSendSyncRequest(amHandle))!=0) return ret; // The product code string can use the full 16 bytes without NULL terminator - if(productCode) memcpy(productCode, &cmdbuf[2], 16); + if(productCode) snprintf(productCode, 16, "%s", (char*)&cmdbuf[2]); return (Result)cmdbuf[1]; } From ed3045ab6a425df79f0b1d7a973e39816dbcaf63 Mon Sep 17 00:00:00 2001 From: profi200 Date: Sun, 1 Mar 2015 21:52:19 +0100 Subject: [PATCH 4/4] Fixed AM_InstallFIRM(). See 3dbrew. --- libctru/include/3ds/services/am.h | 3 +-- libctru/source/services/am.c | 9 ++++----- 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/libctru/include/3ds/services/am.h b/libctru/include/3ds/services/am.h index b1d5db2..3eb1501 100644 --- a/libctru/include/3ds/services/am.h +++ b/libctru/include/3ds/services/am.h @@ -107,10 +107,9 @@ Result AM_DeleteAppTitle(u8 mediatype, u64 titleID); About: Installs FIRM to NAND (firm0:/ & firm1:/) from a CXI Note: The title must have the uniqueid: 0x00000, otherwise this will fail. - mediatype mediatype of title titleid title id of title */ -Result AM_InstallFIRM(u8 mediatype, u64 titleID); +Result AM_InstallFIRM(u64 titleID); /* AM_GetTitleProductCode() About: Gets the product code of a title based on its title id. diff --git a/libctru/source/services/am.c b/libctru/source/services/am.c index e6c84a8..e80faff 100644 --- a/libctru/source/services/am.c +++ b/libctru/source/services/am.c @@ -171,15 +171,14 @@ Result AM_DeleteAppTitle(u8 mediatype, u64 titleID) return (Result)cmdbuf[1]; } -Result AM_InstallFIRM(u8 mediatype, u64 titleID) +Result AM_InstallFIRM(u64 titleID) { Result ret = 0; u32 *cmdbuf = getThreadCommandBuffer(); - cmdbuf[0] = 0x000400C0; - cmdbuf[1] = mediatype; - cmdbuf[2] = titleID & 0xffffffff; - cmdbuf[3] = (u32)(titleID >> 32); + cmdbuf[0] = 0x04010080; + cmdbuf[1] = titleID & 0xffffffff; + cmdbuf[2] = (u32)(titleID >> 32); if((ret = svcSendSyncRequest(amHandle))!=0) return ret;