mirror of
https://github.com/switchbrew/libnx.git
synced 2025-08-06 08:19:22 +02:00
Introducing ipc domains, bsd stuff
This commit is contained in:
parent
fb1d6f4d5c
commit
003e300e83
@ -46,6 +46,11 @@ typedef struct {
|
|||||||
u32 Addr;
|
u32 Addr;
|
||||||
} IpcStaticSendDescriptor;
|
} IpcStaticSendDescriptor;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
u32 Addr;
|
||||||
|
u32 Packed;
|
||||||
|
} IpcStaticRecvDescriptor;
|
||||||
|
|
||||||
static inline void ipcAddSendBuffer(IpcCommand* cmd, void* buffer, size_t size, u8 flags) {
|
static inline void ipcAddSendBuffer(IpcCommand* cmd, void* buffer, size_t size, u8 flags) {
|
||||||
size_t off = cmd->NumSend;
|
size_t off = cmd->NumSend;
|
||||||
cmd->Buffers[off] = buffer;
|
cmd->Buffers[off] = buffer;
|
||||||
@ -103,8 +108,17 @@ static inline void* ipcPrepareHeader(IpcCommand* cmd, size_t sizeof_raw) {
|
|||||||
size_t i;
|
size_t i;
|
||||||
*buf++ = 4 | (cmd->NumStaticIn << 16) | (cmd->NumSend << 20) | (cmd->NumRecv << 24) | (cmd->NumTransfer << 28);
|
*buf++ = 4 | (cmd->NumStaticIn << 16) | (cmd->NumSend << 20) | (cmd->NumRecv << 24) | (cmd->NumTransfer << 28);
|
||||||
|
|
||||||
|
u32* fill_in_size_later = buf;
|
||||||
|
|
||||||
|
if (cmd->NumStaticOut > 0) {
|
||||||
|
*buf = (cmd->NumStaticOut + 2) << 10;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
*buf = 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (cmd->SendPid || cmd->NumHandlesCopy > 0 || cmd->NumHandlesMove > 0) {
|
if (cmd->SendPid || cmd->NumHandlesCopy > 0 || cmd->NumHandlesMove > 0) {
|
||||||
*buf++ = (sizeof_raw/4) | 0x80000000;
|
*buf++ |= 0x80000000;
|
||||||
*buf++ = (!!cmd->SendPid) | (cmd->NumHandlesCopy << 1) | (cmd->NumHandlesMove << 5);
|
*buf++ = (!!cmd->SendPid) | (cmd->NumHandlesCopy << 1) | (cmd->NumHandlesMove << 5);
|
||||||
|
|
||||||
if (cmd->SendPid)
|
if (cmd->SendPid)
|
||||||
@ -114,7 +128,7 @@ static inline void* ipcPrepareHeader(IpcCommand* cmd, size_t sizeof_raw) {
|
|||||||
*buf++ = cmd->Handles[i];
|
*buf++ = cmd->Handles[i];
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
*buf++ = sizeof_raw/4;
|
buf++;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i=0; i<cmd->NumStaticIn; i++, buf+=2) {
|
for (i=0; i<cmd->NumStaticIn; i++, buf+=2) {
|
||||||
@ -136,14 +150,32 @@ static inline void* ipcPrepareHeader(IpcCommand* cmd, size_t sizeof_raw) {
|
|||||||
(((ptr >> 32) & 15) << 28) | ((ptr >> 36) << 2);
|
(((ptr >> 32) & 15) << 28) | ((ptr >> 36) << 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
// todo: More
|
u32 padding = ((16 - (((uintptr_t) buf) & 15)) & 15) / 4;
|
||||||
return (void*) ((((uintptr_t)buf) + 15) &~ 15);
|
u32* raw = (u32*) (buf + padding);
|
||||||
|
|
||||||
|
size_t raw_size = (sizeof_raw/4) + 4;
|
||||||
|
raw_size += ((cmd->NumStaticOut*2) + 3)/4; // todo: these contain u16 lengths for StaticOuts
|
||||||
|
|
||||||
|
buf += raw_size;
|
||||||
|
*fill_in_size_later |= raw_size;
|
||||||
|
|
||||||
|
for (i=0; i<cmd->NumStaticOut; i++, buf+=2) {
|
||||||
|
IpcStaticRecvDescriptor* desc = (IpcStaticRecvDescriptor*) buf;
|
||||||
|
size_t off = cmd->NumStaticIn + i;
|
||||||
|
|
||||||
|
uintptr_t ptr = (uintptr_t) cmd->Statics[off];
|
||||||
|
desc->Addr = ptr;
|
||||||
|
desc->Packed = (ptr >> 32) | (cmd->StaticSizes[off] << 16);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (void*) raw;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline Result ipcDispatch(Handle session) {
|
static inline Result ipcDispatch(Handle session) {
|
||||||
return svcSendSyncRequest(session);
|
return svcSendSyncRequest(session);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Response parsing
|
||||||
typedef struct {
|
typedef struct {
|
||||||
bool HasPid;
|
bool HasPid;
|
||||||
u64 Pid;
|
u64 Pid;
|
||||||
@ -211,3 +243,67 @@ static inline Result ipcParseResponse(IpcCommandResponse* r) {
|
|||||||
r->NumBuffers = num_bufs;
|
r->NumBuffers = num_bufs;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Domain shit
|
||||||
|
static inline Result ipcConvertSessionToDomain(Handle session, u32* object_id_out) {
|
||||||
|
u32* buf = armGetTls();
|
||||||
|
|
||||||
|
buf[0] = 5;
|
||||||
|
buf[1] = 8;
|
||||||
|
buf[4] = SFCI_MAGIC;
|
||||||
|
buf[5] = 0;
|
||||||
|
buf[6] = 0;
|
||||||
|
buf[7] = 0;
|
||||||
|
|
||||||
|
Result rc = ipcDispatch(session);
|
||||||
|
|
||||||
|
if (R_SUCCEEDED(rc)) {
|
||||||
|
IpcCommandResponse r;
|
||||||
|
ipcParseResponse(&r);
|
||||||
|
|
||||||
|
struct {
|
||||||
|
u64 magic;
|
||||||
|
u64 result;
|
||||||
|
u32 object_id;
|
||||||
|
} *raw = r.Raw;
|
||||||
|
|
||||||
|
rc = raw->result;
|
||||||
|
|
||||||
|
if (R_SUCCEEDED(rc)) {
|
||||||
|
*object_id_out = raw->object_id;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
u8 Type;
|
||||||
|
u8 Pad0;
|
||||||
|
u16 Length;
|
||||||
|
u32 ObjectId;
|
||||||
|
u32 Pad1[2];
|
||||||
|
} DomainMessageHeader;
|
||||||
|
|
||||||
|
static inline void* ipcPrepareHeaderForDomain(IpcCommand* cmd, size_t sizeof_raw, size_t object_id) {
|
||||||
|
void* raw = ipcPrepareHeader(cmd, sizeof_raw + sizeof(DomainMessageHeader));
|
||||||
|
DomainMessageHeader* hdr = (DomainMessageHeader*) raw;
|
||||||
|
|
||||||
|
hdr->Type = 1;
|
||||||
|
hdr->Length = sizeof_raw;
|
||||||
|
hdr->ObjectId = object_id;
|
||||||
|
|
||||||
|
hdr->Pad0 = hdr->Pad1[0] = hdr->Pad1[1] = 0;
|
||||||
|
|
||||||
|
return (void*)(((uintptr_t) raw) + sizeof(DomainMessageHeader));
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline Result ipcParseResponseForDomain(IpcCommandResponse* r) {
|
||||||
|
Result rc = ipcParseResponse(r);
|
||||||
|
|
||||||
|
if (R_SUCCEEDED(rc)) {
|
||||||
|
r->Raw = (void*)(((uintptr_t) r->Raw) + sizeof(DomainMessageHeader));
|
||||||
|
}
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
@ -4,6 +4,9 @@ int bsdConnect(int sockfd, void* addr, u32 addrlen);
|
|||||||
int bsdSocket(int domain, int type, int protocol);
|
int bsdSocket(int domain, int type, int protocol);
|
||||||
int bsdBind(int sockfd, void* addr, u32 addrlen);
|
int bsdBind(int sockfd, void* addr, u32 addrlen);
|
||||||
int bsdListen(int sockfd, int backlog);
|
int bsdListen(int sockfd, int backlog);
|
||||||
|
int bsdSend(int sockfd, void* buffer, size_t length, int flags);
|
||||||
|
int bsdRecv(int sockfd, void* buffer, size_t length, int flags);
|
||||||
|
int bsdWrite(int sockfd, void* buffer, size_t length);
|
||||||
|
|
||||||
#define BSD_AF_INET 2
|
#define BSD_AF_INET 2
|
||||||
#define BSD_AF_INET6 10
|
#define BSD_AF_INET6 10
|
||||||
@ -11,6 +14,8 @@ int bsdListen(int sockfd, int backlog);
|
|||||||
#define BSD_SOCK_STREAM 1
|
#define BSD_SOCK_STREAM 1
|
||||||
#define BSD_SOCK_DGRAM 2
|
#define BSD_SOCK_DGRAM 2
|
||||||
|
|
||||||
|
#define BSD_MSG_RECV_ALL 0x40
|
||||||
|
|
||||||
struct bsd_sockaddr_in {
|
struct bsd_sockaddr_in {
|
||||||
u8 sin_len;
|
u8 sin_len;
|
||||||
u8 sin_family;
|
u8 sin_family;
|
||||||
|
@ -32,7 +32,7 @@ void heapInit(void* base, size_t size) {
|
|||||||
|
|
||||||
void heapSetup() {
|
void heapSetup() {
|
||||||
// Called by crt0.
|
// Called by crt0.
|
||||||
#define HEAP_SIZE 0x20000
|
#define HEAP_SIZE 0x2000000
|
||||||
static u8 g_Heap[HEAP_SIZE];
|
static u8 g_Heap[HEAP_SIZE];
|
||||||
heapInit(&g_Heap[0], HEAP_SIZE);
|
heapInit(&g_Heap[0], HEAP_SIZE);
|
||||||
}
|
}
|
||||||
|
@ -2,8 +2,11 @@
|
|||||||
#include <switch.h>
|
#include <switch.h>
|
||||||
|
|
||||||
static Handle g_bsdHandle = -1;
|
static Handle g_bsdHandle = -1;
|
||||||
|
static u32 g_bsdObjectId = -1;
|
||||||
static int g_Errno = 0;
|
static int g_Errno = 0;
|
||||||
|
|
||||||
|
#define EPIPE 32
|
||||||
|
|
||||||
Result bsdInitialize(TransferMemory* tmem) {
|
Result bsdInitialize(TransferMemory* tmem) {
|
||||||
Result rc = smGetService(&g_bsdHandle, "bsd:s");
|
Result rc = smGetService(&g_bsdHandle, "bsd:s");
|
||||||
|
|
||||||
@ -29,10 +32,10 @@ Result bsdInitialize(TransferMemory* tmem) {
|
|||||||
|
|
||||||
raw->magic = SFCI_MAGIC;
|
raw->magic = SFCI_MAGIC;
|
||||||
raw->cmd_id = 0;
|
raw->cmd_id = 0;
|
||||||
raw->unk0[0] = 0;
|
raw->unk0[0] = 0x4000;
|
||||||
raw->unk0[1] = 0;
|
raw->unk0[1] = 0x4000;
|
||||||
raw->unk0[2] = 0;
|
raw->unk0[2] = 0x4000;
|
||||||
raw->unk0[3] = 0;
|
raw->unk0[3] = 0x4000;
|
||||||
raw->unk0[4] = 0;
|
raw->unk0[4] = 0;
|
||||||
raw->tmem_sz = tmem->Size;
|
raw->tmem_sz = tmem->Size;
|
||||||
|
|
||||||
@ -48,9 +51,17 @@ Result bsdInitialize(TransferMemory* tmem) {
|
|||||||
} *resp = r.Raw;
|
} *resp = r.Raw;
|
||||||
|
|
||||||
rc = resp->result;
|
rc = resp->result;
|
||||||
|
|
||||||
|
if (R_SUCCEEDED(rc)) {
|
||||||
|
rc = ipcConvertSessionToDomain(g_bsdHandle, &g_bsdObjectId);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (R_FAILED(rc)) {
|
||||||
|
g_Errno = EPIPE;
|
||||||
|
}
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -71,7 +82,7 @@ int bsdSocket(int domain, int type, int protocol) {
|
|||||||
u32 pad[4];
|
u32 pad[4];
|
||||||
} *raw;
|
} *raw;
|
||||||
|
|
||||||
raw = ipcPrepareHeader(&c, sizeof(*raw));
|
raw = ipcPrepareHeaderForDomain(&c, sizeof(*raw), g_bsdObjectId);
|
||||||
|
|
||||||
raw->magic = SFCI_MAGIC;
|
raw->magic = SFCI_MAGIC;
|
||||||
raw->cmd_id = 2;
|
raw->cmd_id = 2;
|
||||||
@ -84,7 +95,7 @@ int bsdSocket(int domain, int type, int protocol) {
|
|||||||
|
|
||||||
if (R_SUCCEEDED(rc)) {
|
if (R_SUCCEEDED(rc)) {
|
||||||
IpcCommandResponse r;
|
IpcCommandResponse r;
|
||||||
ipcParseResponse(&r);
|
ipcParseResponseForDomain(&r);
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
u64 magic;
|
u64 magic;
|
||||||
@ -101,8 +112,109 @@ int bsdSocket(int domain, int type, int protocol) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (R_FAILED(rc)) {
|
||||||
|
g_Errno = EPIPE;
|
||||||
|
}
|
||||||
|
|
||||||
return fd;
|
return fd;
|
||||||
}
|
}
|
||||||
|
int bsdRecv(int sockfd, void* buffer, size_t length, int flags) {
|
||||||
|
IpcCommand c;
|
||||||
|
ipcInitialize(&c);
|
||||||
|
ipcAddRecvBuffer(&c, buffer, length, 0);
|
||||||
|
ipcAddRecvStatic(&c, buffer, length, 0);
|
||||||
|
|
||||||
|
struct {
|
||||||
|
u64 magic;
|
||||||
|
u64 cmd_id;
|
||||||
|
u32 sockfd;
|
||||||
|
u32 flags;
|
||||||
|
} *raw;
|
||||||
|
|
||||||
|
raw = ipcPrepareHeaderForDomain(&c, sizeof(*raw), g_bsdObjectId);
|
||||||
|
|
||||||
|
raw->magic = SFCI_MAGIC;
|
||||||
|
raw->cmd_id = 8;
|
||||||
|
raw->sockfd = sockfd;
|
||||||
|
raw->flags = flags;
|
||||||
|
|
||||||
|
Result rc = ipcDispatch(g_bsdHandle);
|
||||||
|
int ret = -1;
|
||||||
|
|
||||||
|
if (R_SUCCEEDED(rc)) {
|
||||||
|
IpcCommandResponse r;
|
||||||
|
ipcParseResponseForDomain(&r);
|
||||||
|
|
||||||
|
struct {
|
||||||
|
u64 magic;
|
||||||
|
u64 result;
|
||||||
|
u32 ret;
|
||||||
|
u32 errno;
|
||||||
|
} *resp = r.Raw;
|
||||||
|
|
||||||
|
rc = resp->result;
|
||||||
|
|
||||||
|
if (R_SUCCEEDED(rc)) {
|
||||||
|
g_Errno = resp->errno;
|
||||||
|
ret = resp->ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (R_FAILED(rc)) {
|
||||||
|
g_Errno = rc; //EPIPE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int bsdSend(int sockfd, void* buffer, size_t length, int flags) {
|
||||||
|
IpcCommand c;
|
||||||
|
ipcInitialize(&c);
|
||||||
|
ipcAddSendBuffer(&c, buffer, length, 0);
|
||||||
|
ipcAddSendStatic(&c, buffer, length, 0);
|
||||||
|
|
||||||
|
struct {
|
||||||
|
u64 magic;
|
||||||
|
u64 cmd_id;
|
||||||
|
u32 sockfd;
|
||||||
|
u32 flags;
|
||||||
|
} *raw;
|
||||||
|
|
||||||
|
raw = ipcPrepareHeaderForDomain(&c, sizeof(*raw), g_bsdObjectId);
|
||||||
|
|
||||||
|
raw->magic = SFCI_MAGIC;
|
||||||
|
raw->cmd_id = 10;
|
||||||
|
raw->sockfd = sockfd;
|
||||||
|
raw->flags = flags;
|
||||||
|
|
||||||
|
Result rc = ipcDispatch(g_bsdHandle);
|
||||||
|
int ret = -1;
|
||||||
|
|
||||||
|
if (R_SUCCEEDED(rc)) {
|
||||||
|
IpcCommandResponse r;
|
||||||
|
ipcParseResponseForDomain(&r);
|
||||||
|
|
||||||
|
struct {
|
||||||
|
u64 magic;
|
||||||
|
u64 result;
|
||||||
|
u32 ret;
|
||||||
|
u32 errno;
|
||||||
|
} *resp = r.Raw;
|
||||||
|
|
||||||
|
rc = resp->result;
|
||||||
|
|
||||||
|
if (R_SUCCEEDED(rc)) {
|
||||||
|
g_Errno = resp->errno;
|
||||||
|
ret = resp->ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (R_FAILED(rc)) {
|
||||||
|
g_Errno = EPIPE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
int bsdConnect(int sockfd, void* addr, u32 addrlen) {
|
int bsdConnect(int sockfd, void* addr, u32 addrlen) {
|
||||||
IpcCommand c;
|
IpcCommand c;
|
||||||
@ -117,7 +229,7 @@ int bsdConnect(int sockfd, void* addr, u32 addrlen) {
|
|||||||
u32 pad[4];
|
u32 pad[4];
|
||||||
} *raw;
|
} *raw;
|
||||||
|
|
||||||
raw = ipcPrepareHeader(&c, sizeof(*raw));
|
raw = ipcPrepareHeaderForDomain(&c, sizeof(*raw), g_bsdObjectId);
|
||||||
|
|
||||||
raw->magic = SFCI_MAGIC;
|
raw->magic = SFCI_MAGIC;
|
||||||
raw->cmd_id = 14;
|
raw->cmd_id = 14;
|
||||||
@ -128,7 +240,7 @@ int bsdConnect(int sockfd, void* addr, u32 addrlen) {
|
|||||||
|
|
||||||
if (R_SUCCEEDED(rc)) {
|
if (R_SUCCEEDED(rc)) {
|
||||||
IpcCommandResponse r;
|
IpcCommandResponse r;
|
||||||
ipcParseResponse(&r);
|
ipcParseResponseForDomain(&r);
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
u64 magic;
|
u64 magic;
|
||||||
@ -145,6 +257,10 @@ int bsdConnect(int sockfd, void* addr, u32 addrlen) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (R_FAILED(rc)) {
|
||||||
|
g_Errno = EPIPE;
|
||||||
|
}
|
||||||
|
|
||||||
return fd;
|
return fd;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -160,7 +276,7 @@ int bsdBind(int sockfd, void* addr, u32 addrlen) {
|
|||||||
u32 pad[5];
|
u32 pad[5];
|
||||||
} *raw;
|
} *raw;
|
||||||
|
|
||||||
raw = ipcPrepareHeader(&c, sizeof(*raw));
|
raw = ipcPrepareHeaderForDomain(&c, sizeof(*raw), g_bsdObjectId);
|
||||||
|
|
||||||
raw->magic = SFCI_MAGIC;
|
raw->magic = SFCI_MAGIC;
|
||||||
raw->cmd_id = 13;
|
raw->cmd_id = 13;
|
||||||
@ -170,7 +286,7 @@ int bsdBind(int sockfd, void* addr, u32 addrlen) {
|
|||||||
|
|
||||||
if (R_SUCCEEDED(rc)) {
|
if (R_SUCCEEDED(rc)) {
|
||||||
IpcCommandResponse r;
|
IpcCommandResponse r;
|
||||||
ipcParseResponse(&r);
|
ipcParseResponseForDomain(&r);
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
u64 magic;
|
u64 magic;
|
||||||
@ -187,6 +303,10 @@ int bsdBind(int sockfd, void* addr, u32 addrlen) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (R_FAILED(rc)) {
|
||||||
|
g_Errno = EPIPE;
|
||||||
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -202,7 +322,7 @@ int bsdListen(int sockfd, int backlog) {
|
|||||||
u32 pad[4];
|
u32 pad[4];
|
||||||
} *raw;
|
} *raw;
|
||||||
|
|
||||||
raw = ipcPrepareHeader(&c, sizeof(*raw));
|
raw = ipcPrepareHeaderForDomain(&c, sizeof(*raw), g_bsdObjectId);
|
||||||
|
|
||||||
raw->magic = SFCI_MAGIC;
|
raw->magic = SFCI_MAGIC;
|
||||||
raw->cmd_id = 18;
|
raw->cmd_id = 18;
|
||||||
@ -214,7 +334,7 @@ int bsdListen(int sockfd, int backlog) {
|
|||||||
|
|
||||||
if (R_SUCCEEDED(rc)) {
|
if (R_SUCCEEDED(rc)) {
|
||||||
IpcCommandResponse r;
|
IpcCommandResponse r;
|
||||||
ipcParseResponse(&r);
|
ipcParseResponseForDomain(&r);
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
u64 magic;
|
u64 magic;
|
||||||
@ -231,5 +351,56 @@ int bsdListen(int sockfd, int backlog) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (R_FAILED(rc)) {
|
||||||
|
g_Errno = EPIPE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int bsdWrite(int sockfd, void* buffer, size_t length) {
|
||||||
|
IpcCommand c;
|
||||||
|
ipcInitialize(&c);
|
||||||
|
ipcAddSendBuffer(&c, buffer, length, 0);
|
||||||
|
ipcAddSendStatic(&c, buffer, length, 0);
|
||||||
|
|
||||||
|
struct {
|
||||||
|
u64 magic;
|
||||||
|
u64 cmd_id;
|
||||||
|
u32 sockfd;
|
||||||
|
} *raw;
|
||||||
|
|
||||||
|
raw = ipcPrepareHeaderForDomain(&c, sizeof(*raw), g_bsdObjectId);
|
||||||
|
|
||||||
|
raw->magic = SFCI_MAGIC;
|
||||||
|
raw->cmd_id = 24;
|
||||||
|
raw->sockfd = sockfd;
|
||||||
|
|
||||||
|
Result rc = ipcDispatch(g_bsdHandle);
|
||||||
|
int ret = -1;
|
||||||
|
|
||||||
|
if (R_SUCCEEDED(rc)) {
|
||||||
|
IpcCommandResponse r;
|
||||||
|
ipcParseResponseForDomain(&r);
|
||||||
|
|
||||||
|
struct {
|
||||||
|
u64 magic;
|
||||||
|
u64 result;
|
||||||
|
u32 ret;
|
||||||
|
u32 errno;
|
||||||
|
} *resp = r.Raw;
|
||||||
|
|
||||||
|
rc = resp->result;
|
||||||
|
|
||||||
|
if (R_SUCCEEDED(rc)) {
|
||||||
|
g_Errno = resp->errno;
|
||||||
|
ret = resp->ret;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (R_FAILED(rc)) {
|
||||||
|
g_Errno = EPIPE;
|
||||||
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user