diff --git a/libctru/include/3ds/services/am.h b/libctru/include/3ds/services/am.h new file mode 100644 index 0000000..79da46f --- /dev/null +++ b/libctru/include/3ds/services/am.h @@ -0,0 +1,93 @@ +#pragma once + +/* + Requires access to "am:net" or "am:u" service +*/ + +Result amInit(); +Result amExit(); + +/* AM_GetTitleCount() +About: Gets the number of titles for a given mediatype + + mediatype mediatype to get titles from + count ptr to store title count +*/ +Result AM_GetTitleCount(u8 mediatype, u32 *count); + +/* AM_GetTitleList() +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 +*/ +Result AM_GetTitleList(u8 mediatype, u32 count, void *buffer); + +/* 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); + +/**** Title Install Methods ****/ +/* AM_StartCiaInstall() +About: Inits CIA install process, the returned ciahandle is where the data for CIA 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); + +/* AM_StartDlpChildCiaInstall() +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 +*/ +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); + +/* AM_FinishCiaInstall() +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 +*/ +Result AM_FinishCiaInstall(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 +*/ +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 +*/ +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 +*/ +Result AM_InstallFIRM(u8 mediatype, u64 titleid); \ No newline at end of file diff --git a/libctru/source/services/am.c b/libctru/source/services/am.c new file mode 100644 index 0000000..aa57541 --- /dev/null +++ b/libctru/source/services/am.c @@ -0,0 +1,164 @@ +#include +#include <3ds.h> + +static Handle amHandle = 0; + +Result amInit() +{ + if(srvGetServiceHandle(&amHandle, "am:net") == 0) + return (Result)0; + else + return srvGetServiceHandle(&amHandle, "am:u"); +} + +Result amExit() +{ + return svcCloseHandle(amHandle); +} + +Result AM_GetTitleCount(u8 mediatype, u32 *count) +{ + Result ret = 0; + u32 *cmdbuf = getThreadCommandBuffer(); + + cmdbuf[0] = 0x00010040; + cmdbuf[1] = mediatype; + + if((ret = svcSendSyncRequest(amHandle))!=0) return ret; + + *count = cmdbuf[2]; + + return (Result)cmdbuf[1]; +} + +Result AM_GetTitleList(u8 mediatype, u32 count, void *buffer) +{ + Result ret = 0; + u32 *cmdbuf = getThreadCommandBuffer(); + + cmdbuf[0] = 0x00020082; + cmdbuf[1] = count; + cmdbuf[2] = mediatype; + cmdbuf[3] = ((count*8) << 4) | 12; + cmdbuf[4] = (u32)buffer; + + if((ret = svcSendSyncRequest(amHandle))!=0) return ret; + + return (Result)cmdbuf[1]; +} + +Result AM_GetDeviceId(u32 *deviceid) +{ + Result ret = 0; + u32 *cmdbuf = getThreadCommandBuffer(); + + cmdbuf[0] = 0x000A0000; + + if((ret = svcSendSyncRequest(amHandle))!=0) return ret; + + *deviceid = cmdbuf[3]; + + return (Result)cmdbuf[1]; +} + +Result AM_StartCiaInstall(u8 mediatype, Handle *ciahandle) +{ + Result ret = 0; + u32 *cmdbuf = getThreadCommandBuffer(); + + cmdbuf[0] = 0x04020040; + cmdbuf[1] = mediatype; + + if((ret = svcSendSyncRequest(amHandle))!=0) return ret; + + *ciahandle = cmdbuf[3]; + + return (Result)cmdbuf[1]; +} + +Result AM_StartDlpChildCiaInstall(Handle *ciahandle) +{ + Result ret = 0; + u32 *cmdbuf = getThreadCommandBuffer(); + + cmdbuf[0] = 0x04030000; + + if((ret = svcSendSyncRequest(amHandle))!=0) return ret; + + *ciahandle = cmdbuf[3]; + + return (Result)cmdbuf[1]; +} + +Result AM_CancelCIAInstall(Handle *ciahandle) +{ + Result ret = 0; + u32 *cmdbuf = getThreadCommandBuffer(); + + cmdbuf[0] = 0x04050002; + cmdbuf[1] = 0x10; + cmdbuf[2] = *ciahandle; + + if((ret = svcSendSyncRequest(amHandle))!=0) return ret; + + return (Result)cmdbuf[1]; +} + +Result AM_FinishCiaInstall(u8 mediatype, Handle *ciahandle) +{ + Result ret = 0; + u32 *cmdbuf = getThreadCommandBuffer(); + + cmdbuf[0] = 0x04040002; + cmdbuf[1] = 0x10; + cmdbuf[2] = *ciahandle; + + if((ret = svcSendSyncRequest(amHandle))!=0) return ret; + + return (Result)cmdbuf[1]; +} + +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; + + if((ret = svcSendSyncRequest(amHandle))!=0) return ret; + + return (Result)cmdbuf[1]; +}