mirror of
https://github.com/Atmosphere-NX/Atmosphere
synced 2024-12-22 12:21:18 +00:00
Stratosphere: Fix remaining bugs in sm, which now works as a KIP1 on hardware
This commit is contained in:
parent
52730d2188
commit
30f975a558
6 changed files with 30 additions and 45 deletions
|
@ -40,14 +40,8 @@ void WaitableManager::process() {
|
|||
handles.resize(signalables.size());
|
||||
std::transform(signalables.begin(), signalables.end(), handles.begin(), [](IWaitable *w) { return w->get_handle(); });
|
||||
|
||||
unsigned int num_not_deferred = 0;
|
||||
for (auto & signalable : signalables) {
|
||||
if (!signalable->get_deferred()) {
|
||||
num_not_deferred++;
|
||||
}
|
||||
}
|
||||
|
||||
rc = svcWaitSynchronization(&handle_index, handles.data(), num_not_deferred, this->timeout);
|
||||
rc = svcWaitSynchronization(&handle_index, handles.data(), signalables.size(), this->timeout);
|
||||
if (R_SUCCEEDED(rc)) {
|
||||
/* Handle a signaled waitable. */
|
||||
/* TODO: What timeout should be passed here? */
|
||||
|
@ -82,12 +76,19 @@ void WaitableManager::process() {
|
|||
delete signalables[handle_index];
|
||||
}
|
||||
|
||||
/* If relevant, remove from signalables. */
|
||||
signalables.erase(std::remove(signalables.begin(), signalables.end(), signalables[handle_index]), signalables.end());
|
||||
|
||||
for (int i = 0; i < handle_index; i++) {
|
||||
signalables[i]->update_priority();
|
||||
}
|
||||
}
|
||||
|
||||
/* Do deferred callback for each waitable. */
|
||||
std::for_each(signalables.begin() + num_not_deferred, signalables.end(), [](IWaitable *w) { w->handle_deferred(); });
|
||||
for (auto & waitable : signalables) {
|
||||
if (waitable->get_deferred()) {
|
||||
waitable->handle_deferred();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -48,7 +48,7 @@ void __appExit(void) {
|
|||
int main(int argc, char **argv)
|
||||
{
|
||||
consoleDebugInit(debugDevice_SVC);
|
||||
|
||||
|
||||
/* TODO: What's a good timeout value to use here? */
|
||||
WaitableManager *server_manager = new WaitableManager(U64_MAX);
|
||||
|
||||
|
|
|
@ -4,7 +4,6 @@
|
|||
|
||||
Result ManagerService::dispatch(IpcParsedCommand &r, IpcCommand &out_c, u64 cmd_id, u8 *pointer_buffer, size_t pointer_buffer_size) {
|
||||
Result rc = 0xF601;
|
||||
|
||||
switch ((ManagerServiceCmd)cmd_id) {
|
||||
case Manager_Cmd_RegisterProcess:
|
||||
rc = WrapIpcCommandImpl<&ManagerService::register_process>(this, r, out_c, pointer_buffer, pointer_buffer_size);
|
||||
|
|
|
@ -6,6 +6,15 @@
|
|||
static Registration::Process g_process_list[REGISTRATION_LIST_MAX_PROCESS] = {0};
|
||||
static Registration::Service g_service_list[REGISTRATION_LIST_MAX_SERVICE] = {0};
|
||||
|
||||
u64 GetServiceNameLength(u64 service) {
|
||||
u64 service_name_len = 0;
|
||||
while (service & 0xFF) {
|
||||
service_name_len++;
|
||||
service >>= 8;
|
||||
}
|
||||
return service_name_len;
|
||||
}
|
||||
|
||||
/* Utilities. */
|
||||
Registration::Process *Registration::GetProcessForPid(u64 pid) {
|
||||
for (unsigned int i = 0; i < REGISTRATION_LIST_MAX_PROCESS; i++) {
|
||||
|
@ -162,13 +171,10 @@ Result Registration::GetServiceForPid(u64 pid, u64 service, Handle *out) {
|
|||
return 0xC15;
|
||||
}
|
||||
|
||||
u64 service_name_len = 0;
|
||||
while ((service >> (8 * service_name_len)) & 0xFF) {
|
||||
service_name_len++;
|
||||
}
|
||||
u64 service_name_len = GetServiceNameLength(service);
|
||||
|
||||
/* If the service has bytes after a null terminator, that's no good. */
|
||||
if ((service >> (8 * service_name_len))) {
|
||||
if (service_name_len != 8 && (service >> (8 * service_name_len))) {
|
||||
return 0xC15;
|
||||
}
|
||||
|
||||
|
@ -191,13 +197,10 @@ Result Registration::RegisterServiceForPid(u64 pid, u64 service, u64 max_session
|
|||
return 0xC15;
|
||||
}
|
||||
|
||||
u64 service_name_len = 0;
|
||||
while ((service >> (8 * service_name_len)) & 0xFF) {
|
||||
service_name_len++;
|
||||
}
|
||||
u64 service_name_len = GetServiceNameLength(service);
|
||||
|
||||
/* If the service has bytes after a null terminator, that's no good. */
|
||||
if ((service >> (8 * service_name_len))) {
|
||||
if (service_name_len != 8 && (service >> (8 * service_name_len))) {
|
||||
return 0xC15;
|
||||
}
|
||||
|
||||
|
@ -240,13 +243,10 @@ Result Registration::RegisterServiceForSelf(u64 service, u64 max_sessions, bool
|
|||
return rc;
|
||||
}
|
||||
|
||||
u64 service_name_len = 0;
|
||||
while ((service >> (8 * service_name_len)) & 0xFF) {
|
||||
service_name_len++;
|
||||
}
|
||||
u64 service_name_len = GetServiceNameLength(service);
|
||||
|
||||
/* If the service has bytes after a null terminator, that's no good. */
|
||||
if ((service >> (8 * service_name_len))) {
|
||||
if (service_name_len != 8 && (service >> (8 * service_name_len))) {
|
||||
return 0xC15;
|
||||
}
|
||||
|
||||
|
@ -276,27 +276,13 @@ Result Registration::UnregisterServiceForPid(u64 pid, u64 service) {
|
|||
return 0xC15;
|
||||
}
|
||||
|
||||
u64 service_name_len = 0;
|
||||
while ((service >> (8 * service_name_len)) & 0xFF) {
|
||||
service_name_len++;
|
||||
}
|
||||
u64 service_name_len = GetServiceNameLength(service);
|
||||
|
||||
/* If the service has bytes after a null terminator, that's no good. */
|
||||
if ((service >> (8 * service_name_len))) {
|
||||
if (service_name_len != 8 && (service >> (8 * service_name_len))) {
|
||||
return 0xC15;
|
||||
}
|
||||
|
||||
if (pid >= REGISTRATION_PID_BUILTIN_MAX) {
|
||||
Registration::Process *proc = GetProcessForPid(pid);
|
||||
if (proc == NULL) {
|
||||
return 0x415;
|
||||
}
|
||||
|
||||
if (!IsValidForSac(proc->sac, proc->sac_size, service, true)) {
|
||||
return 0x1015;
|
||||
}
|
||||
}
|
||||
|
||||
Registration::Service *target_service = GetService(service);
|
||||
if (target_service == NULL) {
|
||||
return 0xE15;
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
#define REGISTRATION_LIST_MAX_PROCESS (0x40)
|
||||
#define REGISTRATION_LIST_MAX_SERVICE (0x100)
|
||||
#define REGISTRATION_MAX_SAC_SIZE (0x200)
|
||||
#define REGISTRATION_PID_BUILTIN_MAX 0x7
|
||||
#define REGISTRATION_PID_BUILTIN_MAX 0x50
|
||||
|
||||
class Registration {
|
||||
public:
|
||||
|
|
|
@ -4,8 +4,7 @@
|
|||
#include "sm_registration.hpp"
|
||||
|
||||
Result UserService::dispatch(IpcParsedCommand &r, IpcCommand &out_c, u64 cmd_id, u8 *pointer_buffer, size_t pointer_buffer_size) {
|
||||
Result rc = 0xF601;
|
||||
|
||||
Result rc = 0xF601;
|
||||
switch ((UserServiceCmd)cmd_id) {
|
||||
case User_Cmd_Initialize:
|
||||
rc = WrapIpcCommandImpl<&UserService::initialize>(this, r, out_c, pointer_buffer, pointer_buffer_size);
|
||||
|
@ -27,7 +26,7 @@ Result UserService::dispatch(IpcParsedCommand &r, IpcCommand &out_c, u64 cmd_id,
|
|||
|
||||
Result UserService::handle_deferred() {
|
||||
/* If we're deferred, GetService failed. */
|
||||
return WrapDeferredIpcCommandImpl<&UserService::deferred_get_service>(this, this->deferred_service);
|
||||
return WrapDeferredIpcCommandImpl<&UserService::deferred_get_service>(this, this->deferred_service);;
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue