mirror of
https://github.com/Atmosphere-NX/Atmosphere.git
synced 2024-11-22 20:06:40 +00:00
Stratosphere: Add handle/pid output to IPC templating, fix failure condition message preparation.
This commit is contained in:
parent
b6ba7b94b9
commit
878d68f7e0
3 changed files with 44 additions and 16 deletions
|
@ -105,9 +105,14 @@ struct is_ipc_buffer {
|
||||||
|| is_specialization_of<T, OutPointerWithClientSize>::value;
|
|| is_specialization_of<T, OutPointerWithClientSize>::value;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
struct is_ipc_handle {
|
||||||
|
static const size_t value = (std::is_same<T, MovedHandle>::value || std::is_same<T, CopiedHandle>::value) ? 1 : 0;
|
||||||
|
};
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
struct size_in_raw_data {
|
struct size_in_raw_data {
|
||||||
static const size_t value = (is_ipc_buffer<T>::value) ? 0 : ((sizeof(T) < sizeof(u32)) ? sizeof(u32) : (sizeof(T) + 3) & (~3));
|
static const size_t value = (is_ipc_buffer<T>::value || is_ipc_handle<T>::value) ? 0 : ((sizeof(T) < sizeof(u32)) ? sizeof(u32) : (sizeof(T) + 3) & (~3));
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename ...Args>
|
template <typename ...Args>
|
||||||
|
@ -165,12 +170,6 @@ struct num_inoutbuffers_in_arguments {
|
||||||
static const size_t value = (is_ipc_inoutbuffer<Args>::value + ... + 0);
|
static const size_t value = (is_ipc_inoutbuffer<Args>::value + ... + 0);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
struct is_ipc_handle {
|
|
||||||
static const size_t value = (std::is_same<T, MovedHandle>::value || std::is_same<T, CopiedHandle>::value) ? 1 : 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename ...Args>
|
template <typename ...Args>
|
||||||
struct num_handles_in_arguments {
|
struct num_handles_in_arguments {
|
||||||
static const size_t value = (is_ipc_handle<Args>::value + ... + 0);
|
static const size_t value = (is_ipc_handle<Args>::value + ... + 0);
|
||||||
|
@ -329,6 +328,26 @@ constexpr size_t GetAndUpdateOffsetIntoRawData(size_t& offset) {
|
||||||
return old;
|
return old;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
void EncodeValueIntoIpcMessageBeforePrepare(IpcCommand *c, T value) {
|
||||||
|
if constexpr (std::is_same<T, MovedHandle>::value) {
|
||||||
|
ipcSendHandleMove(c, value.handle);
|
||||||
|
} else if constexpr (std::is_same<T, CopiedHandle>::value) {
|
||||||
|
ipcSendHandleCopy(c, value.handle);
|
||||||
|
} else if constexpr (std::is_same<T, PidDescriptor>::value) {
|
||||||
|
ipcSendPid(c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
void EncodeValueIntoIpcMessageAfterPrepare(u8 *cur_out, T value) {
|
||||||
|
if constexpr (is_ipc_handle<T>::value || std::is_same<T, PidDescriptor>::value) {
|
||||||
|
/* Do nothing. */
|
||||||
|
} else {
|
||||||
|
*((T *)(cur_out)) = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
template<typename... Args>
|
template<typename... Args>
|
||||||
struct Encoder<std::tuple<Args...>> {
|
struct Encoder<std::tuple<Args...>> {
|
||||||
IpcCommand &out_command;
|
IpcCommand &out_command;
|
||||||
|
@ -339,7 +358,9 @@ struct Encoder<std::tuple<Args...>> {
|
||||||
|
|
||||||
u8 *tls = (u8 *)armGetTls();
|
u8 *tls = (u8 *)armGetTls();
|
||||||
|
|
||||||
std::fill(tls, tls + 0x100, 0x100);
|
std::fill(tls, tls + 0x100, 0x00);
|
||||||
|
|
||||||
|
((EncodeValueIntoIpcMessageBeforePrepare<Args>(&out_command, args)), ...);
|
||||||
|
|
||||||
/* Remove the extra space resulting from first Result type. */
|
/* Remove the extra space resulting from first Result type. */
|
||||||
struct {
|
struct {
|
||||||
|
@ -350,14 +371,20 @@ struct Encoder<std::tuple<Args...>> {
|
||||||
raw->magic = SFCO_MAGIC;
|
raw->magic = SFCO_MAGIC;
|
||||||
|
|
||||||
u8 *raw_data = (u8 *)&raw->result;
|
u8 *raw_data = (u8 *)&raw->result;
|
||||||
|
|
||||||
((*((Args *)(raw_data + GetAndUpdateOffsetIntoRawData<Args>(offset))) = (args)), ...);
|
|
||||||
|
|
||||||
if (R_FAILED(raw->result)) {
|
((EncodeValueIntoIpcMessageAfterPrepare<Args>(raw_data + GetAndUpdateOffsetIntoRawData<Args>(offset), args)), ...);
|
||||||
ipcPrepareHeader(&out_command, sizeof(raw));
|
|
||||||
|
Result rc = raw->result;
|
||||||
|
|
||||||
|
if (R_FAILED(rc)) {
|
||||||
|
std::fill(tls, tls + 0x100, 0x00);
|
||||||
|
ipcInitialize(&out_command);
|
||||||
|
raw = (decltype(raw))ipcPrepareHeader(&out_command, sizeof(raw));
|
||||||
|
raw->magic = SFCO_MAGIC;
|
||||||
|
raw->result = rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
return raw->result;
|
return rc;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -28,9 +28,10 @@ Result ProcessManagerService::dispatch(IpcParsedCommand &r, IpcCommand &out_c, u
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::tuple<Result> ProcessManagerService::create_process() {
|
std::tuple<Result, MovedHandle> ProcessManagerService::create_process(u64 flags, u64 title_id, CopiedHandle reslimit_h) {
|
||||||
/* TODO */
|
/* TODO */
|
||||||
return std::make_tuple(0xF601);
|
fprintf(stderr, "CreateProcess(%016lx, %016lx, %08x);\n", flags, title_id, reslimit_h.handle);
|
||||||
|
return std::make_tuple(0xF601, MovedHandle{0x00});
|
||||||
}
|
}
|
||||||
|
|
||||||
std::tuple<Result> ProcessManagerService::get_program_info(Registration::TidSid tid_sid, OutPointerWithServerSize<ProcessManagerService::ProgramInfo, 0x1> out_program_info) {
|
std::tuple<Result> ProcessManagerService::get_program_info(Registration::TidSid tid_sid, OutPointerWithServerSize<ProcessManagerService::ProgramInfo, 0x1> out_program_info) {
|
||||||
|
|
|
@ -32,7 +32,7 @@ class ProcessManagerService : IServiceObject {
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/* Actual commands. */
|
/* Actual commands. */
|
||||||
std::tuple<Result> create_process();
|
std::tuple<Result, MovedHandle> create_process(u64 flags, u64 title_id, CopiedHandle reslimit_h);
|
||||||
std::tuple<Result> get_program_info(Registration::TidSid tid_sid, OutPointerWithServerSize<ProcessManagerService::ProgramInfo, 0x1> out_program_info);
|
std::tuple<Result> get_program_info(Registration::TidSid tid_sid, OutPointerWithServerSize<ProcessManagerService::ProgramInfo, 0x1> out_program_info);
|
||||||
std::tuple<Result, u64> register_title(Registration::TidSid tid_sid);
|
std::tuple<Result, u64> register_title(Registration::TidSid tid_sid);
|
||||||
std::tuple<Result> unregister_title(u64 index);
|
std::tuple<Result> unregister_title(u64 index);
|
||||||
|
|
Loading…
Reference in a new issue