Refactor service functions to return result codes

This commit is contained in:
Billy Laws 2020-09-03 19:43:52 +01:00 committed by ◱ PixelyIon
parent 74a150dff1
commit 89718804d0
125 changed files with 929 additions and 600 deletions

View File

@ -25,6 +25,32 @@
namespace skyline {
using KHandle = u32; //!< The type of a kernel handle
/**
* @brief The result of an operation in HOS
* @url https://switchbrew.org/wiki/Error_codes
*/
union Result {
u32 raw{};
struct {
u16 module : 9;
u16 id : 12;
};
/**
* @note Success is 0, 0 - it is the only error that's not specific to a module
*/
Result() {}
constexpr Result(u16 module, u16 id) {
this->module = module;
this->id = id;
}
constexpr operator u32() const {
return raw;
}
};
namespace constant {
// Memory
constexpr u64 BaseAddress = 0x8000000; //!< The address space base
@ -36,29 +62,6 @@ namespace skyline {
constexpr u16 DockedResolutionH = 1080; //!< The height component of the docked resolution
// Time
constexpr u64 NsInSecond = 1000000000; //!< This is the amount of nanoseconds in a second
// Status codes
namespace status {
constexpr u32 Success = 0x0; //!< "Success"
constexpr u32 PathDoesNotExist = 0x202; //!< "Path does not exist"
constexpr u32 GenericError = 0x272; //!< "Generic error"
constexpr u32 NoMessages = 0x680; //!< "No message available"
constexpr u32 ServiceInvName = 0xC15; //!< "Invalid name"
constexpr u32 ServiceNotReg = 0xE15; //!< "Service not registered"
constexpr u32 InvUser = 0xC87C; //!< Invalid user
constexpr u32 InvSize = 0xCA01; //!< "Invalid size"
constexpr u32 InvAddress = 0xCC01; //!< "Invalid address"
constexpr u32 InvState = 0xD401; //!< "Invalid MemoryState"
constexpr u32 InvPermission = 0xD801; //!< "Invalid Permission"
constexpr u32 InvMemRange = 0xD801; //!< "Invalid Memory Range"
constexpr u32 InvPriority = 0xE001; //!< "Invalid Priority"
constexpr u32 InvHandle = 0xE401; //!< "Invalid handle"
constexpr u32 InvCombination = 0xE801; //!< "Invalid combination"
constexpr u32 Timeout = 0xEA01; //!< "Timeout"
constexpr u32 Interrupted = 0xEC01; //!< "Interrupted"
constexpr u32 MaxHandles = 0xEE01; //!< "Too many handles"
constexpr u32 NotFound = 0xF201; //!< "Not found"
constexpr u32 Unimpl = 0x177202; //!< "Unimplemented behaviour"
}
};
namespace util {

View File

@ -309,7 +309,7 @@ namespace skyline {
std::vector<u8> payload; //!< This holds all of the contents to be pushed to the payload
public:
u32 errorCode{}; //!< The error code to respond with, it is 0 (Success) by default
Result errorCode{}; //!< The error code to respond with, it is 0 (Success) by default
std::vector<KHandle> copyHandles; //!< A vector of handles to copy
std::vector<KHandle> moveHandles; //!< A vector of handles to move
std::vector<KHandle> domainObjects; //!< A vector of domain objects to write

View File

@ -0,0 +1,53 @@
// SPDX-License-Identifier: MPL-2.0
// Copyright © 2020 Skyline Team and Contributors (https://github.com/skyline-emu/)
#pragma once
#include <common.h>
namespace skyline::kernel::result {
constexpr Result OutOfSessions(1, 7);
constexpr Result InvalidArgument(1, 14);
constexpr Result NotImplemented(1, 33);
constexpr Result StopProcessingException(1, 54);
constexpr Result NoSynchronizationObject(1, 57);
constexpr Result TerminationRequested(1, 59);
constexpr Result NoEvent(1, 70);
constexpr Result InvalidSize(1, 101);
constexpr Result InvalidAddress(1, 102);
constexpr Result OutOfResource(1, 103);
constexpr Result OutOfMemory(1, 104);
constexpr Result OutOfHandles(1, 105);
constexpr Result InvalidCurrentMemory(1, 106);
constexpr Result InvalidNewMemoryPermission(1, 108);
constexpr Result InvalidMemoryRegion(1, 110);
constexpr Result InvalidPriority(1, 112);
constexpr Result InvalidCoreId(1, 113);
constexpr Result InvalidHandle(1, 114);
constexpr Result InvalidPointer(1, 115);
constexpr Result InvalidCombination(1, 116);
constexpr Result TimedOut(1, 117);
constexpr Result Cancelled(1, 118);
constexpr Result OutOfRange(1, 119);
constexpr Result InvalidEnumValue(1, 120);
constexpr Result NotFound(1, 121);
constexpr Result Busy(1, 122);
constexpr Result SessionClosed(1, 123);
constexpr Result NotHandled(1, 124);
constexpr Result InvalidState(1, 125);
constexpr Result ReservedUsed(1, 126);
constexpr Result NotSupported(1, 127);
constexpr Result Debug(1, 128);
constexpr Result NoThread(1, 129);
constexpr Result UnknownThread(1, 130);
constexpr Result PortClosed(1, 131);
constexpr Result LimitReached(1, 132);
constexpr Result InvalidMemoryPool(1, 133);
constexpr Result ReceiveListBroken(1, 258);
constexpr Result OutOfAddressSpace(1, 259);
constexpr Result MessageTooLarge(1, 260);
constexpr Result InvalidProcessId(1, 517);
constexpr Result InvalidThreadId(1, 518);
constexpr Result InvalidId(1, 519);
constexpr Result ProcessTerminated(1, 520);
}

View File

@ -2,6 +2,7 @@
// Copyright © 2020 Skyline Team and Contributors (https://github.com/skyline-emu/)
#include <os.h>
#include "results.h"
#include "svc.h"
namespace skyline::kernel::svc {
@ -9,7 +10,7 @@ namespace skyline::kernel::svc {
auto size = state.ctx->registers.w1;
if (!util::IsAligned(size, 0x200000)) {
state.ctx->registers.w0 = constant::status::InvSize;
state.ctx->registers.w0 = result::InvalidSize;
state.ctx->registers.x1 = 0;
state.logger->Warn("svcSetHeapSize: 'size' not divisible by 2MB: {}", size);
@ -19,7 +20,7 @@ namespace skyline::kernel::svc {
auto &heap = state.process->heap;
heap->Resize(size);
state.ctx->registers.w0 = constant::status::Success;
state.ctx->registers.w0 = Result{};
state.ctx->registers.x1 = heap->address;
state.logger->Debug("svcSetHeapSize: Allocated at 0x{:X} for 0x{:X} bytes", heap->address, heap->size);
@ -28,14 +29,14 @@ namespace skyline::kernel::svc {
void SetMemoryAttribute(DeviceState &state) {
auto address = state.ctx->registers.x0;
if (!util::PageAligned(address)) {
state.ctx->registers.w0 = constant::status::InvAddress;
state.ctx->registers.w0 = result::InvalidAddress;
state.logger->Warn("svcSetMemoryAttribute: 'address' not page aligned: 0x{:X}", address);
return;
}
auto size = state.ctx->registers.x1;
if (!util::PageAligned(size)) {
state.ctx->registers.w0 = constant::status::InvSize;
state.ctx->registers.w0 = result::InvalidSize;
state.logger->Warn("svcSetMemoryAttribute: 'size' {}: 0x{:X}", size ? "not page aligned" : "is zero", size);
return;
}
@ -45,7 +46,7 @@ namespace skyline::kernel::svc {
auto maskedValue = mask.value | value.value;
if (maskedValue != mask.value || !mask.isUncached || mask.isDeviceShared || mask.isBorrowed || mask.isIpcLocked) {
state.ctx->registers.w0 = constant::status::InvCombination;
state.ctx->registers.w0 = result::InvalidCombination;
state.logger->Warn("svcSetMemoryAttribute: 'mask' invalid: 0x{:X}, 0x{:X}", mask.value, value.value);
return;
}
@ -53,13 +54,13 @@ namespace skyline::kernel::svc {
auto chunk = state.os->memory.GetChunk(address);
auto block = state.os->memory.GetBlock(address);
if (!chunk || !block) {
state.ctx->registers.w0 = constant::status::InvAddress;
state.ctx->registers.w0 = result::InvalidAddress;
state.logger->Warn("svcSetMemoryAttribute: Cannot find memory region: 0x{:X}", address);
return;
}
if (!chunk->state.attributeChangeAllowed) {
state.ctx->registers.w0 = constant::status::InvState;
state.ctx->registers.w0 = result::InvalidState;
state.logger->Warn("svcSetMemoryAttribute: Attribute change not allowed for chunk: 0x{:X}", address);
return;
}
@ -68,7 +69,7 @@ namespace skyline::kernel::svc {
MemoryManager::InsertBlock(chunk, *block);
state.logger->Debug("svcSetMemoryAttribute: Set caching to {} at 0x{:X} for 0x{:X} bytes", !block->attributes.isUncached, address, size);
state.ctx->registers.w0 = constant::status::Success;
state.ctx->registers.w0 = Result{};
}
void MapMemory(DeviceState &state) {
@ -77,32 +78,32 @@ namespace skyline::kernel::svc {
auto size = state.ctx->registers.x2;
if (!util::PageAligned(destination) || !util::PageAligned(source)) {
state.ctx->registers.w0 = constant::status::InvAddress;
state.ctx->registers.w0 = result::InvalidAddress;
state.logger->Warn("svcMapMemory: Addresses not page aligned: Source: 0x{:X}, Destination: 0x{:X} (Size: 0x{:X} bytes)", source, destination, size);
return;
}
if (!util::PageAligned(size)) {
state.ctx->registers.w0 = constant::status::InvSize;
state.ctx->registers.w0 = result::InvalidSize;
state.logger->Warn("svcMapMemory: 'size' {}: 0x{:X}", size ? "not page aligned" : "is zero", size);
return;
}
auto stack = state.os->memory.stack;
if (!stack.IsInside(destination)) {
state.ctx->registers.w0 = constant::status::InvMemRange;
state.ctx->registers.w0 = result::InvalidMemoryRegion;
state.logger->Warn("svcMapMemory: Destination not within stack region: Source: 0x{:X}, Destination: 0x{:X} (Size: 0x{:X} bytes)", source, destination, size);
return;
}
auto descriptor = state.os->memory.Get(source);
if (!descriptor) {
state.ctx->registers.w0 = constant::status::InvAddress;
state.ctx->registers.w0 = result::InvalidAddress;
state.logger->Warn("svcMapMemory: Source has no descriptor: Source: 0x{:X}, Destination: 0x{:X} (Size: 0x{:X} bytes)", source, destination, size);
return;
}
if (!descriptor->chunk.state.mapAllowed) {
state.ctx->registers.w0 = constant::status::InvState;
state.ctx->registers.w0 = result::InvalidState;
state.logger->Warn("svcMapMemory: Source doesn't allow usage of svcMapMemory: Source: 0x{:X}, Destination: 0x{:X} (Size: 0x{:X} bytes) 0x{:X}", source, destination, size, descriptor->chunk.state.value);
return;
}
@ -117,7 +118,7 @@ namespace skyline::kernel::svc {
object->item->UpdatePermission(source, size, {false, false, false});
state.logger->Debug("svcMapMemory: Mapped range 0x{:X} - 0x{:X} to 0x{:X} - 0x{:X} (Size: 0x{:X} bytes)", source, source + size, destination, destination + size, size);
state.ctx->registers.w0 = constant::status::Success;
state.ctx->registers.w0 = Result{};
}
void UnmapMemory(DeviceState &state) {
@ -126,20 +127,20 @@ namespace skyline::kernel::svc {
auto size = state.ctx->registers.x2;
if (!util::PageAligned(destination) || !util::PageAligned(source)) {
state.ctx->registers.w0 = constant::status::InvAddress;
state.ctx->registers.w0 = result::InvalidAddress;
state.logger->Warn("svcUnmapMemory: Addresses not page aligned: Source: 0x{:X}, Destination: 0x{:X} (Size: 0x{:X} bytes)", source, destination, size);
return;
}
if (!util::PageAligned(size)) {
state.ctx->registers.w0 = constant::status::InvSize;
state.ctx->registers.w0 = result::InvalidSize;
state.logger->Warn("svcUnmapMemory: 'size' {}: 0x{:X}", size ? "not page aligned" : "is zero", size);
return;
}
auto stack = state.os->memory.stack;
if (!stack.IsInside(source)) {
state.ctx->registers.w0 = constant::status::InvMemRange;
state.ctx->registers.w0 = result::InvalidMemoryRegion;
state.logger->Warn("svcUnmapMemory: Source not within stack region: Source: 0x{:X}, Destination: 0x{:X} (Size: 0x{:X} bytes)", source, destination, size);
return;
}
@ -147,13 +148,13 @@ namespace skyline::kernel::svc {
auto sourceDesc = state.os->memory.Get(source);
auto destDesc = state.os->memory.Get(destination);
if (!sourceDesc || !destDesc) {
state.ctx->registers.w0 = constant::status::InvAddress;
state.ctx->registers.w0 = result::InvalidAddress;
state.logger->Warn("svcUnmapMemory: Addresses have no descriptor: Source: 0x{:X}, Destination: 0x{:X} (Size: 0x{:X} bytes)", source, destination, size);
return;
}
if (!destDesc->chunk.state.mapAllowed) {
state.ctx->registers.w0 = constant::status::InvState;
state.ctx->registers.w0 = result::InvalidState;
state.logger->Warn("svcUnmapMemory: Destination doesn't allow usage of svcMapMemory: Source: 0x{:X}, Destination: 0x{:X} (Size: 0x{:X} bytes) 0x{:X}", source, destination, size, destDesc->chunk.state.value);
return;
}
@ -173,7 +174,7 @@ namespace skyline::kernel::svc {
state.process->DeleteHandle(sourceObject->handle);
state.logger->Debug("svcUnmapMemory: Unmapped range 0x{:X} - 0x{:X} to 0x{:X} - 0x{:X} (Size: 0x{:X} bytes)", source, source + size, destination, destination + size, size);
state.ctx->registers.w0 = constant::status::Success;
state.ctx->registers.w0 = Result{};
}
void QueryMemory(DeviceState &state) {
@ -208,7 +209,7 @@ namespace skyline::kernel::svc {
state.process->WriteMemory(memInfo, state.ctx->registers.x0);
state.ctx->registers.w0 = constant::status::Success;
state.ctx->registers.w0 = Result{};
}
void ExitProcess(DeviceState &state) {
@ -223,7 +224,7 @@ namespace skyline::kernel::svc {
auto priority = static_cast<i8>(state.ctx->registers.w4);
if (!state.thread->switchPriority.Valid(priority)) {
state.ctx->registers.w0 = constant::status::InvAddress;
state.ctx->registers.w0 = result::InvalidAddress;
state.logger->Warn("svcCreateThread: 'priority' invalid: {}", priority);
return;
}
@ -232,7 +233,7 @@ namespace skyline::kernel::svc {
state.logger->Debug("svcCreateThread: Created thread with handle 0x{:X} (Entry Point: 0x{:X}, Argument: 0x{:X}, Stack Pointer: 0x{:X}, Priority: {}, TID: {})", thread->handle, entryAddress, entryArgument, stackTop, priority, thread->tid);
state.ctx->registers.w1 = thread->handle;
state.ctx->registers.w0 = constant::status::Success;
state.ctx->registers.w0 = Result{};
}
void StartThread(DeviceState &state) {
@ -241,10 +242,10 @@ namespace skyline::kernel::svc {
auto thread = state.process->GetHandle<type::KThread>(handle);
state.logger->Debug("svcStartThread: Starting thread: 0x{:X}, PID: {}", handle, thread->tid);
thread->Start();
state.ctx->registers.w0 = constant::status::Success;
state.ctx->registers.w0 = Result{};
} catch (const std::exception &) {
state.logger->Warn("svcStartThread: 'handle' invalid: 0x{:X}", handle);
state.ctx->registers.w0 = constant::status::InvHandle;
state.ctx->registers.w0 = result::InvalidHandle;
}
}
@ -279,10 +280,10 @@ namespace skyline::kernel::svc {
state.logger->Debug("svcGetThreadPriority: Writing thread priority {}", priority);
state.ctx->registers.w1 = priority;
state.ctx->registers.w0 = constant::status::Success;
state.ctx->registers.w0 = Result{};
} catch (const std::exception &) {
state.logger->Warn("svcGetThreadPriority: 'handle' invalid: 0x{:X}", handle);
state.ctx->registers.w0 = constant::status::InvHandle;
state.ctx->registers.w0 = result::InvalidHandle;
}
}
@ -293,17 +294,17 @@ namespace skyline::kernel::svc {
try {
state.logger->Debug("svcSetThreadPriority: Setting thread priority to {}", priority);
state.process->GetHandle<type::KThread>(handle)->UpdatePriority(static_cast<u8>(priority));
state.ctx->registers.w0 = constant::status::Success;
state.ctx->registers.w0 = Result{};
} catch (const std::exception &) {
state.logger->Warn("svcSetThreadPriority: 'handle' invalid: 0x{:X}", handle);
state.ctx->registers.w0 = constant::status::InvHandle;
state.ctx->registers.w0 = result::InvalidHandle;
}
}
void ClearEvent(DeviceState &state) {
auto object = state.process->GetHandle<type::KEvent>(state.ctx->registers.w0);
object->signalled = false;
state.ctx->registers.w0 = constant::status::Success;
state.ctx->registers.w0 = Result{};
}
void MapSharedMemory(DeviceState &state) {
@ -312,14 +313,14 @@ namespace skyline::kernel::svc {
auto address = state.ctx->registers.x1;
if (!util::PageAligned(address)) {
state.ctx->registers.w0 = constant::status::InvAddress;
state.ctx->registers.w0 = result::InvalidAddress;
state.logger->Warn("svcMapSharedMemory: 'address' not page aligned: 0x{:X}", address);
return;
}
auto size = state.ctx->registers.x2;
if (!util::PageAligned(size)) {
state.ctx->registers.w0 = constant::status::InvSize;
state.ctx->registers.w0 = result::InvalidSize;
state.logger->Warn("svcMapSharedMemory: 'size' {}: 0x{:X}", size ? "not page aligned" : "is zero", size);
return;
}
@ -327,7 +328,7 @@ namespace skyline::kernel::svc {
memory::Permission permission = *reinterpret_cast<memory::Permission *>(&state.ctx->registers.w3);
if ((permission.w && !permission.r) || (permission.x && !permission.r)) {
state.logger->Warn("svcMapSharedMemory: 'permission' invalid: {}{}{}", permission.r ? "R" : "-", permission.w ? "W" : "-", permission.x ? "X" : "-");
state.ctx->registers.w0 = constant::status::InvPermission;
state.ctx->registers.w0 = result::InvalidNewMemoryPermission;
return;
}
@ -335,24 +336,24 @@ namespace skyline::kernel::svc {
object->Map(address, size, permission);
state.ctx->registers.w0 = constant::status::Success;
state.ctx->registers.w0 = Result{};
} catch (const std::exception &) {
state.logger->Warn("svcMapSharedMemory: 'handle' invalid: 0x{:X}", state.ctx->registers.w0);
state.ctx->registers.w0 = constant::status::InvHandle;
state.ctx->registers.w0 = result::InvalidHandle;
}
}
void CreateTransferMemory(DeviceState &state) {
auto address = state.ctx->registers.x1;
if (!util::PageAligned(address)) {
state.ctx->registers.w0 = constant::status::InvAddress;
state.ctx->registers.w0 = result::InvalidAddress;
state.logger->Warn("svcCreateTransferMemory: 'address' not page aligned: 0x{:X}", address);
return;
}
auto size = state.ctx->registers.x2;
if (!util::PageAligned(size)) {
state.ctx->registers.w0 = constant::status::InvSize;
state.ctx->registers.w0 = result::InvalidSize;
state.logger->Warn("svcCreateTransferMemory: 'size' {}: 0x{:X}", size ? "not page aligned" : "is zero", size);
return;
}
@ -360,7 +361,7 @@ namespace skyline::kernel::svc {
memory::Permission permission = *reinterpret_cast<memory::Permission *>(&state.ctx->registers.w3);
if ((permission.w && !permission.r) || (permission.x && !permission.r)) {
state.logger->Warn("svcCreateTransferMemory: 'permission' invalid: {}{}{}", permission.r ? "R" : "-", permission.w ? "W" : "-", permission.x ? "X" : "-");
state.ctx->registers.w0 = constant::status::InvPermission;
state.ctx->registers.w0 = result::InvalidNewMemoryPermission;
return;
}
@ -368,7 +369,7 @@ namespace skyline::kernel::svc {
auto shmem = state.process->NewHandle<type::KTransferMemory>(state.process->pid, address, size, permission);
state.ctx->registers.w0 = constant::status::Success;
state.ctx->registers.w0 = Result{};
state.ctx->registers.w1 = shmem.handle;
}
@ -377,10 +378,10 @@ namespace skyline::kernel::svc {
try {
state.process->handles.erase(handle);
state.logger->Debug("svcCloseHandle: Closing handle: 0x{:X}", handle);
state.ctx->registers.w0 = constant::status::Success;
state.ctx->registers.w0 = Result{};
} catch (const std::exception &) {
state.logger->Warn("svcCloseHandle: 'handle' invalid: 0x{:X}", handle);
state.ctx->registers.w0 = constant::status::InvHandle;
state.ctx->registers.w0 = result::InvalidHandle;
}
}
@ -399,16 +400,16 @@ namespace skyline::kernel::svc {
default: {
state.logger->Warn("svcResetSignal: 'handle' type invalid: 0x{:X} ({})", handle, object->objectType);
state.ctx->registers.w0 = constant::status::InvHandle;
state.ctx->registers.w0 = result::InvalidHandle;
return;
}
}
state.logger->Debug("svcResetSignal: Resetting signal: 0x{:X}", handle);
state.ctx->registers.w0 = constant::status::Success;
state.ctx->registers.w0 = Result{};
} catch (const std::out_of_range &) {
state.logger->Warn("svcResetSignal: 'handle' invalid: 0x{:X}", handle);
state.ctx->registers.w0 = constant::status::InvHandle;
state.ctx->registers.w0 = result::InvalidHandle;
return;
}
}
@ -418,7 +419,7 @@ namespace skyline::kernel::svc {
auto numHandles = state.ctx->registers.w2;
if (numHandles > maxSyncHandles) {
state.ctx->registers.w0 = constant::status::MaxHandles;
state.ctx->registers.w0 = result::OutOfHandles;
return;
}
@ -440,7 +441,7 @@ namespace skyline::kernel::svc {
break;
default: {
state.ctx->registers.w0 = constant::status::InvHandle;
state.ctx->registers.w0 = result::InvalidHandle;
return;
}
}
@ -455,7 +456,7 @@ namespace skyline::kernel::svc {
while (true) {
if (state.thread->cancelSync) {
state.thread->cancelSync = false;
state.ctx->registers.w0 = constant::status::Interrupted;
state.ctx->registers.w0 = result::Cancelled;
break;
}
@ -463,7 +464,7 @@ namespace skyline::kernel::svc {
for (const auto &object : objectTable) {
if (object->signalled) {
state.logger->Debug("svcWaitSynchronization: Signalled handle: 0x{:X}", waitHandles.at(index));
state.ctx->registers.w0 = constant::status::Success;
state.ctx->registers.w0 = Result{};
state.ctx->registers.w1 = index;
return;
}
@ -472,7 +473,7 @@ namespace skyline::kernel::svc {
if ((util::GetTimeNs() - start) >= timeout) {
state.logger->Debug("svcWaitSynchronization: Wait has timed out");
state.ctx->registers.w0 = constant::status::Timeout;
state.ctx->registers.w0 = result::TimedOut;
return;
}
}
@ -483,7 +484,7 @@ namespace skyline::kernel::svc {
state.process->GetHandle<type::KThread>(state.ctx->registers.w0)->cancelSync = true;
} catch (const std::exception &) {
state.logger->Warn("svcCancelSynchronization: 'handle' invalid: 0x{:X}", state.ctx->registers.w0);
state.ctx->registers.w0 = constant::status::InvHandle;
state.ctx->registers.w0 = result::InvalidHandle;
}
}
@ -491,7 +492,7 @@ namespace skyline::kernel::svc {
auto address = state.ctx->registers.x1;
if (!util::WordAligned(address)) {
state.logger->Warn("svcArbitrateLock: 'address' not word aligned: 0x{:X}", address);
state.ctx->registers.w0 = constant::status::InvAddress;
state.ctx->registers.w0 = result::InvalidAddress;
return;
}
@ -507,14 +508,14 @@ namespace skyline::kernel::svc {
else
state.logger->Debug("svcArbitrateLock: Owner handle did not match current owner for mutex or didn't have waiter flag at 0x{:X}", address);
state.ctx->registers.w0 = constant::status::Success;
state.ctx->registers.w0 = Result{};
}
void ArbitrateUnlock(DeviceState &state) {
auto address = state.ctx->registers.x0;
if (!util::WordAligned(address)) {
state.logger->Warn("svcArbitrateUnlock: 'address' not word aligned: 0x{:X}", address);
state.ctx->registers.w0 = constant::status::InvAddress;
state.ctx->registers.w0 = result::InvalidAddress;
return;
}
@ -522,10 +523,10 @@ namespace skyline::kernel::svc {
if (state.process->MutexUnlock(address)) {
state.logger->Debug("svcArbitrateUnlock: Unlocked mutex at 0x{:X}", address);
state.ctx->registers.w0 = constant::status::Success;
state.ctx->registers.w0 = Result{};
} else {
state.logger->Debug("svcArbitrateUnlock: A non-owner thread tried to release a mutex at 0x{:X}", address);
state.ctx->registers.w0 = constant::status::InvAddress;
state.ctx->registers.w0 = result::InvalidAddress;
}
}
@ -533,7 +534,7 @@ namespace skyline::kernel::svc {
auto mtxAddress = state.ctx->registers.x0;
if (!util::WordAligned(mtxAddress)) {
state.logger->Warn("svcWaitProcessWideKeyAtomic: mutex address not word aligned: 0x{:X}", mtxAddress);
state.ctx->registers.w0 = constant::status::InvAddress;
state.ctx->registers.w0 = result::InvalidAddress;
return;
}
@ -544,7 +545,7 @@ namespace skyline::kernel::svc {
if (!state.process->MutexUnlock(mtxAddress)) {
state.logger->Debug("WaitProcessWideKeyAtomic: A non-owner thread tried to release a mutex at 0x{:X}", mtxAddress);
state.ctx->registers.w0 = constant::status::InvAddress;
state.ctx->registers.w0 = result::InvalidAddress;
return;
}
@ -553,10 +554,10 @@ namespace skyline::kernel::svc {
if (state.process->ConditionalVariableWait(condAddress, mtxAddress, timeout)) {
state.logger->Debug("svcWaitProcessWideKeyAtomic: Waited for conditional variable and relocked mutex");
state.ctx->registers.w0 = constant::status::Success;
state.ctx->registers.w0 = Result{};
} else {
state.logger->Debug("svcWaitProcessWideKeyAtomic: Wait has timed out");
state.ctx->registers.w0 = constant::status::Timeout;
state.ctx->registers.w0 = result::TimedOut;
}
}
@ -566,7 +567,7 @@ namespace skyline::kernel::svc {
state.logger->Debug("svcSignalProcessWideKey: Signalling Conditional-Variable at 0x{:X} for {}", address, count);
state.process->ConditionalVariableSignal(address, count);
state.ctx->registers.w0 = constant::status::Success;
state.ctx->registers.w0 = Result{};
}
void GetSystemTick(DeviceState &state) {
@ -591,19 +592,19 @@ namespace skyline::kernel::svc {
handle = state.process->NewHandle<type::KSession>(std::static_pointer_cast<service::BaseService>(state.os->serviceManager.smUserInterface)).handle;
} else {
state.logger->Warn("svcConnectToNamedPort: Connecting to invalid port: '{}'", port);
state.ctx->registers.w0 = constant::status::NotFound;
state.ctx->registers.w0 = result::NotFound;
return;
}
state.logger->Debug("svcConnectToNamedPort: Connecting to port '{}' at 0x{:X}", port, handle);
state.ctx->registers.w1 = handle;
state.ctx->registers.w0 = constant::status::Success;
state.ctx->registers.w0 = Result{};
}
void SendSyncRequest(DeviceState &state) {
state.os->serviceManager.SyncRequestHandler(static_cast<KHandle>(state.ctx->registers.x0));
state.ctx->registers.w0 = constant::status::Success;
state.ctx->registers.w0 = Result{};
}
void GetThreadId(DeviceState &state) {
@ -619,7 +620,7 @@ namespace skyline::kernel::svc {
state.logger->Debug("svcGetThreadId: Handle: 0x{:X}, PID: {}", handle, pid);
state.ctx->registers.x1 = static_cast<u64>(pid);
state.ctx->registers.w0 = constant::status::Success;
state.ctx->registers.w0 = Result{};
}
void OutputDebugString(DeviceState &state) {
@ -629,7 +630,7 @@ namespace skyline::kernel::svc {
debug.pop_back();
state.logger->Info("Debug Output: {}", debug);
state.ctx->registers.w0 = constant::status::Success;
state.ctx->registers.w0 = Result{};
}
void GetInfo(DeviceState &state) {
@ -711,13 +712,13 @@ namespace skyline::kernel::svc {
default:
state.logger->Warn("svcGetInfo: Unimplemented case ID0: {}, ID1: {}", id0, id1);
state.ctx->registers.w0 = constant::status::Unimpl;
state.ctx->registers.w0 = result::InvalidEnumValue;
return;
}
state.logger->Debug("svcGetInfo: ID0: {}, ID1: {}, Out: 0x{:X}", id0, id1, out);
state.ctx->registers.x1 = out;
state.ctx->registers.w0 = constant::status::Success;
state.ctx->registers.w0 = Result{};
}
}

View File

@ -17,22 +17,35 @@ namespace skyline::service::account {
{0x65, SFUNC(IAccountServiceForApplication::GetBaasAccountManagerForApplication)}
}) {}
void IAccountServiceForApplication::GetUserExistence(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
Result IAccountServiceForApplication::GetUserExistence(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
auto id = request.Pop<UserId>();
// ID can't be zero
if (id == UserId{})
return result::NullArgument;
response.Push<u32>(id == constant::DefaultUserId);
return {};
}
void IAccountServiceForApplication::ListAllUsers(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
Result IAccountServiceForApplication::ListAllUsers(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
try {
// We only support one active user currently so hardcode this and ListOpenUsers
WriteUserList(request.outputBuf.at(0), {constant::DefaultUserId});
return WriteUserList(request.outputBuf.at(0), {constant::DefaultUserId});
} catch (const std::out_of_range &e) {
return result::InvalidInputBuffer;
}
}
void IAccountServiceForApplication::ListOpenUsers(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
WriteUserList(request.outputBuf.at(0), {constant::DefaultUserId});
Result IAccountServiceForApplication::ListOpenUsers(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
try {
return WriteUserList(request.outputBuf.at(0), {constant::DefaultUserId});
} catch (const std::out_of_range &e) {
return result::InvalidInputBuffer;
}
}
void IAccountServiceForApplication::WriteUserList(ipc::OutputBuffer buffer, std::vector<UserId> userIds) {
Result IAccountServiceForApplication::WriteUserList(ipc::OutputBuffer buffer, std::vector<UserId> userIds) {
std::span outputUserIds(state.process->GetPointer<UserId>(buffer.address), buffer.size / sizeof(UserId));
for (auto &userId : outputUserIds) {
@ -43,25 +56,34 @@ namespace skyline::service::account {
userIds.pop_back();
}
}
return {};
}
void IAccountServiceForApplication::GetLastOpenedUser(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
Result IAccountServiceForApplication::GetLastOpenedUser(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
response.Push(constant::DefaultUserId);
return {};
}
void IAccountServiceForApplication::InitializeApplicationInfoV0(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {}
Result IAccountServiceForApplication::InitializeApplicationInfoV0(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
return {};
}
void IAccountServiceForApplication::GetProfile(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
Result IAccountServiceForApplication::GetProfile(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
auto id = request.Pop<UserId>();
if (id != constant::DefaultUserId) {
response.errorCode = constant::status::InvUser;
return;
}
if (id != constant::DefaultUserId)
return result::UserNotFound;
manager.RegisterService(std::make_shared<IProfile>(state, manager, id), session, response);
return {};
}
void IAccountServiceForApplication::GetBaasAccountManagerForApplication(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
Result IAccountServiceForApplication::GetBaasAccountManagerForApplication(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
auto id = request.Pop<UserId>();
if (id == UserId{})
return result::NullArgument;
manager.RegisterService(SRVREG(IManagerForApplication), session, response);
return {};
}
}

View File

@ -8,6 +8,13 @@
namespace skyline {
namespace service::account {
namespace result {
constexpr Result NullArgument(124, 20);
constexpr Result InvalidArgument(124, 22);
constexpr Result InvalidInputBuffer(124, 32);
constexpr Result UserNotFound(124, 100);
}
/**
* @brief This hold an account's user ID
*/
@ -31,7 +38,7 @@ namespace skyline {
/**
* @brief Writes a vector of 128-bit user IDs to an output buffer
*/
void WriteUserList(ipc::OutputBuffer buffer, std::vector<UserId> userIds);
Result WriteUserList(ipc::OutputBuffer buffer, std::vector<UserId> userIds);
public:
IAccountServiceForApplication(const DeviceState &state, ServiceManager &manager);
@ -39,37 +46,37 @@ namespace skyline {
/**
* @brief This checks if the given user ID exists
*/
void GetUserExistence(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
Result GetUserExistence(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
/**
* @brief This returns a list of all user accounts on the console
*/
void ListAllUsers(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
Result ListAllUsers(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
/**
* @brief This returns a list of all open user accounts on the console
*/
void ListOpenUsers(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
Result ListOpenUsers(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
/**
* @brief This returns the user ID of the last active user on the console
*/
void GetLastOpenedUser(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
Result GetLastOpenedUser(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
/**
* @brief This provides information about the running application for account services to use (https://switchbrew.org/wiki/Account_services#InitializeApplicationInfoV0)
*/
void InitializeApplicationInfoV0(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
Result InitializeApplicationInfoV0(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
/**
* @brief This returns a handle to an IProfile which can be used for reading user information
*/
void GetProfile(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
Result GetProfile(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
/**
* @brief This returns a handle to an IManagerForApplication which can be used for reading Nintendo Online info
*/
void GetBaasAccountManagerForApplication(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
Result GetBaasAccountManagerForApplication(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
};
}

View File

@ -10,7 +10,7 @@ namespace skyline::service::account {
{0x1, SFUNC(IProfile::GetBase)}
}) {}
void IProfile::Get(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
Result IProfile::Get(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
struct AccountUserData {
u32 _unk0_;
u32 iconID; //!< Icon ID (0 = Mii, the rest are character icon IDs)
@ -23,10 +23,10 @@ namespace skyline::service::account {
auto userData = state.process->GetPointer<AccountUserData>(request.outputBuf.at(0).address);
userData->iconBackgroundColorID = 0x1; // Color indexing starts at 0x1
GetBase(session, request, response);
return GetBase(session, request, response);
}
void IProfile::GetBase(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
Result IProfile::GetBase(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
struct {
UserId uid; //!< The UID of the corresponding account
u64 lastEditTimestamp; //!< A POSIX UTC timestamp denoting the last account edit
@ -40,5 +40,7 @@ namespace skyline::service::account {
std::memcpy(accountProfileBase.nickname.data(), username.c_str(), usernameSize);
response.Push(accountProfileBase);
return {};
}
}

View File

@ -21,11 +21,11 @@ namespace skyline::service::account {
/**
* @brief This returns AccountUserData and AccountProfileBase objects that describe the user's information
*/
void Get(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
Result Get(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
/**
* @brief This returns an AccountProfileBase object that describe the user's information
*/
void GetBase(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
Result GetBase(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
};
}

View File

@ -16,19 +16,23 @@ namespace skyline::service::am {
{0x15E, SFUNC(IAllSystemAppletProxiesService::OpenApplicationProxy)}
}) {}
void IAllSystemAppletProxiesService::OpenLibraryAppletProxy(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
Result IAllSystemAppletProxiesService::OpenLibraryAppletProxy(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
manager.RegisterService(SRVREG(ILibraryAppletProxy), session, response);
return {};
}
void IAllSystemAppletProxiesService::OpenApplicationProxy(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
Result IAllSystemAppletProxiesService::OpenApplicationProxy(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
manager.RegisterService(SRVREG(IApplicationProxy), session, response);
return {};
}
void IAllSystemAppletProxiesService::OpenOverlayAppletProxy(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
Result IAllSystemAppletProxiesService::OpenOverlayAppletProxy(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
manager.RegisterService(SRVREG(IOverlayAppletProxy), session, response);
return {};
}
void IAllSystemAppletProxiesService::OpenSystemAppletProxy(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
Result IAllSystemAppletProxiesService::OpenSystemAppletProxy(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
manager.RegisterService(SRVREG(ISystemAppletProxy), session, response);
return {};
}
}

View File

@ -17,21 +17,21 @@ namespace skyline::service::am {
/**
* @brief This returns #ILibraryAppletProxy (https://switchbrew.org/wiki/Applet_Manager_services#OpenLibraryAppletProxy)
*/
void OpenLibraryAppletProxy(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
Result OpenLibraryAppletProxy(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
/**
* @brief This returns #IApplicationProxy (https://switchbrew.org/wiki/Applet_Manager_services#OpenApplicationProxy)
*/
void OpenApplicationProxy(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
Result OpenApplicationProxy(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
/**
* @brief This returns #IOverlayAppletProxy (https://switchbrew.org/wiki/Applet_Manager_services#OpenOverlayAppletProxy)
*/
void OpenOverlayAppletProxy(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
Result OpenOverlayAppletProxy(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
/**
* @brief This returns #ISystemAppletProxy (https://switchbrew.org/wiki/Applet_Manager_services#OpenSystemAppletProxy)
*/
void OpenSystemAppletProxy(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
Result OpenSystemAppletProxy(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
};
}

View File

@ -9,7 +9,8 @@ namespace skyline::service::am {
{0x0, SFUNC(IApplicationProxyService::OpenApplicationProxy)}
}) {}
void IApplicationProxyService::OpenApplicationProxy(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
Result IApplicationProxyService::OpenApplicationProxy(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
manager.RegisterService(SRVREG(IApplicationProxy), session, response);
return {};
}
}

View File

@ -17,6 +17,6 @@ namespace skyline::service::am {
/**
* @brief This returns #IApplicationProxy (https://switchbrew.org/wiki/Applet_Manager_services#OpenApplicationProxy)
*/
void OpenApplicationProxy(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
Result OpenApplicationProxy(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
};
}

View File

@ -15,22 +15,29 @@ namespace skyline::service::am {
{0x65, SFUNC(ILibraryAppletAccessor::PopOutData)},
}) {}
void ILibraryAppletAccessor::GetAppletStateChangedEvent(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
Result ILibraryAppletAccessor::GetAppletStateChangedEvent(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
stateChangeEvent->Signal();
KHandle handle = state.process->InsertItem(stateChangeEvent);
state.logger->Debug("Applet State Change Event Handle: 0x{:X}", handle);
response.copyHandles.push_back(handle);
return {};
}
void ILibraryAppletAccessor::Start(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {}
Result ILibraryAppletAccessor::Start(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
return {};
}
void ILibraryAppletAccessor::GetResult(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {}
Result ILibraryAppletAccessor::GetResult(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
return {};
}
void ILibraryAppletAccessor::PushInData(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {}
Result ILibraryAppletAccessor::PushInData(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
return {};
}
void ILibraryAppletAccessor::PopOutData(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
Result ILibraryAppletAccessor::PopOutData(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
constexpr u32 LaunchParameterMagic = 0xC79497CA; //!< This is the magic of the application launch parameters
constexpr size_t LaunchParameterSize = 0x88; //!< This is the size of the launch parameter IStorage
@ -41,5 +48,6 @@ namespace skyline::service::am {
storageService->Push(constant::DefaultUserId);
manager.RegisterService(storageService, session, response);
return {};
}
}

View File

@ -21,26 +21,26 @@ namespace skyline::service::am {
/**
* @brief This function returns a handle to the library applet state change event
*/
void GetAppletStateChangedEvent(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
Result GetAppletStateChangedEvent(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
/**
* @brief This function starts the library applet (https://switchbrew.org/wiki/Applet_Manager_services#Start)
*/
void Start(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
Result Start(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
/**
* @brief This function returns the exit code of the library applet (https://switchbrew.org/wiki/Applet_Manager_services#GetResult)
*/
void GetResult(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
Result GetResult(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
/**
* @brief This function pushes in data to the library applet (https://switchbrew.org/wiki/Applet_Manager_services#PushInData)
*/
void PushInData(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
Result PushInData(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
/**
* @brief This function receives data from the library applet (https://switchbrew.org/wiki/Applet_Manager_services#PopOutData)
*/
void PopOutData(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
Result PopOutData(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
};
}

View File

@ -19,7 +19,7 @@ namespace skyline::service::am {
{0x82, SFUNC(IApplicationFunctions::GetGpuErrorDetectedSystemEvent)},
}) {}
void IApplicationFunctions::PopLaunchParameter(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
Result IApplicationFunctions::PopLaunchParameter(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
constexpr u32 LaunchParameterMagic = 0xC79497CA; //!< This is the magic of the application launch parameters
constexpr size_t LaunchParameterSize = 0x88; //!< This is the size of the launch parameter IStorage
@ -30,32 +30,42 @@ namespace skyline::service::am {
storageService->Push(constant::DefaultUserId);
manager.RegisterService(storageService, session, response);
return {};
}
void IApplicationFunctions::EnsureSaveData(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
Result IApplicationFunctions::EnsureSaveData(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
response.Push<u8>(0);
return {};
}
void IApplicationFunctions::GetDesiredLanguage(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
Result IApplicationFunctions::GetDesiredLanguage(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
response.Push(util::MakeMagic<u64>("en-US"));
return {};
}
void IApplicationFunctions::NotifyRunning(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
Result IApplicationFunctions::NotifyRunning(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
response.Push<u8>(1);
return {};
}
void IApplicationFunctions::GetPseudoDeviceId(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
Result IApplicationFunctions::GetPseudoDeviceId(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
response.Push<u64>(0L);
response.Push<u64>(0L);
return {};
}
void IApplicationFunctions::InitializeGamePlayRecording(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {}
Result IApplicationFunctions::InitializeGamePlayRecording(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
return {};
}
void IApplicationFunctions::SetGamePlayRecordingState(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {}
Result IApplicationFunctions::SetGamePlayRecordingState(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
return {};
}
void IApplicationFunctions::GetGpuErrorDetectedSystemEvent(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
Result IApplicationFunctions::GetGpuErrorDetectedSystemEvent(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
auto handle = state.process->InsertItem(gpuErrorEvent);
state.logger->Debug("GPU Error Event Handle: 0x{:X}", handle);
response.copyHandles.push_back(handle);
return {};
}
}

View File

@ -21,41 +21,41 @@ namespace skyline::service::am {
/**
* @brief This returns an Applet Manager IStorage containing the application's launch parameters (https://switchbrew.org/wiki/Applet_Manager_services#PopLaunchParameter)
*/
void PopLaunchParameter(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
Result PopLaunchParameter(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
/**
* @brief This creates a save data folder for the requesting application (https://switchbrew.org/wiki/Applet_Manager_services#EnsureSaveData)
*/
void EnsureSaveData(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
Result EnsureSaveData(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
/**
* @brief This returns the desired language for the application (https://switchbrew.org/wiki/Applet_Manager_services#GetDesiredLanguage)
*/
void GetDesiredLanguage(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
Result GetDesiredLanguage(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
/**
* @brief This returns if the application is running or not, always returns true (https://switchbrew.org/wiki/Applet_Manager_services#NotifyRunning)
*/
void NotifyRunning(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
Result NotifyRunning(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
/**
* @brief This returns a UUID, however what it refers to is currently unknown (https://switchbrew.org/wiki/Applet_Manager_services#GetPseudoDeviceId)
*/
void GetPseudoDeviceId(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
Result GetPseudoDeviceId(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
/**
* @brief This initializes gameplay recording (https://switchbrew.org/wiki/Applet_Manager_services#InitializeGamePlayRecording)
*/
void InitializeGamePlayRecording(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
Result InitializeGamePlayRecording(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
/**
* @brief This controls the gameplay recording state (https://switchbrew.org/wiki/Applet_Manager_services#SetGamePlayRecordingState)
*/
void SetGamePlayRecordingState(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
Result SetGamePlayRecordingState(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
/**
* @brief This obtains a handle to the system GPU error KEvent (https://switchbrew.org/wiki/Applet_Manager_services#GetGpuErrorDetectedSystemEvent)
*/
void GetGpuErrorDetectedSystemEvent(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
Result GetGpuErrorDetectedSystemEvent(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
};
}

View File

@ -10,16 +10,19 @@ namespace skyline::service::am {
{0x2, SFUNC(IAudioController::GetLibraryAppletExpectedMasterVolume)}
}) {}
void IAudioController::SetExpectedMasterVolume(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
Result IAudioController::SetExpectedMasterVolume(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
mainAppletVolume = request.Pop<float>();
libraryAppletVolume = request.Pop<float>();
return {};
}
void IAudioController::GetMainAppletExpectedMasterVolume(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
Result IAudioController::GetMainAppletExpectedMasterVolume(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
response.Push<float>(mainAppletVolume);
return {};
}
void IAudioController::GetLibraryAppletExpectedMasterVolume(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
Result IAudioController::GetLibraryAppletExpectedMasterVolume(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
response.Push<float>(libraryAppletVolume);
return {};
}
}

View File

@ -21,16 +21,16 @@ namespace skyline::service::am {
/**
* @brief This sets the expected volumes for an application (https://switchbrew.org/wiki/Applet_Manager_services#SetExpectedMasterVolume)
*/
void SetExpectedMasterVolume(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
Result SetExpectedMasterVolume(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
/**
* @brief This returns the main applet volume that is expected by the application (https://switchbrew.org/wiki/Applet_Manager_services#GetMainAppletExpectedMasterVolume)
*/
void GetMainAppletExpectedMasterVolume(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
Result GetMainAppletExpectedMasterVolume(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
/**
* @brief This returns the library applet volume that is expected by the application (https://switchbrew.org/wiki/Applet_Manager_services#GetLibraryAppletExpectedMasterVolume)
*/
void GetLibraryAppletExpectedMasterVolume(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
Result GetLibraryAppletExpectedMasterVolume(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
};
}

View File

@ -23,35 +23,38 @@ namespace skyline::service::am {
QueueMessage(Message::FocusStateChange);
}
void ICommonStateGetter::GetEventHandle(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
Result ICommonStateGetter::GetEventHandle(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
auto handle = state.process->InsertItem(messageEvent);
state.logger->Debug("Applet Event Handle: 0x{:X}", handle);
response.copyHandles.push_back(handle);
return {};
}
void ICommonStateGetter::ReceiveMessage(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
if (messageQueue.empty()) {
response.errorCode = constant::status::NoMessages;
return;
}
Result ICommonStateGetter::ReceiveMessage(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
if (messageQueue.empty())
return result::NoMessages;
response.Push(messageQueue.front());
messageQueue.pop();
return {};
}
void ICommonStateGetter::GetCurrentFocusState(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
Result ICommonStateGetter::GetCurrentFocusState(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
response.Push(focusState);
return {};
}
void ICommonStateGetter::GetOperationMode(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
Result ICommonStateGetter::GetOperationMode(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
response.Push(operationMode);
return {};
}
void ICommonStateGetter::GetPerformanceMode(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
Result ICommonStateGetter::GetPerformanceMode(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
response.Push(static_cast<u32>(operationMode));
return {};
}
void ICommonStateGetter::GetDefaultDisplayResolution(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
Result ICommonStateGetter::GetDefaultDisplayResolution(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
if (operationMode == OperationMode::Handheld) {
response.Push<u32>(constant::HandheldResolutionW);
response.Push<u32>(constant::HandheldResolutionH);
@ -59,5 +62,6 @@ namespace skyline::service::am {
response.Push<u32>(constant::DockedResolutionW);
response.Push<u32>(constant::DockedResolutionH);
}
return {};
}
}

View File

@ -9,6 +9,10 @@
#include <services/serviceman.h>
namespace skyline::service::am {
namespace result {
constexpr Result NoMessages(128, 3);
}
/**
* @brief https://switchbrew.org/wiki/Applet_Manager_services#ICommonStateGetter
*/
@ -53,31 +57,31 @@ namespace skyline::service::am {
/**
* @brief This returns the handle to a KEvent object that is signalled whenever RecieveMessage has a message (https://switchbrew.org/wiki/Applet_Manager_services#GetEventHandle)
*/
void GetEventHandle(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
Result GetEventHandle(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
/**
* @brief This returns an #AppletMessage or 0x680 to indicate the lack of a message (https://switchbrew.org/wiki/Applet_Manager_services#ReceiveMessage)
*/
void ReceiveMessage(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
Result ReceiveMessage(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
/**
* @brief This returns if an application is in focus or not. It always returns in focus on the emulator (https://switchbrew.org/wiki/Applet_Manager_services#GetCurrentFocusState)
*/
void GetCurrentFocusState(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
Result GetCurrentFocusState(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
/**
* @brief This returns the current OperationMode (https://switchbrew.org/wiki/Applet_Manager_services#GetOperationMode)
*/
void GetOperationMode(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
Result GetOperationMode(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
/**
* @brief This returns the current PerformanceMode (Same as operationMode but u32) (https://switchbrew.org/wiki/Applet_Manager_services#GetPerformanceMode)
*/
void GetPerformanceMode(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
Result GetPerformanceMode(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
/**
* @brief This returns the current display width and height in two u32s (https://switchbrew.org/wiki/Applet_Manager_services#GetDefaultDisplayResolution)
*/
void GetDefaultDisplayResolution(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
Result GetDefaultDisplayResolution(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
};
}

View File

@ -11,16 +11,18 @@ namespace skyline::service::am {
{0xA, SFUNC(ILibraryAppletCreator::CreateStorage)}
}) {}
void ILibraryAppletCreator::CreateLibraryApplet(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
Result ILibraryAppletCreator::CreateLibraryApplet(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
manager.RegisterService(SRVREG(ILibraryAppletAccessor), session, response);
return {};
}
void ILibraryAppletCreator::CreateStorage(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
Result ILibraryAppletCreator::CreateStorage(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
auto size = request.Pop<i64>();
if (size < 0)
throw exception("Cannot create an IStorage with a negative size");
manager.RegisterService(std::make_shared<IStorage>(state, manager, size), session, response);
return {};
}
}

View File

@ -17,11 +17,11 @@ namespace skyline::service::am {
/**
* @brief This function returns a handle to a library applet accessor (https://switchbrew.org/wiki/Applet_Manager_services#CreateLibraryApplet)
*/
void CreateLibraryApplet(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
Result CreateLibraryApplet(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
/**
* @brief This function creates an IStorage that can be used by the application (https://switchbrew.org/wiki/Applet_Manager_services#CreateStorage)
*/
void CreateStorage(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
Result CreateStorage(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
};
}

View File

@ -20,30 +20,45 @@ namespace skyline::service::am {
{0x5B, SFUNC(ISelfController::GetLibraryAppletLaunchableEvent)}
}) {}
void ISelfController::LockExit(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {}
Result ISelfController::LockExit(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
return {};
}
void ISelfController::UnlockExit(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {}
Result ISelfController::UnlockExit(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
return {};
}
void ISelfController::GetLibraryAppletLaunchableEvent(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
Result ISelfController::GetLibraryAppletLaunchableEvent(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
libraryAppletLaunchableEvent->Signal();
KHandle handle = state.process->InsertItem(libraryAppletLaunchableEvent);
state.logger->Debug("Library Applet Launchable Event Handle: 0x{:X}", handle);
response.copyHandles.push_back(handle);
return {};
}
void ISelfController::SetOperationModeChangedNotification(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {}
Result ISelfController::SetOperationModeChangedNotification(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
return {};
}
void ISelfController::SetPerformanceModeChangedNotification(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {}
Result ISelfController::SetPerformanceModeChangedNotification(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
return {};
}
void ISelfController::SetFocusHandlingMode(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {}
Result ISelfController::SetFocusHandlingMode(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
return {};
}
void ISelfController::SetRestartMessageEnabled(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {}
Result ISelfController::SetRestartMessageEnabled(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
return {};
}
void ISelfController::SetOutOfFocusSuspendingEnabled(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {}
Result ISelfController::SetOutOfFocusSuspendingEnabled(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
return {};
}
void ISelfController::CreateManagedDisplayLayer(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
Result ISelfController::CreateManagedDisplayLayer(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
state.logger->Debug("Creating Managed Layer on Default Display");
auto hosBinder = state.os->serviceManager.GetService<hosbinder::IHOSBinderDriver>("dispdrv");
@ -52,12 +67,14 @@ namespace skyline::service::am {
hosBinder->layerStatus = hosbinder::LayerStatus::Managed;
response.Push<u64>(0);
return {};
}
void ISelfController::GetAccumulatedSuspendedTickChangedEvent(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
Result ISelfController::GetAccumulatedSuspendedTickChangedEvent(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
auto handle = state.process->InsertItem(accumulatedSuspendedTickChangedEvent);
state.logger->Debug("Accumulated Suspended Tick Event Handle: 0x{:X}", handle);
response.copyHandles.push_back(handle);
return {};
}
}

View File

@ -21,51 +21,51 @@ namespace skyline::service::am {
/**
* @brief This function prevents the running application from being quit via the home button (https://switchbrew.org/wiki/Applet_Manager_services#LockExit)
*/
void LockExit(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
Result LockExit(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
/**
* @brief This function allows the running application to be quit via the home button (https://switchbrew.org/wiki/Applet_Manager_services#UnlockExit)
*/
void UnlockExit(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
Result UnlockExit(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
/**
* @brief This function obtains a handle to the library applet launchable event (https://switchbrew.org/wiki/Applet_Manager_services#GetLibraryAppletLaunchableEvent)
*/
void GetLibraryAppletLaunchableEvent(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
Result GetLibraryAppletLaunchableEvent(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
/**
* @brief This function takes a u8 bool flag and no output (Stubbed) (https://switchbrew.org/wiki/Applet_Manager_services#SetOperationModeChangedNotification)
*/
void SetOperationModeChangedNotification(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
Result SetOperationModeChangedNotification(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
/**
* @brief This function takes a u8 bool flag and no output (Stubbed) (https://switchbrew.org/wiki/Applet_Manager_services#SetPerformanceModeChangedNotification)
*/
void SetPerformanceModeChangedNotification(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
Result SetPerformanceModeChangedNotification(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
/**
* @brief This function takes 3 unknown u8 values and has no output (Stubbed) (https://switchbrew.org/wiki/Applet_Manager_services#GetCurrentFocusState)
*/
void SetFocusHandlingMode(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
Result SetFocusHandlingMode(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
/**
* @brief This function toggles whether a restart message should be sent (https://switchbrew.org/wiki/Applet_Manager_services#SetRestartMessageEnabled)
*/
void SetRestartMessageEnabled(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
Result SetRestartMessageEnabled(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
/**
* @brief This function takes a u8 bool flag and has no output (Stubbed) (https://switchbrew.org/wiki/Applet_Manager_services#SetOutOfFocusSuspendingEnabled)
*/
void SetOutOfFocusSuspendingEnabled(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
Result SetOutOfFocusSuspendingEnabled(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
/**
* @brief This function returns an output u64 LayerId (https://switchbrew.org/wiki/Applet_Manager_services#CreateManagedDisplayLayer)
*/
void CreateManagedDisplayLayer(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
Result CreateManagedDisplayLayer(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
/**
* @brief This obtains a handle to the system sleep time change KEvent (https://switchbrew.org/wiki/Applet_Manager_services#GetAccumulatedSuspendedTickChangedEvent)
*/
void GetAccumulatedSuspendedTickChangedEvent(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
Result GetAccumulatedSuspendedTickChangedEvent(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
};
}

View File

@ -10,9 +10,12 @@ namespace skyline::service::am {
{0xA, SFUNC(IWindowController::AcquireForegroundRights)}
}) {}
void IWindowController::GetAppletResourceUserId(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
Result IWindowController::GetAppletResourceUserId(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
response.Push(static_cast<u64>(state.process->pid));
return {};
}
void IWindowController::AcquireForegroundRights(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {}
Result IWindowController::AcquireForegroundRights(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
return {};
}
}

View File

@ -17,11 +17,11 @@ namespace skyline::service::am {
/**
* @brief This returns the PID of the current application (https://switchbrew.org/wiki/Applet_Manager_services#GetAppletResourceUserId)
*/
void GetAppletResourceUserId(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
Result GetAppletResourceUserId(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
/**
* @brief This function has mo inputs or outputs (Stubbed) (https://switchbrew.org/wiki/Applet_Manager_services#AcquireForegroundRights)
*/
void AcquireForegroundRights(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
Result AcquireForegroundRights(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
};
}

View File

@ -16,7 +16,8 @@ namespace skyline::service::am {
{0x3E8, SFUNC(BaseProxy::GetDebugFunctions)}
}) {}
void IApplicationProxy::GetApplicationFunctions(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
Result IApplicationProxy::GetApplicationFunctions(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
manager.RegisterService(SRVREG(IApplicationFunctions), session, response);
return {};
}
}

View File

@ -16,6 +16,6 @@ namespace skyline::service::am {
/**
* @brief This returns #IApplicationFunctions (https://switchbrew.org/wiki/Applet_Manager_services#IApplicationFunctions)
*/
void GetApplicationFunctions(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
Result GetApplicationFunctions(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
};
}

View File

@ -12,37 +12,45 @@
#include "base_proxy.h"
namespace skyline::service::am {
BaseProxy::BaseProxy(const DeviceState &state, ServiceManager &manager, const std::unordered_map<u32, std::function<void(type::KSession &, ipc::IpcRequest &, ipc::IpcResponse &)>> &vTable) : BaseService(state, manager, vTable) {}
BaseProxy::BaseProxy(const DeviceState &state, ServiceManager &manager, const std::unordered_map<u32, std::function<Result(type::KSession &, ipc::IpcRequest &, ipc::IpcResponse &)>> &vTable) : BaseService(state, manager, vTable) {}
void BaseProxy::GetCommonStateGetter(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
Result BaseProxy::GetCommonStateGetter(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
manager.RegisterService(SRVREG(ICommonStateGetter), session, response);
return {};
}
void BaseProxy::GetSelfController(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
Result BaseProxy::GetSelfController(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
manager.RegisterService(SRVREG(ISelfController), session, response);
return {};
}
void BaseProxy::GetWindowController(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
Result BaseProxy::GetWindowController(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
manager.RegisterService(SRVREG(IWindowController), session, response);
return {};
}
void BaseProxy::GetAudioController(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
Result BaseProxy::GetAudioController(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
manager.RegisterService(SRVREG(IAudioController), session, response);
return {};
}
void BaseProxy::GetDisplayController(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
Result BaseProxy::GetDisplayController(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
manager.RegisterService(SRVREG(IDisplayController), session, response);
return {};
}
void BaseProxy::GetLibraryAppletCreator(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
Result BaseProxy::GetLibraryAppletCreator(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
manager.RegisterService(SRVREG(ILibraryAppletCreator), session, response);
return {};
}
void BaseProxy::GetDebugFunctions(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
Result BaseProxy::GetDebugFunctions(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
manager.RegisterService(SRVREG(IDebugFunctions), session, response);
return {};
}
void BaseProxy::GetAppletCommonFunctions(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
Result BaseProxy::GetAppletCommonFunctions(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
manager.RegisterService(SRVREG(IAppletCommonFunctions), session, response);
return {};
}
}

View File

@ -12,46 +12,46 @@ namespace skyline::service::am {
*/
class BaseProxy : public BaseService {
public:
BaseProxy(const DeviceState &state, ServiceManager &manager, const std::unordered_map<u32, std::function<void(type::KSession & , ipc::IpcRequest & , ipc::IpcResponse & )>> &vTable);
BaseProxy(const DeviceState &state, ServiceManager &manager, const std::unordered_map<u32, std::function<Result(type::KSession & , ipc::IpcRequest & , ipc::IpcResponse & )>> &vTable);
/**
* @brief This returns #ICommonStateGetter (https://switchbrew.org/wiki/Applet_Manager_services#ICommonStateGetter)
*/
void GetCommonStateGetter(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
Result GetCommonStateGetter(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
/**
* @brief This returns #ISelfController (https://switchbrew.org/wiki/Applet_Manager_services#ISelfController)
*/
void GetSelfController(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
Result GetSelfController(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
/**
* @brief This returns #IWindowController (https://switchbrew.org/wiki/Applet_Manager_services#IWindowController)
*/
void GetWindowController(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
Result GetWindowController(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
/**
* @brief This returns #IAudioController (https://switchbrew.org/wiki/Applet_Manager_services#IAudioController)
*/
void GetAudioController(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
Result GetAudioController(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
/**
* @brief This returns #IDisplayController (https://switchbrew.org/wiki/Applet_Manager_services#IDisplayController)
*/
void GetDisplayController(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
Result GetDisplayController(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
/**
* @brief This returns #ILibraryAppletCreator (https://switchbrew.org/wiki/Applet_Manager_services#ILibraryAppletCreator)
*/
void GetLibraryAppletCreator(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
Result GetLibraryAppletCreator(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
/**
* @brief This returns #IDebugFunctions (https://switchbrew.org/wiki/Applet_Manager_services#IDebugFunctions)
*/
void GetDebugFunctions(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
Result GetDebugFunctions(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
/**
* @brief This returns #IAppletCommonFunctions (https://switchbrew.org/wiki/Applet_Manager_services#IAppletCommonFunctions)
*/
void GetAppletCommonFunctions(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
Result GetAppletCommonFunctions(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
};
}

View File

@ -9,7 +9,8 @@ namespace skyline::service::am {
{0x0, SFUNC(IStorage::Open)}
}) {}
void IStorage::Open(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
Result IStorage::Open(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
manager.RegisterService(std::make_shared<IStorageAccessor>(state, manager, shared_from_this()), session, response);
return {};
}
}

View File

@ -22,7 +22,7 @@ namespace skyline::service::am {
/**
* @brief This returns an IStorageAccessor that can read and write data to an IStorage
*/
void Open(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
Result Open(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
/**
* @brief This function writes an object to the storage

View File

@ -12,30 +12,34 @@ namespace skyline::service::am {
{0xB, SFUNC(IStorageAccessor::Read)}
}) {}
void IStorageAccessor::GetSize(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
Result IStorageAccessor::GetSize(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
response.Push<i64>(parent->content.size());
return {};
}
void IStorageAccessor::Write(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
Result IStorageAccessor::Write(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
auto offset = request.Pop<i64>();
auto size = request.inputBuf.at(0).size;
auto size = std::min(static_cast<i64>(request.inputBuf.at(0).size), static_cast<i64>(parent->content.size()) - offset);
if (offset + size > parent->content.size())
throw exception("Trying to write past the end of an IStorage");
if (offset < 0)
throw exception("Trying to write before the start of an IStorage");
if (offset > parent->content.size())
return result::OutOfBounds;
if (size > 0)
state.process->ReadMemory(parent->content.data() + offset, request.inputBuf.at(0).address, size);
return {};
}
void IStorageAccessor::Read(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
auto offset = request.Pop<u64>();
auto size = request.outputBuf.at(0).size;
Result IStorageAccessor::Read(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
auto offset = request.Pop<i64>();
auto size = std::min(static_cast<i64>(request.inputBuf.at(0).size), static_cast<i64>(parent->content.size()) - offset);
if (offset + size > parent->content.size())
throw exception("Trying to read past the end of an IStorage");
if (offset > parent->content.size())
return result::OutOfBounds;
if (size > 0)
state.process->WriteMemory(parent->content.data() + offset, request.outputBuf.at(0).address, size);
return {};
}
}

View File

@ -7,6 +7,9 @@
#include <services/serviceman.h>
namespace skyline::service::am {
namespace result {
constexpr Result OutOfBounds(128, 503);
}
class IStorage;
/**
@ -22,16 +25,16 @@ namespace skyline::service::am {
/**
* @brief This returns the size of the storage in bytes
*/
void GetSize(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
Result GetSize(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
/**
* @brief This writes a buffer to the storage at the specified offset
*/
void Write(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
Result Write(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
/**
* @brief This returns a buffer containing the contents of the storage at the specified offset
*/
void Read(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
Result Read(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
};
}

View File

@ -9,7 +9,8 @@ namespace skyline::service::apm {
{0x0, SFUNC(IManager::OpenSession)}
}) {}
void IManager::OpenSession(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
Result IManager::OpenSession(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
manager.RegisterService(SRVREG(ISession), session, response);
return {};
}
}

View File

@ -17,6 +17,6 @@ namespace skyline::service::apm {
/**
* @brief This returns an handle to ISession
*/
void OpenSession(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
Result OpenSession(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
};
}

View File

@ -9,15 +9,17 @@ namespace skyline::service::apm {
{0x1, SFUNC(ISession::GetPerformanceConfiguration)}
}) {}
void ISession::SetPerformanceConfiguration(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
Result ISession::SetPerformanceConfiguration(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
auto mode = request.Pop<u32>();
auto config = request.Pop<u32>();
performanceConfig.at(mode) = config;
state.logger->Info("SetPerformanceConfiguration called with 0x{:X} ({})", config, mode ? "Docked" : "Handheld");
return {};
}
void ISession::GetPerformanceConfiguration(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
u32 performanceMode = request.Pop<u32>();
Result ISession::GetPerformanceConfiguration(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
auto performanceMode = request.Pop<u32>();
response.Push<u32>(performanceConfig.at(performanceMode));
return {};
}
}

View File

@ -20,11 +20,11 @@ namespace skyline::service::apm {
/**
* @brief This sets performanceConfig to the given arguments, it doesn't affect anything else (https://switchbrew.org/wiki/PPC_services#SetPerformanceConfiguration)
*/
void SetPerformanceConfiguration(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
Result SetPerformanceConfiguration(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
/**
* @brief This retrieves the particular performanceConfig for a mode and returns it to the client (https://switchbrew.org/wiki/PPC_services#SetPerformanceConfiguration)
*/
void GetPerformanceConfiguration(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
Result GetPerformanceConfiguration(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
};
}

View File

@ -17,7 +17,7 @@ namespace skyline::service::audio {
{0xA, SFUNC(IAudioDevice::GetActiveAudioDeviceName)}
}) {}
void IAudioDevice::ListAudioDeviceName(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
Result IAudioDevice::ListAudioDeviceName(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
u64 offset{};
for (std::string deviceName : {"AudioTvOutput", "AudioStereoJackOutput", "AudioBuiltInSpeakerOutput"}) {
if (offset + deviceName.size() + 1 > request.outputBuf.at(0).size)
@ -26,26 +26,32 @@ namespace skyline::service::audio {
state.process->WriteMemory(deviceName.c_str(), request.outputBuf.at(0).address + offset, deviceName.size() + 1);
offset += deviceName.size() + 1;
}
return {};
}
void IAudioDevice::SetAudioDeviceOutputVolume(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {}
Result IAudioDevice::SetAudioDeviceOutputVolume(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
return {};
}
void IAudioDevice::GetActiveAudioDeviceName(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
Result IAudioDevice::GetActiveAudioDeviceName(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
std::string deviceName("AudioStereoJackOutput");
if (deviceName.size() > request.outputBuf.at(0).size)
throw exception("Too small a buffer supplied to GetActiveAudioDeviceName");
state.process->WriteMemory(deviceName.c_str(), request.outputBuf.at(0).address, deviceName.size() + 1);
return {};
}
void IAudioDevice::QueryAudioDeviceSystemEvent(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
Result IAudioDevice::QueryAudioDeviceSystemEvent(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
auto handle{state.process->InsertItem(systemEvent)};
state.logger->Debug("Audio Device System Event Handle: 0x{:X}", handle);
response.copyHandles.push_back(handle);
return {};
}
void IAudioDevice::GetActiveChannelCount(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
Result IAudioDevice::GetActiveChannelCount(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
response.Push<u32>(constant::ChannelCount);
return {};
}
}

View File

@ -20,26 +20,26 @@ namespace skyline::service::audio {
/**
* @brief This returns a list of the available audio devices (https://switchbrew.org/wiki/Audio_services#ListAudioDeviceName)
*/
void ListAudioDeviceName(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
Result ListAudioDeviceName(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
/**
* @brief This sets the volume of an audio output (https://switchbrew.org/wiki/Audio_services#SetAudioDeviceOutputVolume)
*/
void SetAudioDeviceOutputVolume(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
Result SetAudioDeviceOutputVolume(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
/**
* @brief This returns the active audio output device
*/
void GetActiveAudioDeviceName(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
Result GetActiveAudioDeviceName(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
/**
* @brief This returns the audio device system event
*/
void QueryAudioDeviceSystemEvent(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
Result QueryAudioDeviceSystemEvent(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
/**
* @brief This returns the current output devices channel count
*/
void GetActiveChannelCount(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
Result GetActiveChannelCount(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
};
}

View File

@ -23,21 +23,24 @@ namespace skyline::service::audio {
state.audio->CloseTrack(track);
}
void IAudioOut::GetAudioOutState(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
Result IAudioOut::GetAudioOutState(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
response.Push(static_cast<u32>(track->playbackState));
return {};
}
void IAudioOut::StartAudioOut(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
Result IAudioOut::StartAudioOut(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
state.logger->Debug("IAudioOut: Start playback");
track->Start();
return {};
}
void IAudioOut::StopAudioOut(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
Result IAudioOut::StopAudioOut(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
state.logger->Debug("IAudioOut: Stop playback");
track->Stop();
return {};
}
void IAudioOut::AppendAudioOutBuffer(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
Result IAudioOut::AppendAudioOutBuffer(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
struct Data {
u64 nextBufferPtr;
u64 sampleBufferPtr;
@ -55,15 +58,18 @@ namespace skyline::service::audio {
} else {
track->AppendBuffer(tag, std::span(state.process->GetPointer<i16>(data.sampleBufferPtr), data.sampleSize / sizeof(i16)));
}
return {};
}
void IAudioOut::RegisterBufferEvent(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
Result IAudioOut::RegisterBufferEvent(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
auto handle{state.process->InsertItem(releaseEvent)};
state.logger->Debug("IAudioOut: Buffer Release Event Handle: 0x{:X}", handle);
response.copyHandles.push_back(handle);
return {};
}
void IAudioOut::GetReleasedAudioOutBuffer(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
Result IAudioOut::GetReleasedAudioOutBuffer(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
auto maxCount{static_cast<u32>(request.outputBuf.at(0).size >> 3)};
std::vector<u64> releasedBuffers{track->GetReleasedBuffers(maxCount)};
auto count{static_cast<u32>(releasedBuffers.size())};
@ -73,11 +79,13 @@ namespace skyline::service::audio {
state.process->WriteMemory(releasedBuffers.data(), request.outputBuf.at(0).address, request.outputBuf.at(0).size);
response.Push<u32>(count);
return {};
}
void IAudioOut::ContainsAudioOutBuffer(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
Result IAudioOut::ContainsAudioOutBuffer(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
auto tag{request.Pop<u64>()};
response.Push(static_cast<u32>(track->ContainsBuffer(tag)));
return {};
}
}

View File

@ -37,36 +37,36 @@ namespace skyline::service::audio {
/**
* @brief Returns the playback state of the audio output (https://switchbrew.org/wiki/Audio_services#GetAudioOutState)
*/
void GetAudioOutState(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
Result GetAudioOutState(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
/**
* @brief Starts playback using data from appended samples (https://switchbrew.org/wiki/Audio_services#StartAudioOut)
*/
void StartAudioOut(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
Result StartAudioOut(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
/**
* @brief Stops playback of audio, waits for all samples to be released (https://switchbrew.org/wiki/Audio_services#StartAudioOut)
*/
void StopAudioOut(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
Result StopAudioOut(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
/**
* @brief Appends sample data to the output buffer (https://switchbrew.org/wiki/Audio_services#AppendAudioOutBuffer)
*/
void AppendAudioOutBuffer(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
Result AppendAudioOutBuffer(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
/**
* @brief Returns a handle to the sample release KEvent (https://switchbrew.org/wiki/Audio_services#AppendAudioOutBuffer)
*/
void RegisterBufferEvent(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
Result RegisterBufferEvent(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
/**
* @brief Returns the IDs of all pending released buffers (https://switchbrew.org/wiki/Audio_services#GetReleasedAudioOutBuffer)
*/
void GetReleasedAudioOutBuffer(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
Result GetReleasedAudioOutBuffer(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
/**
* @brief Checks if the given buffer ID is in the playback queue (https://switchbrew.org/wiki/Audio_services#ContainsAudioOutBuffer)
*/
void ContainsAudioOutBuffer(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
Result ContainsAudioOutBuffer(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
};
}

View File

@ -13,11 +13,12 @@ namespace skyline::service::audio {
{0x3, SFUNC(IAudioOutManager::OpenAudioOut)}
}) {}
void IAudioOutManager::ListAudioOuts(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
Result IAudioOutManager::ListAudioOuts(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
state.process->WriteMemory(reinterpret_cast<void *>(const_cast<char *>(constant::DefaultAudioOutName.data())), request.outputBuf.at(0).address, constant::DefaultAudioOutName.size());
return {};
}
void IAudioOutManager::OpenAudioOut(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
Result IAudioOutManager::OpenAudioOut(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
auto sampleRate{request.Pop<u32>()};
auto channelCount{static_cast<u16>(request.Pop<u32>())};
@ -32,5 +33,7 @@ namespace skyline::service::audio {
response.Push<u16>(0);
response.Push(static_cast<u32>(skyline::audio::AudioFormat::Int16));
response.Push(static_cast<u32>(skyline::audio::AudioOutState::Stopped));
return {};
}
}

View File

@ -23,12 +23,12 @@ namespace skyline {
/**
* @brief Returns a list of all available audio outputs (https://switchbrew.org/wiki/Audio_services#ListAudioOuts)
*/
void ListAudioOuts(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
Result ListAudioOuts(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
/**
* @brief Creates a new audoutU::IAudioOut object and returns a handle to it (https://switchbrew.org/wiki/Audio_services#OpenAudioOut)
*/
void OpenAudioOut(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
Result OpenAudioOut(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
};
}
}

View File

@ -34,23 +34,27 @@ namespace skyline::service::audio::IAudioRenderer {
state.audio->CloseTrack(track);
}
void IAudioRenderer::GetSampleRate(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
Result IAudioRenderer::GetSampleRate(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
response.Push<u32>(parameters.sampleRate);
return {};
}
void IAudioRenderer::GetSampleCount(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
Result IAudioRenderer::GetSampleCount(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
response.Push<u32>(parameters.sampleCount);
return {};
}
void IAudioRenderer::GetMixBufferCount(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
Result IAudioRenderer::GetMixBufferCount(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
response.Push<u32>(parameters.subMixCount);
return {};
}
void IAudioRenderer::GetState(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
Result IAudioRenderer::GetState(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
response.Push(static_cast<u32>(playbackState));
return {};
}
void IAudioRenderer::RequestUpdate(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
Result IAudioRenderer::RequestUpdate(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
auto inputAddress{request.inputBuf.at(0).address};
auto inputHeader{state.process->GetObject<UpdateDataHeader>(inputAddress)};
@ -125,6 +129,8 @@ namespace skyline::service::audio::IAudioRenderer {
state.process->WriteMemory(effect.output, outputAddress);
outputAddress += sizeof(EffectOut);
}
return {};
}
void IAudioRenderer::UpdateAudio() {
@ -171,17 +177,20 @@ namespace skyline::service::audio::IAudioRenderer {
}
}
void IAudioRenderer::Start(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
Result IAudioRenderer::Start(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
playbackState = skyline::audio::AudioOutState::Started;
return {};
}
void IAudioRenderer::Stop(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
Result IAudioRenderer::Stop(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
playbackState = skyline::audio::AudioOutState::Stopped;
return {};
}
void IAudioRenderer::QuerySystemEvent(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
Result IAudioRenderer::QuerySystemEvent(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
auto handle{state.process->InsertItem(systemEvent)};
state.logger->Debug("Audren System Event Handle: 0x{:X}", handle);
response.copyHandles.push_back(handle);
return {};
}
}

View File

@ -98,42 +98,42 @@ namespace skyline {
/**
* @brief Returns the sample rate (https://switchbrew.org/wiki/Audio_services#GetSampleRate)
*/
void GetSampleRate(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
Result GetSampleRate(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
/**
* @brief Returns the sample count (https://switchbrew.org/wiki/Audio_services#GetSampleCount)
*/
void GetSampleCount(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
Result GetSampleCount(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
/**
* @brief Returns the number of mix buffers (https://switchbrew.org/wiki/Audio_services#GetMixBufferCount)
*/
void GetMixBufferCount(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
Result GetMixBufferCount(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
/**
* @brief Returns the state of the renderer (https://switchbrew.org/wiki/Audio_services#GetAudioRendererState) (stubbed)?
*/
void GetState(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
Result GetState(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
/**
* @brief Updates the audio renderer state and appends new data to playback buffers
*/
void RequestUpdate(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
Result RequestUpdate(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
/**
* @brief Start the audio stream from the renderer
*/
void Start(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
Result Start(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
/**
* @brief Stop the audio stream from the renderer
*/
void Stop(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
Result Stop(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
/**
* @brief Returns a handle to the sample release KEvent
*/
void QuerySystemEvent(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
Result QuerySystemEvent(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
};
}
}

View File

@ -14,15 +14,17 @@ namespace skyline::service::audio {
{0x4, SFUNC(IAudioRendererManager::GetAudioDeviceService)}
}) {}
void IAudioRendererManager::OpenAudioRenderer(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
Result IAudioRendererManager::OpenAudioRenderer(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
IAudioRenderer::AudioRendererParameters params = request.Pop<IAudioRenderer::AudioRendererParameters>();
state.logger->Debug("IAudioRendererManager: Opening a rev {} IAudioRenderer with sample rate: {}, voice count: {}, effect count: {}", IAudioRenderer::ExtractVersionFromRevision(params.revision), params.sampleRate, params.voiceCount, params.effectCount);
manager.RegisterService(std::make_shared<IAudioRenderer::IAudioRenderer>(state, manager, params), session, response);
return {};
}
void IAudioRendererManager::GetAudioRendererWorkBufferSize(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
Result IAudioRendererManager::GetAudioRendererWorkBufferSize(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
IAudioRenderer::AudioRendererParameters params = request.Pop<IAudioRenderer::AudioRendererParameters>();
IAudioRenderer::RevisionInfo revisionInfo{};
@ -86,9 +88,11 @@ namespace skyline::service::audio {
state.logger->Debug("IAudioRendererManager: Work buffer size: 0x{:X}", size);
response.Push<i64>(size);
return {};
}
void IAudioRendererManager::GetAudioDeviceService(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
Result IAudioRendererManager::GetAudioDeviceService(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
manager.RegisterService(SRVREG(IAudioDevice), session, response);
return {};
}
}

View File

@ -17,16 +17,16 @@ namespace skyline::service::audio {
/**
* @brief Creates a new IAudioRenderer object and returns a handle to it
*/
void OpenAudioRenderer(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
Result OpenAudioRenderer(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
/**
* @brief Calculates the size of the buffer the guest needs to allocate for IAudioRendererManager
*/
void GetAudioRendererWorkBufferSize(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
Result GetAudioRendererWorkBufferSize(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
/**
* @brief This returns a handle to an instance of an IAudioDevice (https://switchbrew.org/wiki/Audio_services#GetAudioDeviceService)
*/
void GetAudioDeviceService(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
Result GetAudioDeviceService(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
};
}

View File

@ -28,14 +28,14 @@ namespace skyline::service {
protected:
const DeviceState &state; //!< The state of the device
ServiceManager &manager; //!< A reference to the service manager
std::unordered_map<u32, std::function<void(type::KSession &, ipc::IpcRequest &, ipc::IpcResponse &)>> vTable; //!< This holds the mapping from a function's CmdId to the actual function
std::unordered_map<u32, std::function<Result(type::KSession &, ipc::IpcRequest &, ipc::IpcResponse &)>> vTable; //!< This holds the mapping from a function's CmdId to the actual function
public:
/**
* @param state The state of the device
* @param vTable The functions of the service
*/
BaseService(const DeviceState &state, ServiceManager &manager, const std::unordered_map<u32, std::function<void(type::KSession &, ipc::IpcRequest &, ipc::IpcResponse &)>> &vTable) : state(state), manager(manager), vTable(vTable) {}
BaseService(const DeviceState &state, ServiceManager &manager, const std::unordered_map<u32, std::function<Result(type::KSession &, ipc::IpcRequest &, ipc::IpcResponse &)>> &vTable) : state(state), manager(manager), vTable(vTable) {}
/**
* @note To be able to extract the name of the underlying class and ensure correct destruction order
@ -57,17 +57,17 @@ namespace skyline::service {
* @param request The corresponding IpcRequest object
* @param response The corresponding IpcResponse object
*/
void HandleRequest(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
std::function<void(type::KSession &, ipc::IpcRequest &, ipc::IpcResponse &)> function;
Result HandleRequest(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
std::function<Result(type::KSession &, ipc::IpcRequest &, ipc::IpcResponse &)> function;
try {
function = vTable.at(request.payload->value);
} catch (std::out_of_range &) {
state.logger->Warn("Cannot find function in service '{0}': 0x{1:X} ({1})", GetName(), static_cast<u32>(request.payload->value));
return;
return {};
}
try {
function(session, request, response);
return function(session, request, response);
} catch (std::exception &e) {
throw exception("{} (Service: {})", e.what(), GetName());
}

View File

@ -10,7 +10,7 @@ namespace skyline::service::fatalsrv {
{0x2, SFUNC(IService::ThrowFatal)}
}) {}
void IService::ThrowFatal(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
Result IService::ThrowFatal(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
throw exception("A fatal error with code: 0x{:X} has caused emulation to stop", request.Pop<u32>());
}
}

View File

@ -17,6 +17,6 @@ namespace skyline::service::fatalsrv {
/**
* @brief This throws an exception that causes emulation to quit
*/
void ThrowFatal(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
Result ThrowFatal(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
};
}

View File

@ -9,10 +9,11 @@ namespace skyline::service::friends {
{0x0, SFUNC(INotificationService::GetEvent)},
}) {}
void INotificationService::GetEvent(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
Result INotificationService::GetEvent(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
KHandle handle = state.process->InsertItem(notificationEvent);
state.logger->Debug("Friend Notification Event Handle: 0x{:X}", handle);
response.copyHandles.push_back(handle);
return {};
}
}

View File

@ -21,6 +21,6 @@ namespace skyline::service::friends {
/**
* @brief This returns a handle to the notification event
*/
void GetEvent(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
Result GetEvent(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
};
}

View File

@ -11,11 +11,13 @@ namespace skyline::service::friends {
{0x1, SFUNC(IServiceCreator::CreateNotificationService)},
}) {}
void IServiceCreator::CreateFriendService(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
Result IServiceCreator::CreateFriendService(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
manager.RegisterService(SRVREG(IFriendService), session, response);
return {};
}
void IServiceCreator::CreateNotificationService(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
Result IServiceCreator::CreateNotificationService(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
manager.RegisterService(SRVREG(INotificationService), session, response);
return {};
}
}

View File

@ -17,11 +17,11 @@ namespace skyline::service::friends {
/**
* @brief This opens an IFriendService that can be used by applications to access user friend info
*/
void CreateFriendService(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
Result CreateFriendService(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
/**
* @brief This opens an INotificationService that can be used by applications to receive notifications
*/
void CreateNotificationService(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
Result CreateNotificationService(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
};
}

View File

@ -2,6 +2,7 @@
// Copyright © 2020 Skyline Team and Contributors (https://github.com/skyline-emu/)
#include <kernel/types/KProcess.h>
#include "results.h"
#include "IFile.h"
namespace skyline::service::fssrv {
@ -13,7 +14,7 @@ namespace skyline::service::fssrv {
{0x4, SFUNC(IFile::GetSize)}
}) {}
void IFile::Read(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
Result IFile::Read(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
auto readOption = request.Pop<u32>();
request.Skip<u32>();
auto offset = request.Pop<i64>();
@ -21,20 +22,19 @@ namespace skyline::service::fssrv {
if (offset < 0) {
state.logger->Warn("Trying to read a file with a negative offset");
response.errorCode = constant::status::InvAddress;
return;
return result::InvalidOffset;
}
if (size < 0) {
state.logger->Warn("Trying to read a file with a negative size");
response.errorCode = constant::status::InvSize;
return;
return result::InvalidSize;
}
response.Push<u32>(static_cast<u32>(backing->Read(state.process->GetPointer<u8>(request.outputBuf.at(0).address), offset, size)));
return {};
}
void IFile::Write(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
Result IFile::Write(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
auto writeOption = request.Pop<u32>();
request.Skip<u32>();
auto offset = request.Pop<i64>();
@ -42,35 +42,38 @@ namespace skyline::service::fssrv {
if (offset < 0) {
state.logger->Warn("Trying to write to a file with a negative offset");
response.errorCode = constant::status::InvAddress;
return;
return result::InvalidOffset;
}
if (size < 0) {
state.logger->Warn("Trying to write to a file with a negative size");
response.errorCode = constant::status::InvSize;
return;
return result::InvalidSize;
}
if (request.inputBuf.at(0).size < size) {
state.logger->Warn("The input buffer is not large enough to fit the requested size");
response.errorCode = constant::status::InvSize;
return;
return result::InvalidSize;
}
if (backing->Write(state.process->GetPointer<u8>(request.inputBuf.at(0).address), offset, request.inputBuf.at(0).size) != size) {
state.logger->Warn("Failed to write all data to the backing");
response.errorCode = constant::status::GenericError;
}
return result::UnexpectedFailure;
}
void IFile::Flush(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {}
return {};
}
void IFile::SetSize(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
Result IFile::Flush(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
return {};
}
Result IFile::SetSize(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
backing->Resize(request.Pop<u64>());
return {};
}
void IFile::GetSize(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
Result IFile::GetSize(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
response.Push<u64>(backing->size);
return {};
}
}

View File

@ -21,26 +21,26 @@ namespace skyline::service::fssrv {
/**
* @brief This reads a buffer from a region of an IFile
*/
void Read(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
Result Read(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
/**
* @brief This writes a buffer to a region of an IFile
*/
void Write(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
Result Write(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
/**
* @brief This flushes any written data to the IFile on the Switch, however the emulator processes any FS event immediately so this does nothing
*/
void Flush(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
Result Flush(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
/**
* @brief This sets the size of an IFile
*/
void SetSize(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
Result SetSize(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
/**
* @brief This obtains the size of an IFile
*/
void GetSize(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
Result GetSize(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
};
}

View File

@ -3,6 +3,7 @@
#include <kernel/types/KProcess.h>
#include <vfs/filesystem.h>
#include "results.h"
#include "IFile.h"
#include "IFileSystem.h"
@ -14,42 +15,45 @@ namespace skyline::service::fssrv {
{0xA, SFUNC(IFileSystem::Commit)}
}) {}
void IFileSystem::CreateFile(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
Result IFileSystem::CreateFile(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
std::string path = std::string(state.process->GetPointer<char>(request.inputBuf.at(0).address));
auto mode = request.Pop<u64>();
auto size = request.Pop<u32>();
response.errorCode = backing->CreateFile(path, size) ? constant::status::Success : constant::status::PathDoesNotExist;
return backing->CreateFile(path, size) ? Result{} : result::PathDoesNotExist;
}
void IFileSystem::GetEntryType(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
Result IFileSystem::GetEntryType(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
std::string path = std::string(state.process->GetPointer<char>(request.inputBuf.at(0).address));
auto type = backing->GetEntryType(path);
if (type) {
response.Push(*type);
return {};
} else {
response.Push<u32>(0);
response.errorCode = constant::status::PathDoesNotExist;
return result::PathDoesNotExist;
}
}
void IFileSystem::OpenFile(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
std::string path = std::string(state.process->GetPointer<char>(request.inputBuf.at(0).address));
Result IFileSystem::OpenFile(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
std::string path(state.process->GetPointer<char>(request.inputBuf.at(0).address));
auto mode = request.Pop<vfs::Backing::Mode>();
if (!backing->FileExists(path)) {
response.errorCode = constant::status::PathDoesNotExist;
return;
}
if (!backing->FileExists(path))
return result::PathDoesNotExist;
auto file = backing->OpenFile(path, mode);
if (file == nullptr)
response.errorCode = constant::status::GenericError;
return result::UnexpectedFailure;
else
manager.RegisterService(std::make_shared<IFile>(file, state, manager), session, response);
return {};
}
void IFileSystem::Commit(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {}
Result IFileSystem::Commit(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
return {};
}
}

View File

@ -21,21 +21,21 @@ namespace skyline::service::fssrv {
/**
* @brief This creates a file at the specified path in the filesystem
*/
void CreateFile(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
Result CreateFile(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
/**
* @brief This queries the DirectoryEntryType of the given path (https://switchbrew.org/wiki/Filesystem_services#GetEntryType)
*/
void GetEntryType(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
Result GetEntryType(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
/**
* @brief This returns an IFile handle for the requested path (https://switchbrew.org/wiki/Filesystem_services#OpenFile)
*/
void OpenFile(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
Result OpenFile(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
/**
* @brief This commits all changes to the filesystem (https://switchbrew.org/wiki/Filesystem_services#Commit)
*/
void Commit(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
Result Commit(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
};
}

View File

@ -4,8 +4,9 @@
#include <os.h>
#include <vfs/os_filesystem.h>
#include <loader/loader.h>
#include "IFileSystemProxy.h"
#include "results.h"
#include "IStorage.h"
#include "IFileSystemProxy.h"
namespace skyline::service::fssrv {
IFileSystemProxy::IFileSystemProxy(const DeviceState &state, ServiceManager &manager) : BaseService(state, manager, {
@ -16,15 +17,17 @@ namespace skyline::service::fssrv {
{0x3ED, SFUNC(IFileSystemProxy::GetGlobalAccessLogMode)},
}) {}
void IFileSystemProxy::SetCurrentProcess(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
Result IFileSystemProxy::SetCurrentProcess(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
process = request.Pop<pid_t>();
return {};
}
void IFileSystemProxy::OpenSdCardFileSystem(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
Result IFileSystemProxy::OpenSdCardFileSystem(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
manager.RegisterService(std::make_shared<IFileSystem>(std::make_shared<vfs::OsFileSystem>(state.os->appFilesPath + "/switch/sdmc/"), state, manager), session, response);
return {};
}
void IFileSystemProxy::OpenSaveDataFileSystem(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
Result IFileSystemProxy::OpenSaveDataFileSystem(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
auto spaceId = request.Pop<SaveDataSpaceId>();
auto attribute = request.Pop<SaveDataAttribute>();
@ -61,16 +64,20 @@ namespace skyline::service::fssrv {
}();
manager.RegisterService(std::make_shared<IFileSystem>(std::make_shared<vfs::OsFileSystem>(state.os->appFilesPath + "/switch" + saveDataPath), state, manager), session, response);
return {};
}
void IFileSystemProxy::OpenDataStorageByCurrentProcess(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
if (state.loader->romFs)
Result IFileSystemProxy::OpenDataStorageByCurrentProcess(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
if (!state.loader->romFs)
return result::NoRomFsAvailable;
manager.RegisterService(std::make_shared<IStorage>(state.loader->romFs, state, manager), session, response);
else
throw exception("Tried to call OpenDataStorageByCurrentProcess without a valid RomFS");
return {};
}
void IFileSystemProxy::GetGlobalAccessLogMode(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
Result IFileSystemProxy::GetGlobalAccessLogMode(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
response.Push<u32>(0);
return {};
}
}

View File

@ -68,26 +68,26 @@ namespace skyline::service::fssrv {
/**
* @brief This sets the PID of the process using FS currently (https://switchbrew.org/wiki/Filesystem_services#SetCurrentProcess)
*/
void SetCurrentProcess(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
Result SetCurrentProcess(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
/**
* @brief This returns a handle to an instance of #IFileSystem (https://switchbrew.org/wiki/Filesystem_services#IFileSystem) with type SDCard
*/
void OpenSdCardFileSystem(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
Result OpenSdCardFileSystem(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
/**
* @brief This returns a handle to an instance of #IFileSystem (https://switchbrew.org/wiki/Filesystem_services#IFileSystem) for the requested save data area
*/
void OpenSaveDataFileSystem(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
Result OpenSaveDataFileSystem(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
/**
* @brief This returns a handle to an instance of #IStorage (https://switchbrew.org/wiki/Filesystem_services#IStorage) for the application's data storage
*/
void OpenDataStorageByCurrentProcess(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
Result OpenDataStorageByCurrentProcess(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
/**
* @brief This returns the filesystem log access mode (https://switchbrew.org/wiki/Filesystem_services#GetGlobalAccessLogMode)
*/
void GetGlobalAccessLogMode(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
Result GetGlobalAccessLogMode(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
};
}

View File

@ -2,6 +2,7 @@
// Copyright © 2020 Skyline Team and Contributors (https://github.com/skyline-emu/)
#include <kernel/types/KProcess.h>
#include "results.h"
#include "IStorage.h"
namespace skyline::service::fssrv {
@ -10,26 +11,26 @@ namespace skyline::service::fssrv {
{0x4, SFUNC(IStorage::GetSize)}
}) {}
void IStorage::Read(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
Result IStorage::Read(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
auto offset = request.Pop<i64>();
auto size = request.Pop<i64>();
if (offset < 0) {
state.logger->Warn("Trying to read a file with a negative offset");
response.errorCode = constant::status::InvAddress;
return;
return result::InvalidOffset;
}
if (size < 0) {
state.logger->Warn("Trying to read a file with a negative size");
response.errorCode = constant::status::InvSize;
return;
return result::InvalidSize;
}
backing->Read(state.process->GetPointer<u8>(request.outputBuf.at(0).address), offset, size);
return {};
}
void IStorage::GetSize(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
Result IStorage::GetSize(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
response.Push<u64>(backing->size);
return {};
}
}

View File

@ -21,11 +21,11 @@ namespace skyline::service::fssrv {
/**
* @brief This reads a buffer from a region of an IStorage (https://switchbrew.org/wiki/Filesystem_services#Read)
*/
void Read(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
Result Read(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
/**
* @brief This obtains the size of an IStorage (https://switchbrew.org/wiki/Filesystem_services#GetSize)
*/
void GetSize(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
Result GetSize(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
};
}

View File

@ -0,0 +1,15 @@
// SPDX-License-Identifier: MPL-2.0
// Copyright © 2020 Skyline Team and Contributors (https://github.com/skyline-emu/)
#pragma once
#include <common.h>
namespace skyline::service::fssrv::result {
constexpr Result PathDoesNotExist(2, 1);
constexpr Result NoRomFsAvailable(2, 1001);
constexpr Result UnexpectedFailure(2, 5000);
constexpr Result InvalidArgument(2, 6001);
constexpr Result InvalidOffset(2, 6061);
constexpr Result InvalidSize(2, 6062);
}

View File

@ -11,10 +11,12 @@ namespace skyline::service::hid {
{0x0, SFUNC(IActiveVibrationDeviceList::ActivateVibrationDevice)}
}) {}
void IActiveVibrationDeviceList::ActivateVibrationDevice(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
Result IActiveVibrationDeviceList::ActivateVibrationDevice(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
auto handle = request.Pop<NpadDeviceHandle>();
if (!handle.isRight)
state.input->npad.at(handle.id).vibrationRight = NpadVibrationValue{};
return {};
}
}

View File

@ -18,6 +18,6 @@ namespace skyline::service::hid {
/**
* @brief Activates a vibration device with the specified #VibrationDeviceHandle (https://switchbrew.org/wiki/HID_services#ActivateVibrationDevice)
*/
void ActivateVibrationDevice(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
Result ActivateVibrationDevice(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
};
}

View File

@ -9,10 +9,11 @@ namespace skyline::service::hid {
{0x0, SFUNC(IAppletResource::GetSharedMemoryHandle)}
}) {}
void IAppletResource::GetSharedMemoryHandle(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
Result IAppletResource::GetSharedMemoryHandle(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
auto handle = state.process->InsertItem<type::KSharedMemory>(state.input->kHid);
state.logger->Debug("HID Shared Memory Handle: 0x{:X}", handle);
response.copyHandles.push_back(handle);
return {};
}
}

View File

@ -18,6 +18,6 @@ namespace skyline::service::hid {
/**
* @brief This opens a handle to HID shared memory (https://switchbrew.org/wiki/HID_services#GetSharedMemoryHandle)
*/
void GetSharedMemoryHandle(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
Result GetSharedMemoryHandle(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
};
}

View File

@ -26,11 +26,12 @@ namespace skyline::service::hid {
{0xCE, SFUNC(IHidServer::SendVibrationValues)}
}) {}
void IHidServer::CreateAppletResource(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
Result IHidServer::CreateAppletResource(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
manager.RegisterService(SRVREG(IAppletResource), session, response);
return {};
}
void IHidServer::SetSupportedNpadStyleSet(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
Result IHidServer::SetSupportedNpadStyleSet(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
auto styleSet = request.Pop<NpadStyleSet>();
std::lock_guard lock(state.input->npad.mutex);
state.input->npad.styles = styleSet;
@ -38,13 +39,15 @@ namespace skyline::service::hid {
state.logger->Debug("Controller Support:\nPro-Controller: {}\nJoy-Con: Handheld: {}, Dual: {}, L: {}, R: {}\nGameCube: {}\nPokeBall: {}\nNES: {}, NES Handheld: {}, SNES: {}", static_cast<bool>(styleSet.proController), static_cast<bool>(styleSet.joyconHandheld), static_cast<bool>(styleSet.joyconDual), static_cast<bool>(styleSet.joyconLeft), static_cast<bool>
(styleSet.joyconRight), static_cast<bool>(styleSet.gamecube), static_cast<bool>(styleSet.palma), static_cast<bool>(styleSet.nes), static_cast<bool>(styleSet.nesHandheld), static_cast<bool>(styleSet.snes));
return {};
}
void IHidServer::GetSupportedNpadStyleSet(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
Result IHidServer::GetSupportedNpadStyleSet(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
response.Push(state.input->npad.styles);
return {};
}
void IHidServer::SetSupportedNpadIdType(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
Result IHidServer::SetSupportedNpadIdType(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
const auto &buffer = request.inputBuf.at(0);
u64 address = buffer.address;
size_t size = buffer.size / sizeof(NpadId);
@ -58,62 +61,73 @@ namespace skyline::service::hid {
std::lock_guard lock(state.input->npad.mutex);
state.input->npad.supportedIds = supportedIds;
state.input->npad.Update();
return {};
}
void IHidServer::ActivateNpad(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
Result IHidServer::ActivateNpad(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
state.input->npad.Activate();
return {};
}
void IHidServer::DeactivateNpad(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
Result IHidServer::DeactivateNpad(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
state.input->npad.Deactivate();
return {};
}
void IHidServer::AcquireNpadStyleSetUpdateEventHandle(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
Result IHidServer::AcquireNpadStyleSetUpdateEventHandle(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
auto id = request.Pop<NpadId>();
request.copyHandles.push_back(state.process->InsertItem(state.input->npad.at(id).updateEvent));
return {};
}
void IHidServer::ActivateNpadWithRevision(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
Result IHidServer::ActivateNpadWithRevision(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
state.input->npad.Activate();
return {};
}
void IHidServer::SetNpadJoyHoldType(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
Result IHidServer::SetNpadJoyHoldType(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
std::lock_guard lock(state.input->npad.mutex);
request.Skip<u64>();
state.input->npad.orientation = request.Pop<NpadJoyOrientation>();
state.input->npad.Update();
return {};
}
void IHidServer::GetNpadJoyHoldType(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
Result IHidServer::GetNpadJoyHoldType(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
response.Push(state.input->npad.orientation);
return {};
}
void IHidServer::SetNpadJoyAssignmentModeSingleByDefault(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
Result IHidServer::SetNpadJoyAssignmentModeSingleByDefault(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
auto id = request.Pop<NpadId>();
std::lock_guard lock(state.input->npad.mutex);
state.input->npad.at(id).SetAssignment(NpadJoyAssignment::Single);
state.input->npad.Update();
return {};
}
void IHidServer::SetNpadJoyAssignmentModeSingle(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
Result IHidServer::SetNpadJoyAssignmentModeSingle(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
auto id = request.Pop<NpadId>();
std::lock_guard lock(state.input->npad.mutex);
state.input->npad.at(id).SetAssignment(NpadJoyAssignment::Single);
state.input->npad.Update();
return {};
}
void IHidServer::SetNpadJoyAssignmentModeDual(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
Result IHidServer::SetNpadJoyAssignmentModeDual(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
auto id = request.Pop<NpadId>();
std::lock_guard lock(state.input->npad.mutex);
state.input->npad.at(id).SetAssignment(NpadJoyAssignment::Dual);
state.input->npad.Update();
return {};
}
void IHidServer::CreateActiveVibrationDeviceList(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
Result IHidServer::CreateActiveVibrationDeviceList(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
manager.RegisterService(SRVREG(IActiveVibrationDeviceList), session, response);
return {};
}
void IHidServer::SendVibrationValues(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
Result IHidServer::SendVibrationValues(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
request.Skip<u64>(); // appletResourceUserId
auto &handleBuf = request.inputBuf.at(0);
@ -136,5 +150,7 @@ namespace skyline::service::hid {
}
}
}
return {};
}
}

View File

@ -18,76 +18,76 @@ namespace skyline::service::hid {
/**
* @brief This returns an IAppletResource (https://switchbrew.org/wiki/HID_services#CreateAppletResource)
*/
void CreateAppletResource(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
Result CreateAppletResource(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
/**
* @brief This sets the style of controllers supported (https://switchbrew.org/wiki/HID_services#SetSupportedNpadStyleSet)
*/
void SetSupportedNpadStyleSet(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
Result SetSupportedNpadStyleSet(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
/**
* @brief This gets the style of controllers supported (https://switchbrew.org/wiki/HID_services#GetSupportedNpadStyleSet)
*/
void GetSupportedNpadStyleSet(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
Result GetSupportedNpadStyleSet(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
/**
* @brief This sets the NpadIds which are supported (https://switchbrew.org/wiki/HID_services#SetSupportedNpadIdType)
*/
void SetSupportedNpadIdType(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
Result SetSupportedNpadIdType(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
/**
* @brief This requests the activation of controllers (https://switchbrew.org/wiki/HID_services#ActivateNpad)
*/
void ActivateNpad(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
Result ActivateNpad(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
/**
* @brief This requests the deactivation of controllers (https://switchbrew.org/wiki/HID_services#DeactivateNpad)
*/
void DeactivateNpad(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
Result DeactivateNpad(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
/**
* @brief This requests an event that's signalled on a specific NpadId changing (https://switchbrew.org/wiki/HID_services#AcquireNpadStyleSetUpdateEventHandle)
*/
void AcquireNpadStyleSetUpdateEventHandle(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
Result AcquireNpadStyleSetUpdateEventHandle(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
/**
* @brief This requests the activation of controllers with a specific HID revision (https://switchbrew.org/wiki/HID_services#ActivateNpadWithRevision)
*/
void ActivateNpadWithRevision(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
Result ActivateNpadWithRevision(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
/**
* @brief Sets the Joy-Con hold mode (https://switchbrew.org/wiki/HID_services#SetNpadJoyHoldType)
*/
void SetNpadJoyHoldType(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
Result SetNpadJoyHoldType(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
/**
* @brief Sets the Joy-Con hold mode (https://switchbrew.org/wiki/HID_services#GetNpadJoyHoldType)
*/
void GetNpadJoyHoldType(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
Result GetNpadJoyHoldType(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
/**
* @brief Sets the Joy-Con assignment mode to Single by default (https://switchbrew.org/wiki/HID_services#SetNpadJoyAssignmentModeSingleByDefault)
*/
void SetNpadJoyAssignmentModeSingleByDefault(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
Result SetNpadJoyAssignmentModeSingleByDefault(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
/**
* @brief Sets the Joy-Con assignment mode to Single (https://switchbrew.org/wiki/HID_services#SetNpadJoyAssignmentModeSingle)
*/
void SetNpadJoyAssignmentModeSingle(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
Result SetNpadJoyAssignmentModeSingle(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
/**
* @brief Sets the Joy-Con assignment mode to Dual (https://switchbrew.org/wiki/HID_services#SetNpadJoyAssignmentModeDual)
*/
void SetNpadJoyAssignmentModeDual(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
Result SetNpadJoyAssignmentModeDual(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
/**
* @brief Returns an instance of #IActiveVibrationDeviceList (https://switchbrew.org/wiki/HID_services#CreateActiveVibrationDeviceList)
*/
void CreateActiveVibrationDeviceList(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
Result CreateActiveVibrationDeviceList(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
/**
* @brief Send vibration values to an NPad (https://switchbrew.org/wiki/HID_services#SendVibrationValues)
*/
void SendVibrationValues(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
Result SendVibrationValues(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
};
}

View File

@ -161,7 +161,7 @@ namespace skyline::service::hosbinder {
gbpBuffer->nvmapHandle, gbpBuffer->offset, (1U << gbpBuffer->blockHeightLog2), gbpBuffer->size);
}
void IHOSBinderDriver::TransactParcel(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
Result IHOSBinderDriver::TransactParcel(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
auto layerId = request.Pop<u32>();
auto code = request.Pop<TransactionCode>();
@ -192,7 +192,7 @@ namespace skyline::service::hosbinder {
.height = constant::HandheldResolutionH,
.transformHint = 0,
.pendingBuffers = 0,
.status = constant::status::Success,
.status = 0,
};
out.WriteData(connect);
break;
@ -207,20 +207,24 @@ namespace skyline::service::hosbinder {
}
out.WriteParcel(request.outputBuf.at(0));
return {};
}
void IHOSBinderDriver::AdjustRefcount(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
Result IHOSBinderDriver::AdjustRefcount(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
request.Skip<u32>();
auto addVal = request.Pop<i32>();
auto type = request.Pop<i32>();
state.logger->Debug("Reference Change: {} {} reference", addVal, type ? "strong" : "weak");
return {};
}
void IHOSBinderDriver::GetNativeHandle(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
Result IHOSBinderDriver::GetNativeHandle(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
KHandle handle = state.process->InsertItem(state.gpu->bufferEvent);
state.logger->Debug("Display Buffer Event Handle: 0x{:X}", handle);
response.copyHandles.push_back(handle);
response.Push<u32>(constant::status::Success);
return {};
}
void IHOSBinderDriver::SetDisplay(const std::string &name) {

View File

@ -48,6 +48,7 @@ namespace skyline::service::hosbinder {
};
std::unordered_map<u32, std::shared_ptr<Buffer>> queue; //!< A vector of shared pointers to all the queued buffers
/**
* @brief This the GbpBuffer struct of the specified buffer
*/
@ -90,17 +91,17 @@ namespace skyline::service::hosbinder {
/**
* @brief This emulates the transaction of parcels between a IGraphicBufferProducer and the application (https://switchbrew.org/wiki/Nvnflinger_services#TransactParcel)
*/
void TransactParcel(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
Result TransactParcel(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
/**
* @brief This adjusts the reference counts to the underlying binder, it is stubbed as we aren't using the real symbols (https://switchbrew.org/wiki/Nvnflinger_services#AdjustRefcount)
*/
void AdjustRefcount(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
Result AdjustRefcount(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
/**
* @brief This adjusts the reference counts to the underlying binder, it is stubbed as we aren't using the real symbols (https://switchbrew.org/wiki/Nvnflinger_services#GetNativeHandle)
*/
void GetNativeHandle(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
Result GetNativeHandle(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
/**
* @brief This sets displayId to a specific display type

View File

@ -9,7 +9,8 @@ namespace skyline::service::lm {
{0x0, SFUNC(ILogService::OpenLogger)}
}) {}
void ILogService::OpenLogger(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
Result ILogService::OpenLogger(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
manager.RegisterService(SRVREG(ILogger), session, response);
return {};
}
}

View File

@ -17,6 +17,6 @@ namespace skyline::service::lm {
/**
* @brief This opens an ILogger that can be used by applications to print log messages (https://switchbrew.org/wiki/Log_services#OpenLogger)
*/
void OpenLogger(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
Result OpenLogger(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
};
}

View File

@ -35,7 +35,7 @@ namespace skyline::service::lm {
}
}
void ILogger::Log(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
Result ILogger::Log(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
struct Data {
u64 pid;
u64 threadContext;
@ -98,7 +98,10 @@ namespace skyline::service::lm {
break;
}
return {};
}
void ILogger::SetDestination(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {}
Result ILogger::SetDestination(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
return {};
}
}

View File

@ -53,11 +53,11 @@ namespace skyline::service::lm {
/**
* @brief This prints a message to the log (https://switchbrew.org/wiki/Log_services#Log)
*/
void Log(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
Result Log(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
/**
* @brief This sets the log destination (https://switchbrew.org/wiki/Log_services#SetDestination)
*/
void SetDestination(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
Result SetDestination(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
};
}

View File

@ -9,5 +9,7 @@ namespace skyline::service::nfp {
{0x0, SFUNC(IUser::Initialize)}
}) {}
void IUser::Initialize(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {}
Result IUser::Initialize(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
return {};
}
}

View File

@ -17,6 +17,6 @@ namespace skyline::service::nfp {
/**
* @brief This initializes an NFP session
*/
void Initialize(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
Result Initialize(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
};
}

View File

@ -9,7 +9,8 @@ namespace skyline::service::nfp {
{0x0, SFUNC(IUserManager::CreateUserInterface)}
}) {}
void IUserManager::CreateUserInterface(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
Result IUserManager::CreateUserInterface(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
manager.RegisterService(SRVREG(IUser), session, response);
return {};
}
}

View File

@ -17,6 +17,6 @@ namespace skyline::service::nfp {
/**
* @brief This opens an IUser that can be used by applications to access NFC devices
*/
void CreateUserInterface(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
Result CreateUserInterface(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
};
}

View File

@ -9,7 +9,8 @@ namespace skyline::service::nifm {
{0x4, SFUNC(IGeneralService::CreateRequest)}
}) {}
void IGeneralService::CreateRequest(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
Result IGeneralService::CreateRequest(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
manager.RegisterService(SRVREG(IRequest), session, response);
return {};
}
}

View File

@ -17,6 +17,6 @@ namespace skyline::service::nifm {
/**
* @brief This creates an IRequest instance that can be used to bring up the network (https://switchbrew.org/wiki/Network_Interface_services#CreateRequest)
*/
void CreateRequest(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
Result CreateRequest(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
};
}

View File

@ -12,14 +12,17 @@ namespace skyline::service::nifm {
{0x4, SFUNC(IRequest::Submit)},
}) {}
void IRequest::GetRequestState(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
Result IRequest::GetRequestState(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
constexpr u32 Unsubmitted = 1; //!< The request has not been submitted
response.Push<u32>(Unsubmitted);
return {};
}
void IRequest::GetResult(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {}
Result IRequest::GetResult(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
return {};
}
void IRequest::GetSystemEventReadableHandles(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
Result IRequest::GetSystemEventReadableHandles(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
auto handle = state.process->InsertItem(event0);
state.logger->Debug("Request Event 0 Handle: 0x{:X}", handle);
response.copyHandles.push_back(handle);
@ -27,7 +30,11 @@ namespace skyline::service::nifm {
handle = state.process->InsertItem(event1);
state.logger->Debug("Request Event 1 Handle: 0x{:X}", handle);
response.copyHandles.push_back(handle);
return {};
}
void IRequest::Submit(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {}
Result IRequest::Submit(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
return {};
}
}

View File

@ -22,21 +22,21 @@ namespace skyline::service::nifm {
/**
* @brief This returns the current state of the request (https://switchbrew.org/wiki/Network_Interface_services#GetRequestState)
*/
void GetRequestState(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
Result GetRequestState(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
/**
* @brief This returns the error code if a network bring up request fails (https://switchbrew.org/wiki/Network_Interface_services#GetResult)
*/
void GetResult(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
Result GetResult(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
/**
* @brief This returns two KEvent handles that signal request on request updates (https://switchbrew.org/wiki/Network_Interface_services#GetSystemEventReadableHandles)
*/
void GetSystemEventReadableHandles(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
Result GetSystemEventReadableHandles(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
/**
* @brief This submits a request to bring up a network (https://switchbrew.org/wiki/Network_Interface_services#Submit)
*/
void Submit(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
Result Submit(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
};
}

View File

@ -10,7 +10,8 @@ namespace skyline::service::nifm {
{0x5, SFUNC(IStaticService::CreateGeneralService)}
}) {}
void IStaticService::CreateGeneralService(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
Result IStaticService::CreateGeneralService(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
manager.RegisterService(SRVREG(IGeneralService), session, response);
return {};
}
}

View File

@ -17,6 +17,6 @@ namespace skyline::service::nifm {
/**
* @brief This opens an IGeneralService that can be used by applications to control the network connection (https://switchbrew.org/wiki/Network_Interface_services#CreateGeneralServiceOld)
*/
void CreateGeneralService(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
Result CreateGeneralService(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
};
}

View File

@ -64,15 +64,17 @@ namespace skyline::service::nvdrv {
{0xD, SFUNC(INvDrvServices::SetGraphicsFirmwareMemoryMarginEnabled)}
}) {}
void INvDrvServices::Open(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
Result INvDrvServices::Open(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
auto buffer = request.inputBuf.at(0);
auto path = state.process->GetString(buffer.address, buffer.size);
response.Push<u32>(OpenDevice(path));
response.Push<u32>(constant::status::Success);
response.Push(device::NvStatus::Success);
return {};
}
void INvDrvServices::Ioctl(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
Result INvDrvServices::Ioctl(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
auto fd = request.Pop<u32>();
auto cmd = request.Pop<u32>();
@ -87,25 +89,27 @@ namespace skyline::service::nvdrv {
device::IoctlData data(request.outputBuf.at(0));
fdMap.at(fd)->HandleIoctl(cmd, data);
response.Push<u32>(data.status);
response.Push(data.status);
} else {
device::IoctlData data(request.inputBuf.at(0));
fdMap.at(fd)->HandleIoctl(cmd, data);
response.Push<u32>(data.status);
response.Push(data.status);
}
} else {
device::IoctlData data(request.inputBuf.at(0), request.outputBuf.at(0));
fdMap.at(fd)->HandleIoctl(cmd, data);
response.Push<u32>(data.status);
response.Push(data.status);
}
} catch (const std::out_of_range &) {
throw exception("IOCTL was requested on an invalid file descriptor");
}
return {};
}
void INvDrvServices::Close(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
Result INvDrvServices::Close(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
auto fd = request.Pop<u32>();
state.logger->Debug("Closing NVDRV device ({})", fd);
@ -119,14 +123,16 @@ namespace skyline::service::nvdrv {
state.logger->Warn("Trying to close non-existent FD");
}
response.Push<u32>(constant::status::Success);
response.Push(device::NvStatus::Success);
return {};
}
void INvDrvServices::Initialize(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
response.Push<u32>(constant::status::Success);
Result INvDrvServices::Initialize(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
response.Push(device::NvStatus::Success);
return {};
}
void INvDrvServices::QueryEvent(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
Result INvDrvServices::QueryEvent(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
auto fd = request.Pop<u32>();
auto eventId = request.Pop<u32>();
auto device = fdMap.at(fd);
@ -138,15 +144,20 @@ namespace skyline::service::nvdrv {
state.logger->Debug("QueryEvent: FD: {}, Event ID: {}, Handle: {}", fd, eventId, handle);
response.copyHandles.push_back(handle);
response.Push<u32>(device::NvStatus::Success);
response.Push(device::NvStatus::Success);
} else {
response.Push<u32>(device::NvStatus::BadValue);
}
response.Push(device::NvStatus::BadValue);
}
void INvDrvServices::SetAruidByPID(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
response.Push<u32>(constant::status::Success);
return {};
}
void INvDrvServices::SetGraphicsFirmwareMemoryMarginEnabled(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {}
Result INvDrvServices::SetAruidByPID(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
response.Push(device::NvStatus::Success);
return {};
}
Result INvDrvServices::SetGraphicsFirmwareMemoryMarginEnabled(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
return {};
}
}

View File

@ -67,36 +67,36 @@ namespace skyline::service::nvdrv {
/**
* @brief Open a specific device and return a FD (https://switchbrew.org/wiki/NV_services#Open)
*/
void Open(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
Result Open(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
/**
* @brief Close the specified FD (https://switchbrew.org/wiki/NV_services#Close)
*/
void Ioctl(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
Result Ioctl(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
/**
* @brief Close the specified FD (https://switchbrew.org/wiki/NV_services#Close)
*/
void Close(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
Result Close(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
/**
* @brief This initializes the driver (https://switchbrew.org/wiki/NV_services#Initialize)
*/
void Initialize(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
Result Initialize(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
/**
* @brief This returns a specific event from a device (https://switchbrew.org/wiki/NV_services#QueryEvent)
*/
void QueryEvent(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
Result QueryEvent(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
/**
* @brief This sets the AppletResourceUserId which matches the PID (https://switchbrew.org/wiki/NV_services#SetAruidByPID)
*/
void SetAruidByPID(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
Result SetAruidByPID(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
/**
* @brief This enables the graphics firmware memory margin (https://switchbrew.org/wiki/NV_services#SetGraphicsFirmwareMemoryMarginEnabled)
*/
void SetGraphicsFirmwareMemoryMarginEnabled(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
Result SetGraphicsFirmwareMemoryMarginEnabled(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
};
}

View File

@ -61,7 +61,7 @@ namespace skyline::service::nvdrv::device {
/**
* @brief This enumerates all the possible error codes returned by the Nvidia driver (https://switchbrew.org/wiki/NV_services#Errors)
*/
enum NvStatus : u32 {
enum class NvStatus : u32 {
Success = 0x0, //!< The operation has succeeded
NotImplemented = 0x1, //!< The operation is not implemented
NotSupported = 0x2, //!< The operation is not supported

View File

@ -106,18 +106,14 @@ namespace skyline::service::nvdrv::device {
u32 result; // Out
} data = state.process->GetObject<Data>(buffer.input[0].address);
try {
auto &object = handleTable.at(data.handle);
switch (data.parameter) {
case Parameter::Size:
data.result = object->size;
break;
case Parameter::Alignment:
case Parameter::HeapMask:
case Parameter::Kind: {
if (object->status != NvMapObject::Status::Allocated)
data.result = NvStatus::BadParameter;
switch (data.parameter) {
case Parameter::Alignment:
data.result = object->align;
break;
@ -127,23 +123,20 @@ namespace skyline::service::nvdrv::device {
case Parameter::Kind:
data.result = object->kind;
break;
default:
break;
}
break;
}
case Parameter::Base:
buffer.status = NvStatus::NotImplemented;
break;
case Parameter::Compr:
buffer.status = NvStatus::NotImplemented;
data.result = 0;
break;
default:
buffer.status = NvStatus::NotImplemented;
return;
}
state.process->WriteMemory(data, buffer.output[0].address);
state.logger->Debug("Param: Input: Handle: 0x{:X}, Parameter: {}, Output: Result: 0x{:X}, Status: {}", data.handle, data.parameter, data.result, buffer.status);
} catch (std::exception &e) {
buffer.status = NvStatus::BadParameter;
return;
}
}
void NvMap::GetId(IoctlData &buffer) {

View File

@ -10,7 +10,8 @@ namespace skyline::service::pctl {
{0x1, SFUNC(IParentalControlServiceFactory::CreateService)}
}) {}
void IParentalControlServiceFactory::CreateService(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
Result IParentalControlServiceFactory::CreateService(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
manager.RegisterService(SRVREG(IParentalControlService), session, response);
return {};
}
}

View File

@ -17,6 +17,6 @@ namespace skyline::service::pctl {
/**
* @brief This creates and initializes an IParentalControlService instance that can be used to read parental control configuration
*/
void CreateService(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
Result CreateService(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
};
}

View File

@ -50,26 +50,30 @@ namespace skyline::service::pl {
}
}
void IPlatformServiceManager::GetLoadState(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
Result IPlatformServiceManager::GetLoadState(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
constexpr u32 FontLoaded = 1; //!< This is returned to show that all fonts have been loaded into memory
response.Push(FontLoaded);
return {};
}
void IPlatformServiceManager::GetSize(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
Result IPlatformServiceManager::GetSize(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
auto fontId = request.Pop<u32>();
response.Push<u32>(fontTable.at(fontId).length);
return {};
}
void IPlatformServiceManager::GetSharedMemoryAddressOffset(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
Result IPlatformServiceManager::GetSharedMemoryAddressOffset(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
auto fontId = request.Pop<u32>();
response.Push<u32>(fontTable.at(fontId).offset);
return {};
}
void IPlatformServiceManager::GetSharedMemoryNativeHandle(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
Result IPlatformServiceManager::GetSharedMemoryNativeHandle(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
auto handle = state.process->InsertItem<type::KSharedMemory>(fontSharedMem);
response.copyHandles.push_back(handle);
return {};
}
}

View File

@ -25,22 +25,22 @@ namespace skyline {
/**
* @brief This returns the loading state of the requested font (https://switchbrew.org/wiki/Shared_Database_services#GetLoadState)
*/
void GetLoadState(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
Result GetLoadState(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
/**
* @brief This returns the size of the requested font (https://switchbrew.org/wiki/Shared_Database_services#GetSize)
*/
void GetSize(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
Result GetSize(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
/**
* @brief This returns the offset in shared memory of the requested font (https://switchbrew.org/wiki/Shared_Database_services#GetSharedMemoryAddressOffset)
*/
void GetSharedMemoryAddressOffset(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
Result GetSharedMemoryAddressOffset(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
/**
* @brief This returns a handle to the whole font shared memory (https://switchbrew.org/wiki/Shared_Database_services#GetSharedMemoryNativeHandle)
*/
void GetSharedMemoryNativeHandle(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
Result GetSharedMemoryNativeHandle(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
};
}
}

View File

@ -8,5 +8,7 @@ namespace skyline::service::prepo {
{0x2775, SFUNC(IPrepoService::SaveReportWithUser)},
}) {}
void IPrepoService::SaveReportWithUser(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {}
Result IPrepoService::SaveReportWithUser(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
return {};
}
}

View File

@ -17,6 +17,6 @@ namespace skyline::service::prepo {
/**
* @brief This saves a play report for the given user
*/
void SaveReportWithUser(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
Result SaveReportWithUser(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
};
}

View File

@ -154,7 +154,7 @@ namespace skyline::service {
auto service = session->domainTable.at(request.domain->objectId);
switch (static_cast<ipc::DomainCommand>(request.domain->command)) {
case ipc::DomainCommand::SendMessage:
service->HandleRequest(*session, request, response);
response.errorCode = service->HandleRequest(*session, request, response);
break;
case ipc::DomainCommand::CloseVHandle:
std::erase_if(serviceMap, [service](const auto &entry) {
@ -167,7 +167,7 @@ namespace skyline::service {
throw exception("Invalid object ID was used with domain request");
}
} else {
session->serviceObject->HandleRequest(*session, request, response);
response.errorCode = session->serviceObject->HandleRequest(*session, request, response);
}
response.WriteResponse(session->isDomain);
break;

View File

@ -31,19 +31,22 @@ namespace skyline::service::settings {
util::MakeMagic<u64>("zh-Hant"),
};
void ISettingsServer::GetAvailableLanguageCodes(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
Result ISettingsServer::GetAvailableLanguageCodes(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
state.process->WriteMemory(LanguageCodeList.data(), request.outputBuf.at(0).address, constant::OldLanguageCodeListSize * sizeof(u64));
response.Push<i32>(constant::OldLanguageCodeListSize);
return {};
}
void ISettingsServer::MakeLanguageCode(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
Result ISettingsServer::MakeLanguageCode(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
response.Push<u64>(LanguageCodeList.at(request.Pop<i32>()));
return {};
}
void ISettingsServer::GetAvailableLanguageCodes2(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
Result ISettingsServer::GetAvailableLanguageCodes2(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
state.process->WriteMemory(LanguageCodeList.data(), request.outputBuf.at(0).address, constant::NewLanguageCodeListSize * sizeof(u64));
response.Push<i32>(constant::NewLanguageCodeListSize);
return {};
}
}

View File

@ -23,17 +23,17 @@ namespace skyline::service {
/**
* @brief This reads the available language codes that an application can use (pre 4.0.0)
*/
void GetAvailableLanguageCodes(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
Result GetAvailableLanguageCodes(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
/**
* @brief This converts a language code list index to it's corresponding language code
*/
void MakeLanguageCode(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
Result MakeLanguageCode(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
/**
* @brief This reads the available language codes that an application can use (post 4.0.0)
*/
void GetAvailableLanguageCodes2(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
Result GetAvailableLanguageCodes2(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response);
};
}
}

View File

@ -8,8 +8,9 @@ namespace skyline::service::settings {
ISystemSettingsServer::ISystemSettingsServer(const DeviceState &state, ServiceManager &manager) : BaseService(state, manager, {
{0x3, SFUNC(ISystemSettingsServer::GetFirmwareVersion)}}) {}
void ISystemSettingsServer::GetFirmwareVersion(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
Result ISystemSettingsServer::GetFirmwareVersion(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
SysVerTitle title{.major=9, .minor=0, .micro=0, .revMajor=4, .revMinor=0, .platform="NX", .verHash="4de65c071fd0869695b7629f75eb97b2551dbf2f", .dispVer="9.0.0", .dispTitle="NintendoSDK Firmware for NX 9.0.0-4.0"};
state.process->WriteMemory(title, request.outputBuf.at(0).address);
return {};
}
}

Some files were not shown because too many files have changed in this diff Show More