mirror of
https://github.com/Atmosphere-NX/Atmosphere.git
synced 2024-12-23 10:52:13 +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;
|
||||
};
|
||||
|
||||
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>
|
||||
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>
|
||||
|
@ -165,12 +170,6 @@ struct num_inoutbuffers_in_arguments {
|
|||
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>
|
||||
struct num_handles_in_arguments {
|
||||
static const size_t value = (is_ipc_handle<Args>::value + ... + 0);
|
||||
|
@ -329,6 +328,26 @@ constexpr size_t GetAndUpdateOffsetIntoRawData(size_t& offset) {
|
|||
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>
|
||||
struct Encoder<std::tuple<Args...>> {
|
||||
IpcCommand &out_command;
|
||||
|
@ -339,7 +358,9 @@ struct Encoder<std::tuple<Args...>> {
|
|||
|
||||
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. */
|
||||
struct {
|
||||
|
@ -350,14 +371,20 @@ struct Encoder<std::tuple<Args...>> {
|
|||
raw->magic = SFCO_MAGIC;
|
||||
|
||||
u8 *raw_data = (u8 *)&raw->result;
|
||||
|
||||
((*((Args *)(raw_data + GetAndUpdateOffsetIntoRawData<Args>(offset))) = (args)), ...);
|
||||
|
||||
if (R_FAILED(raw->result)) {
|
||||
ipcPrepareHeader(&out_command, sizeof(raw));
|
||||
((EncodeValueIntoIpcMessageAfterPrepare<Args>(raw_data + GetAndUpdateOffsetIntoRawData<Args>(offset), args)), ...);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
std::tuple<Result> ProcessManagerService::create_process() {
|
||||
std::tuple<Result, MovedHandle> ProcessManagerService::create_process(u64 flags, u64 title_id, CopiedHandle reslimit_h) {
|
||||
/* 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) {
|
||||
|
|
|
@ -32,7 +32,7 @@ class ProcessManagerService : IServiceObject {
|
|||
|
||||
private:
|
||||
/* 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, u64> register_title(Registration::TidSid tid_sid);
|
||||
std::tuple<Result> unregister_title(u64 index);
|
||||
|
|
Loading…
Reference in a new issue