From 1a6bdc38a99e4a9dff7e91539c8077c20fc55a2a Mon Sep 17 00:00:00 2001 From: profi200 Date: Sat, 7 Mar 2015 18:37:43 +0100 Subject: [PATCH 1/3] Implemented functions to start system applets. --- libctru/include/3ds/services/am.h | 2 +- libctru/include/3ds/services/apt.h | 2 ++ libctru/source/services/apt.c | 33 ++++++++++++++++++++++++++++++ 3 files changed, 36 insertions(+), 1 deletion(-) diff --git a/libctru/include/3ds/services/am.h b/libctru/include/3ds/services/am.h index 3eb1501..eaf7379 100644 --- a/libctru/include/3ds/services/am.h +++ b/libctru/include/3ds/services/am.h @@ -8,7 +8,7 @@ typedef struct { u64 titleID; - u64 unknown; + u64 size; u16 titleVersion; u8 unknown2[6]; } TitleList; diff --git a/libctru/include/3ds/services/apt.h b/libctru/include/3ds/services/apt.h index 15db7b7..368731c 100644 --- a/libctru/include/3ds/services/apt.h +++ b/libctru/include/3ds/services/apt.h @@ -82,4 +82,6 @@ Result APT_DoAppJump(Handle* handle, u32 NSbuf0Size, u32 NSbuf1Size, u8 *NSbuf0P Result APT_PrepareToStartLibraryApplet(Handle* handle, NS_APPID appID); Result APT_StartLibraryApplet(Handle* handle, NS_APPID appID, Handle inhandle, u32 *parambuf, u32 parambufsize); Result APT_LaunchLibraryApplet(NS_APPID appID, Handle inhandle, u32 *parambuf, u32 parambufsize);//This should be used for launching library applets, this uses the above APT_StartLibraryApplet/APT_PrepareToStartLibraryApplet funcs + apt*Session(). parambuf is used for APT params input, when the applet closes the output param block is copied here. This is not usable from the homebrew launcher. This is broken: when the applet does get launched at all, the applet process doesn't actually get terminated when the applet gets closed. +Result APT_PrepareToStartSystemApplet(Handle* handle, NS_APPID appID); +Result APT_StartSystemApplet(Handle* handle, NS_APPID appID, u32 bufSize, Handle applHandle, u8 *buf); diff --git a/libctru/source/services/apt.c b/libctru/source/services/apt.c index 9560c79..036b097 100644 --- a/libctru/source/services/apt.c +++ b/libctru/source/services/apt.c @@ -1155,3 +1155,36 @@ Result APT_LaunchLibraryApplet(NS_APPID appID, Handle inhandle, u32 *parambuf, u return 0; } +Result APT_PrepareToStartSystemApplet(Handle* handle, NS_APPID appID) +{ + if(!handle)handle=&aptuHandle; + + u32* cmdbuf=getThreadCommandBuffer(); + cmdbuf[0]=0x00190040; //request header code + cmdbuf[1]=appID; + + Result ret=0; + if((ret=svcSendSyncRequest(*handle)))return ret; + + return cmdbuf[1]; +} + +Result APT_StartSystemApplet(Handle* handle, NS_APPID appID, u32 bufSize, Handle applHandle, u8 *buf) +{ + if(!handle)handle=&aptuHandle; + + u32* cmdbuf=getThreadCommandBuffer(); + cmdbuf[0] = 0x001F0084; //request header code + cmdbuf[1] = appID; + cmdbuf[2] = bufSize; + cmdbuf[3] = 0; + cmdbuf[4] = applHandle; + cmdbuf[5] = (bufSize<<14) | 2; + cmdbuf[6] = (u32)buf; + + Result ret=0; + if((ret=svcSendSyncRequest(*handle)))return ret; + + return cmdbuf[1]; +} + From 57f139799ca1bee3199c1869cf2f9b84454fccd0 Mon Sep 17 00:00:00 2001 From: patois Date: Mon, 9 Mar 2015 04:54:03 +0100 Subject: [PATCH 2/3] add syscalls 0x61, 0x62, 0x63, 0x64 --- libctru/include/3ds/svc.h | 138 ++++++++++++++++++++++++++++++++++++++ libctru/source/svc.s | 24 +++++++ 2 files changed, 162 insertions(+) diff --git a/libctru/include/3ds/svc.h b/libctru/include/3ds/svc.h index 14dfb4e..08a25ab 100644 --- a/libctru/include/3ds/svc.h +++ b/libctru/include/3ds/svc.h @@ -15,6 +15,21 @@ typedef enum { MEMOP_ALLOC_LINEAR=0x10003 // Allocate linear heap } MemOp; +typedef enum { + MEMSTATE_FREE = 0, + MEMSTATE_RESERVED = 1, + MEMSTATE_IO = 2, + MEMSTATE_STATIC = 3, + MEMSTATE_CODE = 4, + MEMSTATE_PRIVATE = 5, + MEMSTATE_SHARED = 6, + MEMSTATE_CONTINUOUS = 7, + MEMSTATE_ALIASED = 8, + MEMSTATE_ALIAS = 9, + MEMSTATE_ALIASCODE = 10, + MEMSTATE_LOCKED = 11 +} MemState; + typedef enum { MEMPERM_READ = 1, MEMPERM_WRITE = 2, @@ -42,6 +57,125 @@ typedef enum { ARBITER_KERNEL4 =4, } ArbitrationType; +typedef enum { + DBG_EVENT_PROCESS = 0, + DBG_EVENT_CREATE_THREAD = 1, + DBG_EVENT_EXIT_THREAD = 2, + DBG_EVENT_EXIT_PROCESS = 3, + DBG_EVENT_EXCEPTION = 4, + DBG_EVENT_DLL_LOAD = 5, + DBG_EVENT_DLL_UNLOAD = 6, + DBG_EVENT_SCHEDULE_IN = 7, + DBG_EVENT_SCHEDULE_OUT = 8, + DBG_EVENT_SYSCALL_IN = 9, + DBG_EVENT_SYSCALL_OUT = 10, + DBG_EVENT_OUTPUT_STRING = 11, + DBG_EVENT_MAP = 12 +} DebugEventType; + +typedef enum { + REASON_CREATE = 1, + REASON_ATTACH = 2 +} ProcessEventReason; + +typedef struct { + u64 program_id; + u8 process_name[8]; + u32 process_id; + u32 reason; +} ProcessEvent; + +typedef struct { + u32 creator_thread_id; + u32 base_addr; + u32 entry_point; +} CreateThreadEvent; + +typedef enum { + EXITTHREAD_EVENT_NONE = 0, + EXITTHREAD_EVENT_TERMINATE = 1, + EXITTHREAD_EVENT_UNHANDLED_EXC = 2, + EXITTHREAD_EVENT_TERMINATE_PROCESS = 3 +} ExitThreadEventReason; + +typedef enum { + EXITPROCESS_EVENT_NONE = 0, + EXITPROCESS_EVENT_TERMINATE = 1, + EXITPROCESS_EVENT_UNHANDLED_EXCEPTION = 2 +} ExitProcessEventReason; + +typedef struct { + u32 reason; +} ExitProcessEvent; + +typedef struct { + u32 reason; +} ExitThreadEvent; + +typedef struct { + u32 type; + u32 address; + u32 argument; +} ExceptionEvent; + +typedef enum { + EXC_EVENT_UNDEFINED_INSTRUCTION = 0, // arg: (None) + EXC_EVENT_UNKNOWN1 = 1, // arg: (None) + EXC_EVENT_UNKNOWN2 = 2, // arg: address + EXC_EVENT_UNKNOWN3 = 3, // arg: address + EXC_EVENT_ATTACH_BREAK = 4, // arg: (None) + EXC_EVENT_BREAKPOINT = 5, // arg: (None) + EXC_EVENT_USER_BREAK = 6, // arg: user break type + EXC_EVENT_DEBUGGER_BREAK = 7, // arg: (None) + EXC_EVENT_UNDEFINED_SYSCALL = 8 // arg: attempted syscall +} ExceptionEventType; + +typedef enum { + USERBREAK_PANIC = 0, + USERBREAK_ASSERT = 1, + USERBREAK_USER = 2 +} UserBreakType; + +typedef struct { + u64 clock_tick; +} SchedulerInOutEvent; + +typedef struct { + u64 clock_tick; + u32 syscall; +} SyscallInOutEvent; + +typedef struct { + u32 string_addr; + u32 string_size; +} OutputStringEvent; + +typedef struct { + u32 mapped_addr; + u32 mapped_size; + u32 memperm; + u32 memstate; +} MapEvent; + +typedef struct { + u32 type; + u32 thread_id; + u32 unknown[2]; + union { + ProcessEvent process; + CreateThreadEvent create_thread; + ExitThreadEvent exit_thread; + ExitProcessEvent exit_process; + ExceptionEvent exception; + /* TODO: DLL_LOAD */ + /* TODO: DLL_UNLOAD */ + SchedulerInOutEvent scheduler; + SyscallInOutEvent syscall; + OutputStringEvent output_string; + MapEvent map; + }; +} DebugEventInfo; + static inline void* getThreadLocalStorage(void) { void* ret; @@ -92,6 +226,10 @@ s32 svcGetThreadId(u32 *out, Handle handle); s32 svcOutputDebugString(const char* str, int length); Result svcCreatePort(Handle* portServer, Handle* portClient, const char* name, s32 maxSessions); Result svcDebugActiveProcess(Handle* debug, u32 processId); +Result svcBreakDebugProcess(Handle debug); +Result svcTerminateDebugProcess(Handle debug); +Result svcGetProcessDebugEvent(DebugEventInfo *info, Handle debug); +Result svcContinueDebugEvent(Handle debug, u32 flags); Result svcGetProcessList(s32* processCount, u32* processIds, s32 processIdMaxCount); Result svcReadProcessMemory(void* buffer, Handle debug, u32 addr, u32 size); Result svcMapProcessMemory(Handle process, u32 startAddr, u32 endAddr); diff --git a/libctru/source/svc.s b/libctru/source/svc.s index af0d8a2..534a944 100644 --- a/libctru/source/svc.s +++ b/libctru/source/svc.s @@ -319,6 +319,30 @@ svcDebugActiveProcess: str r1, [r2] bx lr +.global svcBreakDebugProcess +.type svcBreakDebugProcess, %function +svcBreakDebugProcess: + svc 0x61 + bx lr + +.global svcTerminateDebugProcess +.type svcTerminateDebugProcess, %function +svcTerminateDebugProcess: + svc 0x62 + bx lr + +.global svcGetProcessDebugEvent +.type svcGetProcessDebugEvent, %function +svcGetProcessDebugEvent: + svc 0x63 + bx lr + +.global svcContinueDebugEvent +.type svcContinueDebugEvent, %function +svcContinueDebugEvent: + svc 0x64 + bx lr + .global svcGetProcessList .type svcGetProcessList, %function svcGetProcessList: From 85261971db831f09501fe8a98a376b063b5e9b82 Mon Sep 17 00:00:00 2001 From: Dave Murphy Date: Wed, 11 Mar 2015 16:46:03 +0000 Subject: [PATCH 3/3] use correct flags --- libctru/source/services/csnd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libctru/source/services/csnd.c b/libctru/source/services/csnd.c index 82767a9..29b8c66 100644 --- a/libctru/source/services/csnd.c +++ b/libctru/source/services/csnd.c @@ -405,7 +405,7 @@ Result csndPlaySound(int chn, u32 flags, u32 sampleRate, void* data0, void* data int encoding = (flags >> 12) & 3; int loopMode = (flags >> 10) & 3; - if (!loopMode) flags |= CSND_LOOPMODE_ONESHOT; + if (!loopMode) flags |= SOUND_ONE_SHOT; if (encoding != CSND_ENCODING_PSG) {