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 { namespace skyline {
using KHandle = u32; //!< The type of a kernel handle 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 { namespace constant {
// Memory // Memory
constexpr u64 BaseAddress = 0x8000000; //!< The address space base 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 constexpr u16 DockedResolutionH = 1080; //!< The height component of the docked resolution
// Time // Time
constexpr u64 NsInSecond = 1000000000; //!< This is the amount of nanoseconds in a second 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 { 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 std::vector<u8> payload; //!< This holds all of the contents to be pushed to the payload
public: 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> copyHandles; //!< A vector of handles to copy
std::vector<KHandle> moveHandles; //!< A vector of handles to move std::vector<KHandle> moveHandles; //!< A vector of handles to move
std::vector<KHandle> domainObjects; //!< A vector of domain objects to write 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/) // Copyright © 2020 Skyline Team and Contributors (https://github.com/skyline-emu/)
#include <os.h> #include <os.h>
#include "results.h"
#include "svc.h" #include "svc.h"
namespace skyline::kernel::svc { namespace skyline::kernel::svc {
@ -9,7 +10,7 @@ namespace skyline::kernel::svc {
auto size = state.ctx->registers.w1; auto size = state.ctx->registers.w1;
if (!util::IsAligned(size, 0x200000)) { if (!util::IsAligned(size, 0x200000)) {
state.ctx->registers.w0 = constant::status::InvSize; state.ctx->registers.w0 = result::InvalidSize;
state.ctx->registers.x1 = 0; state.ctx->registers.x1 = 0;
state.logger->Warn("svcSetHeapSize: 'size' not divisible by 2MB: {}", size); state.logger->Warn("svcSetHeapSize: 'size' not divisible by 2MB: {}", size);
@ -19,7 +20,7 @@ namespace skyline::kernel::svc {
auto &heap = state.process->heap; auto &heap = state.process->heap;
heap->Resize(size); heap->Resize(size);
state.ctx->registers.w0 = constant::status::Success; state.ctx->registers.w0 = Result{};
state.ctx->registers.x1 = heap->address; state.ctx->registers.x1 = heap->address;
state.logger->Debug("svcSetHeapSize: Allocated at 0x{:X} for 0x{:X} bytes", heap->address, heap->size); 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) { void SetMemoryAttribute(DeviceState &state) {
auto address = state.ctx->registers.x0; auto address = state.ctx->registers.x0;
if (!util::PageAligned(address)) { 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); state.logger->Warn("svcSetMemoryAttribute: 'address' not page aligned: 0x{:X}", address);
return; return;
} }
auto size = state.ctx->registers.x1; auto size = state.ctx->registers.x1;
if (!util::PageAligned(size)) { 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); state.logger->Warn("svcSetMemoryAttribute: 'size' {}: 0x{:X}", size ? "not page aligned" : "is zero", size);
return; return;
} }
@ -45,7 +46,7 @@ namespace skyline::kernel::svc {
auto maskedValue = mask.value | value.value; auto maskedValue = mask.value | value.value;
if (maskedValue != mask.value || !mask.isUncached || mask.isDeviceShared || mask.isBorrowed || mask.isIpcLocked) { 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); state.logger->Warn("svcSetMemoryAttribute: 'mask' invalid: 0x{:X}, 0x{:X}", mask.value, value.value);
return; return;
} }
@ -53,13 +54,13 @@ namespace skyline::kernel::svc {
auto chunk = state.os->memory.GetChunk(address); auto chunk = state.os->memory.GetChunk(address);
auto block = state.os->memory.GetBlock(address); auto block = state.os->memory.GetBlock(address);
if (!chunk || !block) { 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); state.logger->Warn("svcSetMemoryAttribute: Cannot find memory region: 0x{:X}", address);
return; return;
} }
if (!chunk->state.attributeChangeAllowed) { 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); state.logger->Warn("svcSetMemoryAttribute: Attribute change not allowed for chunk: 0x{:X}", address);
return; return;
} }
@ -68,7 +69,7 @@ namespace skyline::kernel::svc {
MemoryManager::InsertBlock(chunk, *block); MemoryManager::InsertBlock(chunk, *block);
state.logger->Debug("svcSetMemoryAttribute: Set caching to {} at 0x{:X} for 0x{:X} bytes", !block->attributes.isUncached, address, size); 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) { void MapMemory(DeviceState &state) {
@ -77,32 +78,32 @@ namespace skyline::kernel::svc {
auto size = state.ctx->registers.x2; auto size = state.ctx->registers.x2;
if (!util::PageAligned(destination) || !util::PageAligned(source)) { 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); state.logger->Warn("svcMapMemory: Addresses not page aligned: Source: 0x{:X}, Destination: 0x{:X} (Size: 0x{:X} bytes)", source, destination, size);
return; return;
} }
if (!util::PageAligned(size)) { 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); state.logger->Warn("svcMapMemory: 'size' {}: 0x{:X}", size ? "not page aligned" : "is zero", size);
return; return;
} }
auto stack = state.os->memory.stack; auto stack = state.os->memory.stack;
if (!stack.IsInside(destination)) { 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); state.logger->Warn("svcMapMemory: Destination not within stack region: Source: 0x{:X}, Destination: 0x{:X} (Size: 0x{:X} bytes)", source, destination, size);
return; return;
} }
auto descriptor = state.os->memory.Get(source); auto descriptor = state.os->memory.Get(source);
if (!descriptor) { 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); state.logger->Warn("svcMapMemory: Source has no descriptor: Source: 0x{:X}, Destination: 0x{:X} (Size: 0x{:X} bytes)", source, destination, size);
return; return;
} }
if (!descriptor->chunk.state.mapAllowed) { 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); 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; return;
} }
@ -117,7 +118,7 @@ namespace skyline::kernel::svc {
object->item->UpdatePermission(source, size, {false, false, false}); 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.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) { void UnmapMemory(DeviceState &state) {
@ -126,20 +127,20 @@ namespace skyline::kernel::svc {
auto size = state.ctx->registers.x2; auto size = state.ctx->registers.x2;
if (!util::PageAligned(destination) || !util::PageAligned(source)) { 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); state.logger->Warn("svcUnmapMemory: Addresses not page aligned: Source: 0x{:X}, Destination: 0x{:X} (Size: 0x{:X} bytes)", source, destination, size);
return; return;
} }
if (!util::PageAligned(size)) { 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); state.logger->Warn("svcUnmapMemory: 'size' {}: 0x{:X}", size ? "not page aligned" : "is zero", size);
return; return;
} }
auto stack = state.os->memory.stack; auto stack = state.os->memory.stack;
if (!stack.IsInside(source)) { 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); state.logger->Warn("svcUnmapMemory: Source not within stack region: Source: 0x{:X}, Destination: 0x{:X} (Size: 0x{:X} bytes)", source, destination, size);
return; return;
} }
@ -147,13 +148,13 @@ namespace skyline::kernel::svc {
auto sourceDesc = state.os->memory.Get(source); auto sourceDesc = state.os->memory.Get(source);
auto destDesc = state.os->memory.Get(destination); auto destDesc = state.os->memory.Get(destination);
if (!sourceDesc || !destDesc) { 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); state.logger->Warn("svcUnmapMemory: Addresses have no descriptor: Source: 0x{:X}, Destination: 0x{:X} (Size: 0x{:X} bytes)", source, destination, size);
return; return;
} }
if (!destDesc->chunk.state.mapAllowed) { 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); 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; return;
} }
@ -173,7 +174,7 @@ namespace skyline::kernel::svc {
state.process->DeleteHandle(sourceObject->handle); 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.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) { void QueryMemory(DeviceState &state) {
@ -208,7 +209,7 @@ namespace skyline::kernel::svc {
state.process->WriteMemory(memInfo, state.ctx->registers.x0); state.process->WriteMemory(memInfo, state.ctx->registers.x0);
state.ctx->registers.w0 = constant::status::Success; state.ctx->registers.w0 = Result{};
} }
void ExitProcess(DeviceState &state) { void ExitProcess(DeviceState &state) {
@ -223,7 +224,7 @@ namespace skyline::kernel::svc {
auto priority = static_cast<i8>(state.ctx->registers.w4); auto priority = static_cast<i8>(state.ctx->registers.w4);
if (!state.thread->switchPriority.Valid(priority)) { 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); state.logger->Warn("svcCreateThread: 'priority' invalid: {}", priority);
return; 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.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.w1 = thread->handle;
state.ctx->registers.w0 = constant::status::Success; state.ctx->registers.w0 = Result{};
} }
void StartThread(DeviceState &state) { void StartThread(DeviceState &state) {
@ -241,10 +242,10 @@ namespace skyline::kernel::svc {
auto thread = state.process->GetHandle<type::KThread>(handle); auto thread = state.process->GetHandle<type::KThread>(handle);
state.logger->Debug("svcStartThread: Starting thread: 0x{:X}, PID: {}", handle, thread->tid); state.logger->Debug("svcStartThread: Starting thread: 0x{:X}, PID: {}", handle, thread->tid);
thread->Start(); thread->Start();
state.ctx->registers.w0 = constant::status::Success; state.ctx->registers.w0 = Result{};
} catch (const std::exception &) { } catch (const std::exception &) {
state.logger->Warn("svcStartThread: 'handle' invalid: 0x{:X}", handle); 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.logger->Debug("svcGetThreadPriority: Writing thread priority {}", priority);
state.ctx->registers.w1 = priority; state.ctx->registers.w1 = priority;
state.ctx->registers.w0 = constant::status::Success; state.ctx->registers.w0 = Result{};
} catch (const std::exception &) { } catch (const std::exception &) {
state.logger->Warn("svcGetThreadPriority: 'handle' invalid: 0x{:X}", handle); 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 { try {
state.logger->Debug("svcSetThreadPriority: Setting thread priority to {}", priority); state.logger->Debug("svcSetThreadPriority: Setting thread priority to {}", priority);
state.process->GetHandle<type::KThread>(handle)->UpdatePriority(static_cast<u8>(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 &) { } catch (const std::exception &) {
state.logger->Warn("svcSetThreadPriority: 'handle' invalid: 0x{:X}", handle); 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) { void ClearEvent(DeviceState &state) {
auto object = state.process->GetHandle<type::KEvent>(state.ctx->registers.w0); auto object = state.process->GetHandle<type::KEvent>(state.ctx->registers.w0);
object->signalled = false; object->signalled = false;
state.ctx->registers.w0 = constant::status::Success; state.ctx->registers.w0 = Result{};
} }
void MapSharedMemory(DeviceState &state) { void MapSharedMemory(DeviceState &state) {
@ -312,14 +313,14 @@ namespace skyline::kernel::svc {
auto address = state.ctx->registers.x1; auto address = state.ctx->registers.x1;
if (!util::PageAligned(address)) { 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); state.logger->Warn("svcMapSharedMemory: 'address' not page aligned: 0x{:X}", address);
return; return;
} }
auto size = state.ctx->registers.x2; auto size = state.ctx->registers.x2;
if (!util::PageAligned(size)) { 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); state.logger->Warn("svcMapSharedMemory: 'size' {}: 0x{:X}", size ? "not page aligned" : "is zero", size);
return; return;
} }
@ -327,7 +328,7 @@ namespace skyline::kernel::svc {
memory::Permission permission = *reinterpret_cast<memory::Permission *>(&state.ctx->registers.w3); memory::Permission permission = *reinterpret_cast<memory::Permission *>(&state.ctx->registers.w3);
if ((permission.w && !permission.r) || (permission.x && !permission.r)) { 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.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; return;
} }
@ -335,24 +336,24 @@ namespace skyline::kernel::svc {
object->Map(address, size, permission); object->Map(address, size, permission);
state.ctx->registers.w0 = constant::status::Success; state.ctx->registers.w0 = Result{};
} catch (const std::exception &) { } catch (const std::exception &) {
state.logger->Warn("svcMapSharedMemory: 'handle' invalid: 0x{:X}", state.ctx->registers.w0); 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) { void CreateTransferMemory(DeviceState &state) {
auto address = state.ctx->registers.x1; auto address = state.ctx->registers.x1;
if (!util::PageAligned(address)) { 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); state.logger->Warn("svcCreateTransferMemory: 'address' not page aligned: 0x{:X}", address);
return; return;
} }
auto size = state.ctx->registers.x2; auto size = state.ctx->registers.x2;
if (!util::PageAligned(size)) { 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); state.logger->Warn("svcCreateTransferMemory: 'size' {}: 0x{:X}", size ? "not page aligned" : "is zero", size);
return; return;
} }
@ -360,7 +361,7 @@ namespace skyline::kernel::svc {
memory::Permission permission = *reinterpret_cast<memory::Permission *>(&state.ctx->registers.w3); memory::Permission permission = *reinterpret_cast<memory::Permission *>(&state.ctx->registers.w3);
if ((permission.w && !permission.r) || (permission.x && !permission.r)) { 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.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; return;
} }
@ -368,7 +369,7 @@ namespace skyline::kernel::svc {
auto shmem = state.process->NewHandle<type::KTransferMemory>(state.process->pid, address, size, permission); 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; state.ctx->registers.w1 = shmem.handle;
} }
@ -377,10 +378,10 @@ namespace skyline::kernel::svc {
try { try {
state.process->handles.erase(handle); state.process->handles.erase(handle);
state.logger->Debug("svcCloseHandle: Closing handle: 0x{:X}", 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 &) { } catch (const std::exception &) {
state.logger->Warn("svcCloseHandle: 'handle' invalid: 0x{:X}", handle); 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: { default: {
state.logger->Warn("svcResetSignal: 'handle' type invalid: 0x{:X} ({})", handle, object->objectType); 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; return;
} }
} }
state.logger->Debug("svcResetSignal: Resetting signal: 0x{:X}", handle); 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 &) { } catch (const std::out_of_range &) {
state.logger->Warn("svcResetSignal: 'handle' invalid: 0x{:X}", handle); state.logger->Warn("svcResetSignal: 'handle' invalid: 0x{:X}", handle);
state.ctx->registers.w0 = constant::status::InvHandle; state.ctx->registers.w0 = result::InvalidHandle;
return; return;
} }
} }
@ -418,7 +419,7 @@ namespace skyline::kernel::svc {
auto numHandles = state.ctx->registers.w2; auto numHandles = state.ctx->registers.w2;
if (numHandles > maxSyncHandles) { if (numHandles > maxSyncHandles) {
state.ctx->registers.w0 = constant::status::MaxHandles; state.ctx->registers.w0 = result::OutOfHandles;
return; return;
} }
@ -440,7 +441,7 @@ namespace skyline::kernel::svc {
break; break;
default: { default: {
state.ctx->registers.w0 = constant::status::InvHandle; state.ctx->registers.w0 = result::InvalidHandle;
return; return;
} }
} }
@ -455,7 +456,7 @@ namespace skyline::kernel::svc {
while (true) { while (true) {
if (state.thread->cancelSync) { if (state.thread->cancelSync) {
state.thread->cancelSync = false; state.thread->cancelSync = false;
state.ctx->registers.w0 = constant::status::Interrupted; state.ctx->registers.w0 = result::Cancelled;
break; break;
} }
@ -463,7 +464,7 @@ namespace skyline::kernel::svc {
for (const auto &object : objectTable) { for (const auto &object : objectTable) {
if (object->signalled) { if (object->signalled) {
state.logger->Debug("svcWaitSynchronization: Signalled handle: 0x{:X}", waitHandles.at(index)); 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; state.ctx->registers.w1 = index;
return; return;
} }
@ -472,7 +473,7 @@ namespace skyline::kernel::svc {
if ((util::GetTimeNs() - start) >= timeout) { if ((util::GetTimeNs() - start) >= timeout) {
state.logger->Debug("svcWaitSynchronization: Wait has timed out"); state.logger->Debug("svcWaitSynchronization: Wait has timed out");
state.ctx->registers.w0 = constant::status::Timeout; state.ctx->registers.w0 = result::TimedOut;
return; return;
} }
} }
@ -483,7 +484,7 @@ namespace skyline::kernel::svc {
state.process->GetHandle<type::KThread>(state.ctx->registers.w0)->cancelSync = true; state.process->GetHandle<type::KThread>(state.ctx->registers.w0)->cancelSync = true;
} catch (const std::exception &) { } catch (const std::exception &) {
state.logger->Warn("svcCancelSynchronization: 'handle' invalid: 0x{:X}", state.ctx->registers.w0); 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; auto address = state.ctx->registers.x1;
if (!util::WordAligned(address)) { if (!util::WordAligned(address)) {
state.logger->Warn("svcArbitrateLock: 'address' not word aligned: 0x{:X}", 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; return;
} }
@ -507,14 +508,14 @@ namespace skyline::kernel::svc {
else 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.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) { void ArbitrateUnlock(DeviceState &state) {
auto address = state.ctx->registers.x0; auto address = state.ctx->registers.x0;
if (!util::WordAligned(address)) { if (!util::WordAligned(address)) {
state.logger->Warn("svcArbitrateUnlock: 'address' not word aligned: 0x{:X}", 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; return;
} }
@ -522,10 +523,10 @@ namespace skyline::kernel::svc {
if (state.process->MutexUnlock(address)) { if (state.process->MutexUnlock(address)) {
state.logger->Debug("svcArbitrateUnlock: Unlocked mutex at 0x{:X}", address); state.logger->Debug("svcArbitrateUnlock: Unlocked mutex at 0x{:X}", address);
state.ctx->registers.w0 = constant::status::Success; state.ctx->registers.w0 = Result{};
} else { } else {
state.logger->Debug("svcArbitrateUnlock: A non-owner thread tried to release a mutex at 0x{:X}", address); 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; auto mtxAddress = state.ctx->registers.x0;
if (!util::WordAligned(mtxAddress)) { if (!util::WordAligned(mtxAddress)) {
state.logger->Warn("svcWaitProcessWideKeyAtomic: mutex address not word aligned: 0x{:X}", 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; return;
} }
@ -544,7 +545,7 @@ namespace skyline::kernel::svc {
if (!state.process->MutexUnlock(mtxAddress)) { if (!state.process->MutexUnlock(mtxAddress)) {
state.logger->Debug("WaitProcessWideKeyAtomic: A non-owner thread tried to release a mutex at 0x{:X}", 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; return;
} }
@ -553,10 +554,10 @@ namespace skyline::kernel::svc {
if (state.process->ConditionalVariableWait(condAddress, mtxAddress, timeout)) { if (state.process->ConditionalVariableWait(condAddress, mtxAddress, timeout)) {
state.logger->Debug("svcWaitProcessWideKeyAtomic: Waited for conditional variable and relocked mutex"); state.logger->Debug("svcWaitProcessWideKeyAtomic: Waited for conditional variable and relocked mutex");
state.ctx->registers.w0 = constant::status::Success; state.ctx->registers.w0 = Result{};
} else { } else {
state.logger->Debug("svcWaitProcessWideKeyAtomic: Wait has timed out"); 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.logger->Debug("svcSignalProcessWideKey: Signalling Conditional-Variable at 0x{:X} for {}", address, count);
state.process->ConditionalVariableSignal(address, count); state.process->ConditionalVariableSignal(address, count);
state.ctx->registers.w0 = constant::status::Success; state.ctx->registers.w0 = Result{};
} }
void GetSystemTick(DeviceState &state) { 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; handle = state.process->NewHandle<type::KSession>(std::static_pointer_cast<service::BaseService>(state.os->serviceManager.smUserInterface)).handle;
} else { } else {
state.logger->Warn("svcConnectToNamedPort: Connecting to invalid port: '{}'", port); state.logger->Warn("svcConnectToNamedPort: Connecting to invalid port: '{}'", port);
state.ctx->registers.w0 = constant::status::NotFound; state.ctx->registers.w0 = result::NotFound;
return; return;
} }
state.logger->Debug("svcConnectToNamedPort: Connecting to port '{}' at 0x{:X}", port, handle); state.logger->Debug("svcConnectToNamedPort: Connecting to port '{}' at 0x{:X}", port, handle);
state.ctx->registers.w1 = handle; state.ctx->registers.w1 = handle;
state.ctx->registers.w0 = constant::status::Success; state.ctx->registers.w0 = Result{};
} }
void SendSyncRequest(DeviceState &state) { void SendSyncRequest(DeviceState &state) {
state.os->serviceManager.SyncRequestHandler(static_cast<KHandle>(state.ctx->registers.x0)); 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) { void GetThreadId(DeviceState &state) {
@ -619,7 +620,7 @@ namespace skyline::kernel::svc {
state.logger->Debug("svcGetThreadId: Handle: 0x{:X}, PID: {}", handle, pid); state.logger->Debug("svcGetThreadId: Handle: 0x{:X}, PID: {}", handle, pid);
state.ctx->registers.x1 = static_cast<u64>(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) { void OutputDebugString(DeviceState &state) {
@ -629,7 +630,7 @@ namespace skyline::kernel::svc {
debug.pop_back(); debug.pop_back();
state.logger->Info("Debug Output: {}", debug); state.logger->Info("Debug Output: {}", debug);
state.ctx->registers.w0 = constant::status::Success; state.ctx->registers.w0 = Result{};
} }
void GetInfo(DeviceState &state) { void GetInfo(DeviceState &state) {
@ -711,13 +712,13 @@ namespace skyline::kernel::svc {
default: default:
state.logger->Warn("svcGetInfo: Unimplemented case ID0: {}, ID1: {}", id0, id1); state.logger->Warn("svcGetInfo: Unimplemented case ID0: {}, ID1: {}", id0, id1);
state.ctx->registers.w0 = constant::status::Unimpl; state.ctx->registers.w0 = result::InvalidEnumValue;
return; return;
} }
state.logger->Debug("svcGetInfo: ID0: {}, ID1: {}, Out: 0x{:X}", id0, id1, out); state.logger->Debug("svcGetInfo: ID0: {}, ID1: {}, Out: 0x{:X}", id0, id1, out);
state.ctx->registers.x1 = 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)} {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>(); auto id = request.Pop<UserId>();
// ID can't be zero
if (id == UserId{})
return result::NullArgument;
response.Push<u32>(id == constant::DefaultUserId); 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) {
// We only support one active user currently so hardcode this and ListOpenUsers try {
WriteUserList(request.outputBuf.at(0), {constant::DefaultUserId}); // We only support one active user currently so hardcode this and ListOpenUsers
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) { Result IAccountServiceForApplication::ListOpenUsers(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
WriteUserList(request.outputBuf.at(0), {constant::DefaultUserId}); 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)); std::span outputUserIds(state.process->GetPointer<UserId>(buffer.address), buffer.size / sizeof(UserId));
for (auto &userId : outputUserIds) { for (auto &userId : outputUserIds) {
@ -43,25 +56,34 @@ namespace skyline::service::account {
userIds.pop_back(); 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); 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>(); auto id = request.Pop<UserId>();
if (id != constant::DefaultUserId) { if (id != constant::DefaultUserId)
response.errorCode = constant::status::InvUser; return result::UserNotFound;
return;
}
manager.RegisterService(std::make_shared<IProfile>(state, manager, id), session, response); 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); manager.RegisterService(SRVREG(IManagerForApplication), session, response);
return {};
} }
} }

View File

@ -8,6 +8,13 @@
namespace skyline { namespace skyline {
namespace service::account { 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 * @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 * @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: public:
IAccountServiceForApplication(const DeviceState &state, ServiceManager &manager); IAccountServiceForApplication(const DeviceState &state, ServiceManager &manager);
@ -39,37 +46,37 @@ namespace skyline {
/** /**
* @brief This checks if the given user ID exists * @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 * @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 * @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 * @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) * @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 * @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 * @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)} {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 { struct AccountUserData {
u32 _unk0_; u32 _unk0_;
u32 iconID; //!< Icon ID (0 = Mii, the rest are character icon IDs) 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); auto userData = state.process->GetPointer<AccountUserData>(request.outputBuf.at(0).address);
userData->iconBackgroundColorID = 0x1; // Color indexing starts at 0x1 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 { struct {
UserId uid; //!< The UID of the corresponding account UserId uid; //!< The UID of the corresponding account
u64 lastEditTimestamp; //!< A POSIX UTC timestamp denoting the last account edit 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); std::memcpy(accountProfileBase.nickname.data(), username.c_str(), usernameSize);
response.Push(accountProfileBase); 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 * @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 * @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)} {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); 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); 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); 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); 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) * @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) * @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) * @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) * @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)} {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); 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) * @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)}, {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(); stateChangeEvent->Signal();
KHandle handle = state.process->InsertItem(stateChangeEvent); KHandle handle = state.process->InsertItem(stateChangeEvent);
state.logger->Debug("Applet State Change Event Handle: 0x{:X}", handle); state.logger->Debug("Applet State Change Event Handle: 0x{:X}", handle);
response.copyHandles.push_back(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 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 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); storageService->Push(constant::DefaultUserId);
manager.RegisterService(storageService, session, response); 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 * @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) * @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) * @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) * @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) * @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)}, {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 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 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); storageService->Push(constant::DefaultUserId);
manager.RegisterService(storageService, session, response); 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); 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")); 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); 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);
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); auto handle = state.process->InsertItem(gpuErrorEvent);
state.logger->Debug("GPU Error Event Handle: 0x{:X}", handle); state.logger->Debug("GPU Error Event Handle: 0x{:X}", handle);
response.copyHandles.push_back(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) * @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) * @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) * @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) * @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) * @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) * @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) * @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) * @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)} {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>(); mainAppletVolume = request.Pop<float>();
libraryAppletVolume = 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); 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); 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) * @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) * @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) * @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); 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); auto handle = state.process->InsertItem(messageEvent);
state.logger->Debug("Applet Event Handle: 0x{:X}", handle); state.logger->Debug("Applet Event Handle: 0x{:X}", handle);
response.copyHandles.push_back(handle); response.copyHandles.push_back(handle);
return {};
} }
void ICommonStateGetter::ReceiveMessage(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) { Result ICommonStateGetter::ReceiveMessage(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
if (messageQueue.empty()) { if (messageQueue.empty())
response.errorCode = constant::status::NoMessages; return result::NoMessages;
return;
}
response.Push(messageQueue.front()); response.Push(messageQueue.front());
messageQueue.pop(); 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); 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); 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)); 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) { if (operationMode == OperationMode::Handheld) {
response.Push<u32>(constant::HandheldResolutionW); response.Push<u32>(constant::HandheldResolutionW);
response.Push<u32>(constant::HandheldResolutionH); response.Push<u32>(constant::HandheldResolutionH);
@ -59,5 +62,6 @@ namespace skyline::service::am {
response.Push<u32>(constant::DockedResolutionW); response.Push<u32>(constant::DockedResolutionW);
response.Push<u32>(constant::DockedResolutionH); response.Push<u32>(constant::DockedResolutionH);
} }
return {};
} }
} }

View File

@ -9,6 +9,10 @@
#include <services/serviceman.h> #include <services/serviceman.h>
namespace skyline::service::am { namespace skyline::service::am {
namespace result {
constexpr Result NoMessages(128, 3);
}
/** /**
* @brief https://switchbrew.org/wiki/Applet_Manager_services#ICommonStateGetter * @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) * @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) * @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) * @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) * @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) * @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) * @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)} {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); 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>(); auto size = request.Pop<i64>();
if (size < 0) if (size < 0)
throw exception("Cannot create an IStorage with a negative size"); throw exception("Cannot create an IStorage with a negative size");
manager.RegisterService(std::make_shared<IStorage>(state, manager, size), session, response); 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) * @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) * @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)} {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(); libraryAppletLaunchableEvent->Signal();
KHandle handle = state.process->InsertItem(libraryAppletLaunchableEvent); KHandle handle = state.process->InsertItem(libraryAppletLaunchableEvent);
state.logger->Debug("Library Applet Launchable Event Handle: 0x{:X}", handle); state.logger->Debug("Library Applet Launchable Event Handle: 0x{:X}", handle);
response.copyHandles.push_back(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"); state.logger->Debug("Creating Managed Layer on Default Display");
auto hosBinder = state.os->serviceManager.GetService<hosbinder::IHOSBinderDriver>("dispdrv"); auto hosBinder = state.os->serviceManager.GetService<hosbinder::IHOSBinderDriver>("dispdrv");
@ -52,12 +67,14 @@ namespace skyline::service::am {
hosBinder->layerStatus = hosbinder::LayerStatus::Managed; hosBinder->layerStatus = hosbinder::LayerStatus::Managed;
response.Push<u64>(0); 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); auto handle = state.process->InsertItem(accumulatedSuspendedTickChangedEvent);
state.logger->Debug("Accumulated Suspended Tick Event Handle: 0x{:X}", handle); state.logger->Debug("Accumulated Suspended Tick Event Handle: 0x{:X}", handle);
response.copyHandles.push_back(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) * @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) * @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) * @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) * @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) * @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) * @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) * @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) * @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) * @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) * @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)} {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)); 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) * @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) * @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)} {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); 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) * @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" #include "base_proxy.h"
namespace skyline::service::am { 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); 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); 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); 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); 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); 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); 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); 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); manager.RegisterService(SRVREG(IAppletCommonFunctions), session, response);
return {};
} }
} }

View File

@ -12,46 +12,46 @@ namespace skyline::service::am {
*/ */
class BaseProxy : public BaseService { class BaseProxy : public BaseService {
public: 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) * @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) * @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) * @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) * @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) * @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) * @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) * @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) * @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)} {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); 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 * @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 * @brief This function writes an object to the storage

View File

@ -12,30 +12,34 @@ namespace skyline::service::am {
{0xB, SFUNC(IStorageAccessor::Read)} {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()); 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 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()) if (offset > parent->content.size())
throw exception("Trying to write past the end of an IStorage"); return result::OutOfBounds;
if (offset < 0) if (size > 0)
throw exception("Trying to write before the start of an IStorage"); state.process->ReadMemory(parent->content.data() + offset, request.inputBuf.at(0).address, size);
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) { Result IStorageAccessor::Read(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
auto offset = request.Pop<u64>(); auto offset = request.Pop<i64>();
auto size = request.outputBuf.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()) if (offset > parent->content.size())
throw exception("Trying to read past the end of an IStorage"); return result::OutOfBounds;
state.process->WriteMemory(parent->content.data() + offset, request.outputBuf.at(0).address, size); 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> #include <services/serviceman.h>
namespace skyline::service::am { namespace skyline::service::am {
namespace result {
constexpr Result OutOfBounds(128, 503);
}
class IStorage; class IStorage;
/** /**
@ -22,16 +25,16 @@ namespace skyline::service::am {
/** /**
* @brief This returns the size of the storage in bytes * @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 * @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 * @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)} {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); manager.RegisterService(SRVREG(ISession), session, response);
return {};
} }
} }

View File

@ -17,6 +17,6 @@ namespace skyline::service::apm {
/** /**
* @brief This returns an handle to ISession * @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)} {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 mode = request.Pop<u32>();
auto config = request.Pop<u32>(); auto config = request.Pop<u32>();
performanceConfig.at(mode) = config; performanceConfig.at(mode) = config;
state.logger->Info("SetPerformanceConfiguration called with 0x{:X} ({})", config, mode ? "Docked" : "Handheld"); 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) { Result ISession::GetPerformanceConfiguration(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
u32 performanceMode = request.Pop<u32>(); auto performanceMode = request.Pop<u32>();
response.Push<u32>(performanceConfig.at(performanceMode)); 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) * @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) * @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)} {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{}; u64 offset{};
for (std::string deviceName : {"AudioTvOutput", "AudioStereoJackOutput", "AudioBuiltInSpeakerOutput"}) { for (std::string deviceName : {"AudioTvOutput", "AudioStereoJackOutput", "AudioBuiltInSpeakerOutput"}) {
if (offset + deviceName.size() + 1 > request.outputBuf.at(0).size) 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); state.process->WriteMemory(deviceName.c_str(), request.outputBuf.at(0).address + offset, deviceName.size() + 1);
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"); std::string deviceName("AudioStereoJackOutput");
if (deviceName.size() > request.outputBuf.at(0).size) if (deviceName.size() > request.outputBuf.at(0).size)
throw exception("Too small a buffer supplied to GetActiveAudioDeviceName"); throw exception("Too small a buffer supplied to GetActiveAudioDeviceName");
state.process->WriteMemory(deviceName.c_str(), request.outputBuf.at(0).address, deviceName.size() + 1); 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)}; auto handle{state.process->InsertItem(systemEvent)};
state.logger->Debug("Audio Device System Event Handle: 0x{:X}", handle); state.logger->Debug("Audio Device System Event Handle: 0x{:X}", handle);
response.copyHandles.push_back(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); 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) * @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) * @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 * @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 * @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 * @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); 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)); 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"); state.logger->Debug("IAudioOut: Start playback");
track->Start(); 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"); state.logger->Debug("IAudioOut: Stop playback");
track->Stop(); 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 { struct Data {
u64 nextBufferPtr; u64 nextBufferPtr;
u64 sampleBufferPtr; u64 sampleBufferPtr;
@ -55,15 +58,18 @@ namespace skyline::service::audio {
} else { } else {
track->AppendBuffer(tag, std::span(state.process->GetPointer<i16>(data.sampleBufferPtr), data.sampleSize / sizeof(i16))); 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)}; auto handle{state.process->InsertItem(releaseEvent)};
state.logger->Debug("IAudioOut: Buffer Release Event Handle: 0x{:X}", handle); state.logger->Debug("IAudioOut: Buffer Release Event Handle: 0x{:X}", handle);
response.copyHandles.push_back(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)}; auto maxCount{static_cast<u32>(request.outputBuf.at(0).size >> 3)};
std::vector<u64> releasedBuffers{track->GetReleasedBuffers(maxCount)}; std::vector<u64> releasedBuffers{track->GetReleasedBuffers(maxCount)};
auto count{static_cast<u32>(releasedBuffers.size())}; 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); state.process->WriteMemory(releasedBuffers.data(), request.outputBuf.at(0).address, request.outputBuf.at(0).size);
response.Push<u32>(count); 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>()}; auto tag{request.Pop<u64>()};
response.Push(static_cast<u32>(track->ContainsBuffer(tag))); 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) * @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) * @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) * @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) * @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) * @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) * @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) * @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)} {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()); 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 sampleRate{request.Pop<u32>()};
auto channelCount{static_cast<u16>(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<u16>(0);
response.Push(static_cast<u32>(skyline::audio::AudioFormat::Int16)); response.Push(static_cast<u32>(skyline::audio::AudioFormat::Int16));
response.Push(static_cast<u32>(skyline::audio::AudioOutState::Stopped)); 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) * @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) * @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); 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); 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); 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); 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)); 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 inputAddress{request.inputBuf.at(0).address};
auto inputHeader{state.process->GetObject<UpdateDataHeader>(inputAddress)}; auto inputHeader{state.process->GetObject<UpdateDataHeader>(inputAddress)};
@ -125,6 +129,8 @@ namespace skyline::service::audio::IAudioRenderer {
state.process->WriteMemory(effect.output, outputAddress); state.process->WriteMemory(effect.output, outputAddress);
outputAddress += sizeof(EffectOut); outputAddress += sizeof(EffectOut);
} }
return {};
} }
void IAudioRenderer::UpdateAudio() { 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; 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; 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)}; auto handle{state.process->InsertItem(systemEvent)};
state.logger->Debug("Audren System Event Handle: 0x{:X}", handle); state.logger->Debug("Audren System Event Handle: 0x{:X}", handle);
response.copyHandles.push_back(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) * @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) * @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) * @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)? * @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 * @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 * @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 * @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 * @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)} {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>(); 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); 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); 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::AudioRendererParameters params = request.Pop<IAudioRenderer::AudioRendererParameters>();
IAudioRenderer::RevisionInfo revisionInfo{}; IAudioRenderer::RevisionInfo revisionInfo{};
@ -86,9 +88,11 @@ namespace skyline::service::audio {
state.logger->Debug("IAudioRendererManager: Work buffer size: 0x{:X}", size); state.logger->Debug("IAudioRendererManager: Work buffer size: 0x{:X}", size);
response.Push<i64>(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); 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 * @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 * @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) * @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: protected:
const DeviceState &state; //!< The state of the device const DeviceState &state; //!< The state of the device
ServiceManager &manager; //!< A reference to the service manager 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: public:
/** /**
* @param state The state of the device * @param state The state of the device
* @param vTable The functions of the service * @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 * @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 request The corresponding IpcRequest object
* @param response The corresponding IpcResponse object * @param response The corresponding IpcResponse object
*/ */
void HandleRequest(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) { Result HandleRequest(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
std::function<void(type::KSession &, ipc::IpcRequest &, ipc::IpcResponse &)> function; std::function<Result(type::KSession &, ipc::IpcRequest &, ipc::IpcResponse &)> function;
try { try {
function = vTable.at(request.payload->value); function = vTable.at(request.payload->value);
} catch (std::out_of_range &) { } 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)); state.logger->Warn("Cannot find function in service '{0}': 0x{1:X} ({1})", GetName(), static_cast<u32>(request.payload->value));
return; return {};
} }
try { try {
function(session, request, response); return function(session, request, response);
} catch (std::exception &e) { } catch (std::exception &e) {
throw exception("{} (Service: {})", e.what(), GetName()); throw exception("{} (Service: {})", e.what(), GetName());
} }

View File

@ -10,7 +10,7 @@ namespace skyline::service::fatalsrv {
{0x2, SFUNC(IService::ThrowFatal)} {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>()); 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 * @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)}, {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); KHandle handle = state.process->InsertItem(notificationEvent);
state.logger->Debug("Friend Notification Event Handle: 0x{:X}", handle); state.logger->Debug("Friend Notification Event Handle: 0x{:X}", handle);
response.copyHandles.push_back(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 * @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)}, {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); 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); 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 * @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 * @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/) // Copyright © 2020 Skyline Team and Contributors (https://github.com/skyline-emu/)
#include <kernel/types/KProcess.h> #include <kernel/types/KProcess.h>
#include "results.h"
#include "IFile.h" #include "IFile.h"
namespace skyline::service::fssrv { namespace skyline::service::fssrv {
@ -13,7 +14,7 @@ namespace skyline::service::fssrv {
{0x4, SFUNC(IFile::GetSize)} {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>(); auto readOption = request.Pop<u32>();
request.Skip<u32>(); request.Skip<u32>();
auto offset = request.Pop<i64>(); auto offset = request.Pop<i64>();
@ -21,20 +22,19 @@ namespace skyline::service::fssrv {
if (offset < 0) { if (offset < 0) {
state.logger->Warn("Trying to read a file with a negative offset"); state.logger->Warn("Trying to read a file with a negative offset");
response.errorCode = constant::status::InvAddress; return result::InvalidOffset;
return;
} }
if (size < 0) { if (size < 0) {
state.logger->Warn("Trying to read a file with a negative size"); state.logger->Warn("Trying to read a file with a negative size");
response.errorCode = constant::status::InvSize; return result::InvalidSize;
return;
} }
response.Push<u32>(static_cast<u32>(backing->Read(state.process->GetPointer<u8>(request.outputBuf.at(0).address), offset, size))); 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>(); auto writeOption = request.Pop<u32>();
request.Skip<u32>(); request.Skip<u32>();
auto offset = request.Pop<i64>(); auto offset = request.Pop<i64>();
@ -42,35 +42,38 @@ namespace skyline::service::fssrv {
if (offset < 0) { if (offset < 0) {
state.logger->Warn("Trying to write to a file with a negative offset"); state.logger->Warn("Trying to write to a file with a negative offset");
response.errorCode = constant::status::InvAddress; return result::InvalidOffset;
return;
} }
if (size < 0) { if (size < 0) {
state.logger->Warn("Trying to write to a file with a negative size"); state.logger->Warn("Trying to write to a file with a negative size");
response.errorCode = constant::status::InvSize; return result::InvalidSize;
return;
} }
if (request.inputBuf.at(0).size < size) { if (request.inputBuf.at(0).size < size) {
state.logger->Warn("The input buffer is not large enough to fit the requested size"); state.logger->Warn("The input buffer is not large enough to fit the requested size");
response.errorCode = constant::status::InvSize; return result::InvalidSize;
return;
} }
if (backing->Write(state.process->GetPointer<u8>(request.inputBuf.at(0).address), offset, request.inputBuf.at(0).size) != size) { 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"); state.logger->Warn("Failed to write all data to the backing");
response.errorCode = constant::status::GenericError; return result::UnexpectedFailure;
} }
return {};
} }
void IFile::Flush(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {} Result 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::SetSize(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
backing->Resize(request.Pop<u64>()); 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); 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 * @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 * @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 * @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 * @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 * @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 <kernel/types/KProcess.h>
#include <vfs/filesystem.h> #include <vfs/filesystem.h>
#include "results.h"
#include "IFile.h" #include "IFile.h"
#include "IFileSystem.h" #include "IFileSystem.h"
@ -14,42 +15,45 @@ namespace skyline::service::fssrv {
{0xA, SFUNC(IFileSystem::Commit)} {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)); std::string path = std::string(state.process->GetPointer<char>(request.inputBuf.at(0).address));
auto mode = request.Pop<u64>(); auto mode = request.Pop<u64>();
auto size = request.Pop<u32>(); 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)); std::string path = std::string(state.process->GetPointer<char>(request.inputBuf.at(0).address));
auto type = backing->GetEntryType(path); auto type = backing->GetEntryType(path);
if (type) { if (type) {
response.Push(*type); response.Push(*type);
return {};
} else { } else {
response.Push<u32>(0); response.Push<u32>(0);
response.errorCode = constant::status::PathDoesNotExist; return result::PathDoesNotExist;
} }
} }
void IFileSystem::OpenFile(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) { Result 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)); std::string path(state.process->GetPointer<char>(request.inputBuf.at(0).address));
auto mode = request.Pop<vfs::Backing::Mode>(); auto mode = request.Pop<vfs::Backing::Mode>();
if (!backing->FileExists(path)) { if (!backing->FileExists(path))
response.errorCode = constant::status::PathDoesNotExist; return result::PathDoesNotExist;
return;
}
auto file = backing->OpenFile(path, mode); auto file = backing->OpenFile(path, mode);
if (file == nullptr) if (file == nullptr)
response.errorCode = constant::status::GenericError; return result::UnexpectedFailure;
else else
manager.RegisterService(std::make_shared<IFile>(file, state, manager), session, response); 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 * @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) * @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) * @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) * @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 <os.h>
#include <vfs/os_filesystem.h> #include <vfs/os_filesystem.h>
#include <loader/loader.h> #include <loader/loader.h>
#include "IFileSystemProxy.h" #include "results.h"
#include "IStorage.h" #include "IStorage.h"
#include "IFileSystemProxy.h"
namespace skyline::service::fssrv { namespace skyline::service::fssrv {
IFileSystemProxy::IFileSystemProxy(const DeviceState &state, ServiceManager &manager) : BaseService(state, manager, { IFileSystemProxy::IFileSystemProxy(const DeviceState &state, ServiceManager &manager) : BaseService(state, manager, {
@ -16,15 +17,17 @@ namespace skyline::service::fssrv {
{0x3ED, SFUNC(IFileSystemProxy::GetGlobalAccessLogMode)}, {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>(); 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); 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 spaceId = request.Pop<SaveDataSpaceId>();
auto attribute = request.Pop<SaveDataAttribute>(); 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); 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) { Result IFileSystemProxy::OpenDataStorageByCurrentProcess(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
if (state.loader->romFs) if (!state.loader->romFs)
manager.RegisterService(std::make_shared<IStorage>(state.loader->romFs, state, manager), session, response); return result::NoRomFsAvailable;
else
throw exception("Tried to call OpenDataStorageByCurrentProcess without a valid RomFS"); manager.RegisterService(std::make_shared<IStorage>(state.loader->romFs, state, manager), session, response);
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); 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) * @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 * @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 * @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 * @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) * @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/) // Copyright © 2020 Skyline Team and Contributors (https://github.com/skyline-emu/)
#include <kernel/types/KProcess.h> #include <kernel/types/KProcess.h>
#include "results.h"
#include "IStorage.h" #include "IStorage.h"
namespace skyline::service::fssrv { namespace skyline::service::fssrv {
@ -10,26 +11,26 @@ namespace skyline::service::fssrv {
{0x4, SFUNC(IStorage::GetSize)} {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 offset = request.Pop<i64>();
auto size = request.Pop<i64>(); auto size = request.Pop<i64>();
if (offset < 0) { if (offset < 0) {
state.logger->Warn("Trying to read a file with a negative offset"); state.logger->Warn("Trying to read a file with a negative offset");
response.errorCode = constant::status::InvAddress; return result::InvalidOffset;
return;
} }
if (size < 0) { if (size < 0) {
state.logger->Warn("Trying to read a file with a negative size"); state.logger->Warn("Trying to read a file with a negative size");
response.errorCode = constant::status::InvSize; return result::InvalidSize;
return;
} }
backing->Read(state.process->GetPointer<u8>(request.outputBuf.at(0).address), offset, size); 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); 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) * @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) * @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)} {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>(); auto handle = request.Pop<NpadDeviceHandle>();
if (!handle.isRight) if (!handle.isRight)
state.input->npad.at(handle.id).vibrationRight = NpadVibrationValue{}; 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) * @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)} {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); auto handle = state.process->InsertItem<type::KSharedMemory>(state.input->kHid);
state.logger->Debug("HID Shared Memory Handle: 0x{:X}", handle); state.logger->Debug("HID Shared Memory Handle: 0x{:X}", handle);
response.copyHandles.push_back(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) * @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)} {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); 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>(); auto styleSet = request.Pop<NpadStyleSet>();
std::lock_guard lock(state.input->npad.mutex); std::lock_guard lock(state.input->npad.mutex);
state.input->npad.styles = styleSet; 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> 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)); (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); 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); const auto &buffer = request.inputBuf.at(0);
u64 address = buffer.address; u64 address = buffer.address;
size_t size = buffer.size / sizeof(NpadId); size_t size = buffer.size / sizeof(NpadId);
@ -58,62 +61,73 @@ namespace skyline::service::hid {
std::lock_guard lock(state.input->npad.mutex); std::lock_guard lock(state.input->npad.mutex);
state.input->npad.supportedIds = supportedIds; state.input->npad.supportedIds = supportedIds;
state.input->npad.Update(); 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(); 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(); 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>(); auto id = request.Pop<NpadId>();
request.copyHandles.push_back(state.process->InsertItem(state.input->npad.at(id).updateEvent)); 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(); 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); std::lock_guard lock(state.input->npad.mutex);
request.Skip<u64>(); request.Skip<u64>();
state.input->npad.orientation = request.Pop<NpadJoyOrientation>(); state.input->npad.orientation = request.Pop<NpadJoyOrientation>();
state.input->npad.Update(); 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); 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>(); auto id = request.Pop<NpadId>();
std::lock_guard lock(state.input->npad.mutex); std::lock_guard lock(state.input->npad.mutex);
state.input->npad.at(id).SetAssignment(NpadJoyAssignment::Single); state.input->npad.at(id).SetAssignment(NpadJoyAssignment::Single);
state.input->npad.Update(); 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>(); auto id = request.Pop<NpadId>();
std::lock_guard lock(state.input->npad.mutex); std::lock_guard lock(state.input->npad.mutex);
state.input->npad.at(id).SetAssignment(NpadJoyAssignment::Single); state.input->npad.at(id).SetAssignment(NpadJoyAssignment::Single);
state.input->npad.Update(); 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>(); auto id = request.Pop<NpadId>();
std::lock_guard lock(state.input->npad.mutex); std::lock_guard lock(state.input->npad.mutex);
state.input->npad.at(id).SetAssignment(NpadJoyAssignment::Dual); state.input->npad.at(id).SetAssignment(NpadJoyAssignment::Dual);
state.input->npad.Update(); 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); 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 request.Skip<u64>(); // appletResourceUserId
auto &handleBuf = request.inputBuf.at(0); 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) * @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) * @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) * @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) * @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) * @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) * @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) * @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) * @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) * @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) * @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) * @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) * @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) * @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) * @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) * @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); 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 layerId = request.Pop<u32>();
auto code = request.Pop<TransactionCode>(); auto code = request.Pop<TransactionCode>();
@ -192,7 +192,7 @@ namespace skyline::service::hosbinder {
.height = constant::HandheldResolutionH, .height = constant::HandheldResolutionH,
.transformHint = 0, .transformHint = 0,
.pendingBuffers = 0, .pendingBuffers = 0,
.status = constant::status::Success, .status = 0,
}; };
out.WriteData(connect); out.WriteData(connect);
break; break;
@ -207,20 +207,24 @@ namespace skyline::service::hosbinder {
} }
out.WriteParcel(request.outputBuf.at(0)); 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>(); request.Skip<u32>();
auto addVal = request.Pop<i32>(); auto addVal = request.Pop<i32>();
auto type = request.Pop<i32>(); auto type = request.Pop<i32>();
state.logger->Debug("Reference Change: {} {} reference", addVal, type ? "strong" : "weak"); 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); KHandle handle = state.process->InsertItem(state.gpu->bufferEvent);
state.logger->Debug("Display Buffer Event Handle: 0x{:X}", handle); state.logger->Debug("Display Buffer Event Handle: 0x{:X}", handle);
response.copyHandles.push_back(handle); response.copyHandles.push_back(handle);
response.Push<u32>(constant::status::Success);
return {};
} }
void IHOSBinderDriver::SetDisplay(const std::string &name) { 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 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 * @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) * @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) * @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) * @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 * @brief This sets displayId to a specific display type

View File

@ -9,7 +9,8 @@ namespace skyline::service::lm {
{0x0, SFUNC(ILogService::OpenLogger)} {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); 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) * @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 { struct Data {
u64 pid; u64 pid;
u64 threadContext; u64 threadContext;
@ -98,7 +98,10 @@ namespace skyline::service::lm {
break; 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) * @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) * @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)} {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 * @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)} {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); 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 * @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)} {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); 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) * @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)}, {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 constexpr u32 Unsubmitted = 1; //!< The request has not been submitted
response.Push<u32>(Unsubmitted); 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); auto handle = state.process->InsertItem(event0);
state.logger->Debug("Request Event 0 Handle: 0x{:X}", handle); state.logger->Debug("Request Event 0 Handle: 0x{:X}", handle);
response.copyHandles.push_back(handle); response.copyHandles.push_back(handle);
@ -27,7 +30,11 @@ namespace skyline::service::nifm {
handle = state.process->InsertItem(event1); handle = state.process->InsertItem(event1);
state.logger->Debug("Request Event 1 Handle: 0x{:X}", handle); state.logger->Debug("Request Event 1 Handle: 0x{:X}", handle);
response.copyHandles.push_back(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) * @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) * @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) * @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) * @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)} {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); 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) * @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)} {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 buffer = request.inputBuf.at(0);
auto path = state.process->GetString(buffer.address, buffer.size); auto path = state.process->GetString(buffer.address, buffer.size);
response.Push<u32>(OpenDevice(path)); 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 fd = request.Pop<u32>();
auto cmd = request.Pop<u32>(); auto cmd = request.Pop<u32>();
@ -87,25 +89,27 @@ namespace skyline::service::nvdrv {
device::IoctlData data(request.outputBuf.at(0)); device::IoctlData data(request.outputBuf.at(0));
fdMap.at(fd)->HandleIoctl(cmd, data); fdMap.at(fd)->HandleIoctl(cmd, data);
response.Push<u32>(data.status); response.Push(data.status);
} else { } else {
device::IoctlData data(request.inputBuf.at(0)); device::IoctlData data(request.inputBuf.at(0));
fdMap.at(fd)->HandleIoctl(cmd, data); fdMap.at(fd)->HandleIoctl(cmd, data);
response.Push<u32>(data.status); response.Push(data.status);
} }
} else { } else {
device::IoctlData data(request.inputBuf.at(0), request.outputBuf.at(0)); device::IoctlData data(request.inputBuf.at(0), request.outputBuf.at(0));
fdMap.at(fd)->HandleIoctl(cmd, data); fdMap.at(fd)->HandleIoctl(cmd, data);
response.Push<u32>(data.status); response.Push(data.status);
} }
} catch (const std::out_of_range &) { } catch (const std::out_of_range &) {
throw exception("IOCTL was requested on an invalid file descriptor"); 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>(); auto fd = request.Pop<u32>();
state.logger->Debug("Closing NVDRV device ({})", fd); state.logger->Debug("Closing NVDRV device ({})", fd);
@ -119,14 +123,16 @@ namespace skyline::service::nvdrv {
state.logger->Warn("Trying to close non-existent FD"); 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) { Result INvDrvServices::Initialize(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
response.Push<u32>(constant::status::Success); 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 fd = request.Pop<u32>();
auto eventId = request.Pop<u32>(); auto eventId = request.Pop<u32>();
auto device = fdMap.at(fd); auto device = fdMap.at(fd);
@ -138,15 +144,20 @@ namespace skyline::service::nvdrv {
state.logger->Debug("QueryEvent: FD: {}, Event ID: {}, Handle: {}", fd, eventId, handle); state.logger->Debug("QueryEvent: FD: {}, Event ID: {}, Handle: {}", fd, eventId, handle);
response.copyHandles.push_back(handle); response.copyHandles.push_back(handle);
response.Push<u32>(device::NvStatus::Success); response.Push(device::NvStatus::Success);
} else { } else {
response.Push<u32>(device::NvStatus::BadValue); response.Push(device::NvStatus::BadValue);
} }
return {};
} }
void INvDrvServices::SetAruidByPID(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) { Result INvDrvServices::SetAruidByPID(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {
response.Push<u32>(constant::status::Success); response.Push(device::NvStatus::Success);
return {};
} }
void INvDrvServices::SetGraphicsFirmwareMemoryMarginEnabled(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) {} 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) * @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) * @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) * @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) * @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) * @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) * @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) * @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) * @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 Success = 0x0, //!< The operation has succeeded
NotImplemented = 0x1, //!< The operation is not implemented NotImplemented = 0x1, //!< The operation is not implemented
NotSupported = 0x2, //!< The operation is not supported NotSupported = 0x2, //!< The operation is not supported

View File

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

View File

@ -10,7 +10,8 @@ namespace skyline::service::pctl {
{0x1, SFUNC(IParentalControlServiceFactory::CreateService)} {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); 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 * @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 constexpr u32 FontLoaded = 1; //!< This is returned to show that all fonts have been loaded into memory
response.Push(FontLoaded); 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>(); auto fontId = request.Pop<u32>();
response.Push<u32>(fontTable.at(fontId).length); 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>(); auto fontId = request.Pop<u32>();
response.Push<u32>(fontTable.at(fontId).offset); 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); auto handle = state.process->InsertItem<type::KSharedMemory>(fontSharedMem);
response.copyHandles.push_back(handle); 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) * @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) * @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) * @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) * @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)}, {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 * @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); auto service = session->domainTable.at(request.domain->objectId);
switch (static_cast<ipc::DomainCommand>(request.domain->command)) { switch (static_cast<ipc::DomainCommand>(request.domain->command)) {
case ipc::DomainCommand::SendMessage: case ipc::DomainCommand::SendMessage:
service->HandleRequest(*session, request, response); response.errorCode = service->HandleRequest(*session, request, response);
break; break;
case ipc::DomainCommand::CloseVHandle: case ipc::DomainCommand::CloseVHandle:
std::erase_if(serviceMap, [service](const auto &entry) { 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"); throw exception("Invalid object ID was used with domain request");
} }
} else { } else {
session->serviceObject->HandleRequest(*session, request, response); response.errorCode = session->serviceObject->HandleRequest(*session, request, response);
} }
response.WriteResponse(session->isDomain); response.WriteResponse(session->isDomain);
break; break;

View File

@ -31,19 +31,22 @@ namespace skyline::service::settings {
util::MakeMagic<u64>("zh-Hant"), 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)); state.process->WriteMemory(LanguageCodeList.data(), request.outputBuf.at(0).address, constant::OldLanguageCodeListSize * sizeof(u64));
response.Push<i32>(constant::OldLanguageCodeListSize); 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>())); 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)); state.process->WriteMemory(LanguageCodeList.data(), request.outputBuf.at(0).address, constant::NewLanguageCodeListSize * sizeof(u64));
response.Push<i32>(constant::NewLanguageCodeListSize); 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) * @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 * @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) * @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, { ISystemSettingsServer::ISystemSettingsServer(const DeviceState &state, ServiceManager &manager) : BaseService(state, manager, {
{0x3, SFUNC(ISystemSettingsServer::GetFirmwareVersion)}}) {} {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"}; 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); 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