diff --git a/nx/include/switch/services/ns.h b/nx/include/switch/services/ns.h index 98c8358b..bf9d65eb 100644 --- a/nx/include/switch/services/ns.h +++ b/nx/include/switch/services/ns.h @@ -14,9 +14,31 @@ typedef struct { u8 icon[0x20000];//JPEG } NsApplicationControlData; +typedef struct +{ + u8 title_type; + u8 storageID; + u8 unk_x02; + u8 padding; + u32 title_version; + u64 titleID; +} NsApplicationContentMetaStatus; + +typedef struct +{ + u64 titleID; + u8 type; + u8 unk_x09; + u8 unk_x0A[6]; + u8 unk_x10; + u8 unk_x11[7]; +} NsApplicationRecord; + Result nsInitialize(void); void nsExit(void); +Result nsListApplicationRecord(NsApplicationRecord* buffer, size_t size, size_t entry_offset, size_t* out_entrycount); +Result nsListApplicationContentMetaStatus(u64 titleID, u32 index, NsApplicationContentMetaStatus* buffer, size_t size, size_t* out_entrycount); Result nsGetApplicationControlData(u8 flag, u64 titleID, NsApplicationControlData* buffer, size_t size, size_t* actual_size); /** @@ -44,4 +66,4 @@ Result nsdevInitialize(); void nsdevExit(); Result nsdevTerminateProcess(u64 pid); -Result nsdevTerminateProgram(u64 tid); \ No newline at end of file +Result nsdevTerminateProgram(u64 tid); diff --git a/nx/source/services/ns.c b/nx/source/services/ns.c index 3cc05cda..384803c2 100644 --- a/nx/source/services/ns.c +++ b/nx/source/services/ns.c @@ -92,6 +92,84 @@ static Result _nsGetInterface(Service* srv_out, u64 cmd_id) { return rc; } +Result nsListApplicationRecord(NsApplicationRecord* buffer, size_t size, size_t entry_offset, size_t* out_entrycount) +{ + IpcCommand c; + ipcInitialize(&c); + ipcAddRecvBuffer(&c, buffer, size, 0); + + struct { + u64 magic; + u64 cmd_id; + u32 entry_offset; + } *raw; + + raw = ipcPrepareHeader(&c, sizeof(*raw)); + + raw->magic = SFCI_MAGIC; + raw->cmd_id = 0; + raw->entry_offset = entry_offset; + + Result rc = serviceIpcDispatch(&g_nsAppManSrv); + + if (R_SUCCEEDED(rc)) { + IpcParsedCommand r; + ipcParse(&r); + + struct { + u64 magic; + u64 result; + u32 entry_count; + } *resp = r.Raw; + + rc = resp->result; + + if (R_SUCCEEDED(rc) && out_entrycount) *out_entrycount = resp->entry_count; + } + + return rc; +} + +Result nsListApplicationContentMetaStatus(u64 titleID, u32 index, NsApplicationContentMetaStatus* buffer, size_t size, size_t* out_entrycount) +{ + IpcCommand c; + ipcInitialize(&c); + ipcAddRecvBuffer(&c, buffer, size, 0); + + struct { + u64 magic; + u64 cmd_id; + u32 index; + u64 titleID; + } *raw; + + raw = ipcPrepareHeader(&c, sizeof(*raw)); + + raw->magic = SFCI_MAGIC; + raw->cmd_id = 601; + raw->index = index; + raw->titleID = titleID; + + Result rc = serviceIpcDispatch(&g_nsAppManSrv); + + if (R_SUCCEEDED(rc)) { + IpcParsedCommand r; + ipcParse(&r); + + struct { + u64 magic; + u64 result; + u32 entry_count; + } *resp = r.Raw; + + rc = resp->result; + + if (R_SUCCEEDED(rc) && out_entrycount) *out_entrycount = resp->entry_count; + } + + return rc; +} + Result nsGetApplicationControlData(u8 flag, u64 titleID, NsApplicationControlData* buffer, size_t size, size_t* actual_size) { IpcCommand c; ipcInitialize(&c);