mirror of
https://github.com/wheremyfoodat/Panda3DS.git
synced 2025-05-24 12:36:25 +12:00
Started work on services
This commit is contained in:
parent
3259c5c7a6
commit
208c18356b
9 changed files with 169 additions and 18 deletions
src/core/kernel
|
@ -7,15 +7,40 @@ Handle Kernel::makePort(const char* name) {
|
|||
|
||||
objects[ret].data = new PortData();
|
||||
const auto data = static_cast<PortData*>(objects[ret].data);
|
||||
std::strncpy(data->name, name, PortData::maxNameLen);
|
||||
|
||||
// If the name is empty (ie the first char is the null terminator) then the port is private
|
||||
data->isPublic = name[0] != '\0';
|
||||
std::strncpy(data->name, name, PortData::maxNameLen);
|
||||
|
||||
// Check if this a special port (Like the service manager port) or not, and cache its type
|
||||
if (std::strncmp(name, "srv:", PortData::maxNameLen) == 0) {
|
||||
data->type = PortType::ServiceManager;
|
||||
} else {
|
||||
data->type = PortType::Generic;
|
||||
Helpers::panic("Created generic port %s\n", name);
|
||||
}
|
||||
|
||||
// printf("Created %s port \"%s\" with handle %d\n", data->isPublic ? "public" : "private", data->name, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
Handle Kernel::makeSession(Handle portHandle) {
|
||||
const auto port = getObject(portHandle, KernelObjectType::Port);
|
||||
if (port == nullptr) [[unlikely]] {
|
||||
Helpers::panic("Trying to make session for non-existent port");
|
||||
}
|
||||
|
||||
// Allocate data for session
|
||||
const Handle ret = makeObject(KernelObjectType::Session);
|
||||
objects[ret].data = new SessionData();
|
||||
auto sessionData = static_cast<SessionData*>(objects[ret].data);
|
||||
|
||||
// Link session with its parent port
|
||||
sessionData->portHandle = portHandle;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Get the handle of a port based on its name
|
||||
// If there's no such port, return nullopt
|
||||
std::optional<Handle> Kernel::getPortHandle(const char* name) {
|
||||
|
@ -32,25 +57,33 @@ std::optional<Handle> Kernel::getPortHandle(const char* name) {
|
|||
// Result ConnectToPort(Handle* out, const char* portName)
|
||||
void Kernel::connectToPort() {
|
||||
const u32 handlePointer = regs[0];
|
||||
const char* port = static_cast<const char*>(mem.getReadPointer(regs[1]));
|
||||
printf("ConnectToPort(handle pointer = %08X, port = \"%s\")\n", handlePointer, port);
|
||||
// Read up to max + 1 characters to see if the name is too long
|
||||
std::string port = mem.readString(regs[1], PortData::maxNameLen + 1);
|
||||
|
||||
// TODO: This is unsafe
|
||||
if (std::strlen(port) > PortData::maxNameLen) {
|
||||
if (port.size() > PortData::maxNameLen) {
|
||||
Helpers::panic("ConnectToPort: Port name too long\n");
|
||||
regs[0] = SVCResult::PortNameTooLong;
|
||||
return;
|
||||
}
|
||||
|
||||
const auto portHandle = getPortHandle(port);
|
||||
if (!portHandle.has_value()) [[unlikely]] {
|
||||
// Try getting a handle to the port
|
||||
std::optional<Handle> optionalHandle = getPortHandle(port.c_str());
|
||||
if (!optionalHandle.has_value()) [[unlikely]] {
|
||||
Helpers::panic("ConnectToPort: Port doesn't exist\n");
|
||||
regs[0] = SVCResult::ObjectNotFound;
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
Handle portHandle = optionalHandle.value();
|
||||
printf("ConnectToPort(handle pointer = %08X, port = \"%s\")\n", handlePointer, port.c_str());
|
||||
|
||||
const auto portData = static_cast<PortData*>(objects[portHandle].data);
|
||||
if (!portData->isPublic) {
|
||||
Helpers::panic("ConnectToPort: Attempted to connect to private port");
|
||||
}
|
||||
|
||||
// TODO: Actually create session
|
||||
Handle sessionHandle = makeObject(KernelObjectType::Session);
|
||||
Handle sessionHandle = makeSession(portHandle);
|
||||
|
||||
// TODO: Should the result be written back to [r0]?
|
||||
regs[0] = SVCResult::Success;
|
||||
|
@ -70,8 +103,14 @@ void Kernel::sendSyncRequest() {
|
|||
}
|
||||
|
||||
const auto sessionData = static_cast<SessionData*>(session->data);
|
||||
const u32 messagePointer = VirtualAddrs::TLSBase + 0x80;
|
||||
const auto port = objects[sessionData->portHandle]; // Get parent port object
|
||||
const auto portData = static_cast<PortData*>(port.data);
|
||||
|
||||
if (portData->type == PortType::ServiceManager) { // Special-case SendSyncRequest targetting "srv:"
|
||||
serviceManager.handleSyncRequest(getTLSPointer());
|
||||
} else {
|
||||
Helpers::panic("SendSyncRequest targetting port %s\n", portData->name);
|
||||
}
|
||||
|
||||
Helpers::panic("SendSyncRequest: Message header: %08X", mem.read32(messagePointer));
|
||||
regs[0] = SVCResult::Success;
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue