From dec409ca32258027784db8dafd9540c5997a2288 Mon Sep 17 00:00:00 2001 From: profi200 Date: Sun, 1 Mar 2015 17:17:09 +0100 Subject: [PATCH] Added missing am service cmds and changed the names to reflect 3dbrews docs. --- libctru/include/3ds.h | 2 + libctru/include/3ds/services/am.h | 114 ++++++++++++++++++-------- libctru/source/services/am.c | 128 +++++++++++++++++++----------- 3 files changed, 163 insertions(+), 81 deletions(-) diff --git a/libctru/include/3ds.h b/libctru/include/3ds.h index 1713255..6f6ee42 100644 --- a/libctru/include/3ds.h +++ b/libctru/include/3ds.h @@ -13,8 +13,10 @@ extern "C" { #include <3ds/os.h> #include <3ds/gfx.h> #include <3ds/console.h> +#include <3ds/util/utf.h> #include <3ds/services/ac.h> +#include <3ds/services/am.h> #include <3ds/services/apt.h> #include <3ds/services/cfgnor.h> #include <3ds/services/cfgu.h> diff --git a/libctru/include/3ds/services/am.h b/libctru/include/3ds/services/am.h index 79da46f..60f80dc 100644 --- a/libctru/include/3ds/services/am.h +++ b/libctru/include/3ds/services/am.h @@ -1,93 +1,139 @@ #pragma once +#include <3ds/types.h> + /* 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(); -/* AM_GetTitleCount() + +/* AM_TitleIDListGetTotal() About: Gets the number of titles for a given mediatype - mediatype mediatype to get titles from - count ptr to store title count + mediatype mediatype to get titles from + count ptr to store title count */ -Result AM_GetTitleCount(u8 mediatype, u32 *count); +Result AM_TitleIdListGetTotal(u8 mediatype, u32 *count); -/* AM_GetTitleList() + +/* AM_GetTitleIdList() 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 + mediatype mediatype to get list from + count number of titleids to get + titleIDs ptr to buffer to write title IDs 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 + deviceID ptr to where the device id is written to */ -Result AM_GetDeviceId(u32 *deviceid); +Result AM_GetDeviceId(u32 *deviceID); + + +/* AM_GetTitleProductCode() +About: Get the 16 bytes product code of a title + + mediatype mediatype of title + titleID title ID of title + outProductCode pointer to string to store the output product code +*/ +Result AM_GetTitleProductCode(u8 mediatype, u64 titleID, char *outProductCode); + + +/* 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() +/* AM_StartInstallCIADB0() About: Inits CIA install process, the returned ciahandle is where the data for CIA should be written to +Note: This is for title DB 0 (normal title install) - mediatype mediatype to install CIA to - ciahandle ptr to where the handle should be written to + 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_StartInstallCIADB0(u8 mediatype, Handle *ciaHandle); -/* AM_StartDlpChildCiaInstall() + +/* AM_StartInstallCIADB1() About: Inits CIA install process, the returned ciahandle is where the data for CIA should be written to Note: This is for installing DLP CIAs only, mediatype is hardcoded to be NAND - ciahandle ptr to where the handle should be written to + ciaHandle ptr to where the handle should be written to */ -Result AM_StartDlpChildCiaInstall(Handle *ciahandle); +Result AM_StartInstallCIADB1(Handle *ciaHandle); -/* AM_CancelCIAInstall() + +/* AM_AbortCIAInstall() About: Abort CIA install process - ciahandle ptr to cia Handle provided by AM + ciaHandle ptr to cia Handle provided by AM */ -Result AM_CancelCIAInstall(Handle *ciahandle); +Result AM_AbortCIAInstall(Handle *ciaHandle); -/* AM_FinishCiaInstall() + +/* AM_CloseCIAFinalizeInstall() About: Once all data is written to the cia handle, this command signals AM to proceed with CIA install. Note: AM closes the cia handle provided here - mediatype same mediatype specified ciahandle was obtained - ciahandle ptr to cia Handle provided by AM + mediatype same mediatype specified ciaHandle was obtained + ciaHandle ptr to cia Handle provided by AM */ -Result AM_FinishCiaInstall(u8 mediatype, Handle *ciahandle); +Result AM_CloseCIAFinalizeInstall(u8 mediatype, Handle *ciaHandle); + + /**** Title Delete Methods ****/ /* AM_DeleteTitle() About: Deletes any title on NAND/SDMC Note: AM closes the cia handle provided here - mediatype mediatype of title - titleid title id of title + 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 Note: If the title has the system category bit set, this will fail - mediatype mediatype of title - titleid title id of title + 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 Note: The title must have the uniqueid: 0x00000, otherwise this will fail. - mediatype mediatype of title - titleid title id of title + titleID title id of title */ -Result AM_InstallFIRM(u8 mediatype, u64 titleid); \ No newline at end of file +Result AM_InstallFIRM(u64 titleid); diff --git a/libctru/source/services/am.c b/libctru/source/services/am.c index 4105e89..9a2f866 100644 --- a/libctru/source/services/am.c +++ b/libctru/source/services/am.c @@ -1,4 +1,4 @@ -#include +#include #include <3ds/types.h> #include <3ds/svc.h> #include <3ds/srv.h> @@ -19,7 +19,7 @@ Result amExit() return svcCloseHandle(amHandle); } -Result AM_GetTitleCount(u8 mediatype, u32 *count) +Result AM_TitleIdListGetTotal(u8 mediatype, u32 *count) { Result ret = 0; u32 *cmdbuf = getThreadCommandBuffer(); @@ -34,7 +34,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(); @@ -43,14 +43,64 @@ 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_DeleteAppTitle(u8 mediatype, u64 titleID) +{ + Result ret = 0; + u32 *cmdbuf = getThreadCommandBuffer(); + + cmdbuf[0] = 0x000400C0; + cmdbuf[1] = mediatype; + 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 *outProductCode) +{ + Result ret = 0; + u32 *cmdbuf = getThreadCommandBuffer(); + + cmdbuf[0] = 0x000500C0; + cmdbuf[1] = mediatype; + cmdbuf[2] = titleID & 0xffffffff; + cmdbuf[3] = (u32)(titleID >> 32); + + if((ret = svcSendSyncRequest(amHandle))!=0) return ret; + + if(outProductCode) memcpy(outProductCode, &cmdbuf[2], 16); + + return (Result)cmdbuf[1]; +} + +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(); @@ -59,12 +109,26 @@ 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_InstallFIRM(u64 titleID) +{ + Result ret = 0; + u32 *cmdbuf = getThreadCommandBuffer(); + + cmdbuf[0] = 0x04010080; + cmdbuf[1] = titleID & 0xffffffff; + cmdbuf[2] = (u32)(titleID >> 32); + + if((ret = svcSendSyncRequest(amHandle))!=0) return ret; + + return (Result)cmdbuf[1]; +} + +Result AM_StartInstallCIADB0(u8 mediatype, Handle *ciaHandle) { Result ret = 0; u32 *cmdbuf = getThreadCommandBuffer(); @@ -74,12 +138,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_StartInstallCIADB1(Handle *ciaHandle) { Result ret = 0; u32 *cmdbuf = getThreadCommandBuffer(); @@ -88,78 +152,48 @@ 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_AbortCIAInstall(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_CloseCIAFinalizeInstall(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; - - if((ret = svcSendSyncRequest(amHandle))!=0) return ret; - - return (Result)cmdbuf[1]; -} - -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; - - if((ret = svcSendSyncRequest(amHandle))!=0) return ret; - - return (Result)cmdbuf[1]; -} - -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;