diff --git a/src/core/hle/kernel/client_port.cpp b/src/core/hle/kernel/client_port.cpp index f25cb48dd..b6a4cab26 100644 --- a/src/core/hle/kernel/client_port.cpp +++ b/src/core/hle/kernel/client_port.cpp @@ -4,6 +4,7 @@ #include "common/assert.h" #include "core/hle/kernel/client_port.h" +#include "core/hle/kernel/client_session.h" #include "core/hle/kernel/kernel.h" #include "core/hle/kernel/server_port.h" #include "core/hle/kernel/server_session.h" diff --git a/src/core/hle/kernel/server_port.h b/src/core/hle/kernel/server_port.h index dee0b1a9a..b0f8df62c 100644 --- a/src/core/hle/kernel/server_port.h +++ b/src/core/hle/kernel/server_port.h @@ -4,6 +4,7 @@ #pragma once +#include #include #include #include "common/common_types.h" diff --git a/src/core/hle/service/fs/archive.cpp b/src/core/hle/service/fs/archive.cpp index a9f457726..c10d6a3a9 100644 --- a/src/core/hle/service/fs/archive.cpp +++ b/src/core/hle/service/fs/archive.cpp @@ -93,7 +93,7 @@ File::File(std::unique_ptr&& backend, const FileSys::Path& File::~File() {} -ResultCode File::HandleSyncRequest(Kernel::SharedPtr server_session) { +void File::HandleSyncRequestImpl(Kernel::SharedPtr server_session) { u32* cmd_buff = Kernel::GetCommandBuffer(); FileCommand cmd = static_cast(cmd_buff[0]); switch (cmd) { @@ -116,7 +116,7 @@ ResultCode File::HandleSyncRequest(Kernel::SharedPtr serv ResultVal read = backend->Read(offset, data.size(), data.data()); if (read.Failed()) { cmd_buff[1] = read.Code().raw; - return read.Code(); + return; } Memory::WriteBlock(address, data.data(), *read); cmd_buff[2] = static_cast(*read); @@ -137,7 +137,7 @@ ResultCode File::HandleSyncRequest(Kernel::SharedPtr serv ResultVal written = backend->Write(offset, data.size(), flush != 0, data.data()); if (written.Failed()) { cmd_buff[1] = written.Code().raw; - return written.Code(); + return; } cmd_buff[2] = static_cast(*written); break; @@ -195,10 +195,9 @@ ResultCode File::HandleSyncRequest(Kernel::SharedPtr serv LOG_ERROR(Service_FS, "Unknown command=0x%08X!", cmd); ResultCode error = UnimplementedFunction(ErrorModule::FS); cmd_buff[1] = error.raw; // TODO(Link Mauve): use the correct error code for that. - return error; + return; } cmd_buff[1] = RESULT_SUCCESS.raw; // No error - return RESULT_SUCCESS; } Directory::Directory(std::unique_ptr&& backend, @@ -207,7 +206,7 @@ Directory::Directory(std::unique_ptr&& backend, Directory::~Directory() {} -ResultCode Directory::HandleSyncRequest(Kernel::SharedPtr server_session) { +void Directory::HandleSyncRequestImpl(Kernel::SharedPtr server_session) { u32* cmd_buff = Kernel::GetCommandBuffer(); DirectoryCommand cmd = static_cast(cmd_buff[0]); switch (cmd) { @@ -237,10 +236,9 @@ ResultCode Directory::HandleSyncRequest(Kernel::SharedPtr LOG_ERROR(Service_FS, "Unknown command=0x%08X!", cmd); ResultCode error = UnimplementedFunction(ErrorModule::FS); cmd_buff[1] = error.raw; // TODO(Link Mauve): use the correct error code for that. - return RESULT_SUCCESS; + return; } cmd_buff[1] = RESULT_SUCCESS.raw; // No error - return RESULT_SUCCESS; } //////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/core/hle/service/fs/archive.h b/src/core/hle/service/fs/archive.h index 29527ef48..cb014b5d7 100644 --- a/src/core/hle/service/fs/archive.h +++ b/src/core/hle/service/fs/archive.h @@ -50,11 +50,12 @@ public: return "Path: " + path.DebugStr(); } - ResultCode HandleSyncRequest(Kernel::SharedPtr server_session) override; - FileSys::Path path; ///< Path of the file u32 priority; ///< Priority of the file. TODO(Subv): Find out what this means std::unique_ptr backend; ///< File backend interface + +protected: + void HandleSyncRequestImpl(Kernel::SharedPtr server_session) override; }; class Directory : public SessionRequestHandler { @@ -66,10 +67,11 @@ public: return "Directory: " + path.DebugStr(); } - ResultCode HandleSyncRequest(Kernel::SharedPtr server_session) override; - FileSys::Path path; ///< Path of the directory std::unique_ptr backend; ///< File backend interface + +protected: + void HandleSyncRequestImpl(Kernel::SharedPtr server_session) override; }; /** diff --git a/src/core/hle/service/service.cpp b/src/core/hle/service/service.cpp index 3462af8ce..3d5e3058c 100644 --- a/src/core/hle/service/service.cpp +++ b/src/core/hle/service/service.cpp @@ -64,7 +64,27 @@ static std::string MakeFunctionString(const char* name, const char* port_name, return function_string; } -ResultCode Interface::HandleSyncRequest(Kernel::SharedPtr server_session) { +ResultCode SessionRequestHandler::HandleSyncRequest(Kernel::SharedPtr server_session) { + // Attempt to translate the incoming request's command buffer. + ResultCode result = TranslateRequest(server_session); + + if (result.IsError()) + return result; + + // Actually handle the request + HandleSyncRequestImpl(server_session); + + // TODO(Subv): Translate the response command buffer. + + return RESULT_SUCCESS; +} + +ResultCode SessionRequestHandler::TranslateRequest(Kernel::SharedPtr server_session) { + // TODO(Subv): Implement this function once multiple concurrent processes are supported. + return RESULT_SUCCESS; +} + +void Interface::HandleSyncRequestImpl(Kernel::SharedPtr server_session) { // TODO(Subv): Make use of the server_session in the HLE service handlers to distinguish which session triggered each command. u32* cmd_buff = Kernel::GetCommandBuffer(); @@ -80,14 +100,12 @@ ResultCode Interface::HandleSyncRequest(Kernel::SharedPtr // TODO(bunnei): Hack - ignore error cmd_buff[1] = 0; - return RESULT_SUCCESS; + return; } LOG_TRACE(Service, "%s", MakeFunctionString(itr->second.name, GetPortName().c_str(), cmd_buff).c_str()); itr->second.func(this); - - return RESULT_SUCCESS; // TODO: Implement return from actual function, it should fail if the parameter translation fails } void Interface::Register(const FunctionInfo* functions, size_t n) { @@ -179,4 +197,5 @@ void Shutdown() { g_kernel_named_ports.clear(); LOG_DEBUG(Service, "shutdown OK"); } + } diff --git a/src/core/hle/service/service.h b/src/core/hle/service/service.h index e85882713..7b7db8499 100644 --- a/src/core/hle/service/service.h +++ b/src/core/hle/service/service.h @@ -187,11 +187,27 @@ public: * Dispatches and handles a sync request from the emulated application. * @param server_session The ServerSession that was triggered for this sync request, * it should be used to differentiate which client (As in ClientSession) we're answering to. - * TODO(Subv): Make a HandleSyncRequestParent function that is called from the outside and does { ReturnIfError(Translate()); HandleSyncRequest(); } - * The Translate() function would copy the command buffer from the ServerSession thread's TLS into a temporary buffer, and pass it to HandleSyncRequest. - * TODO(Subv): HandleSyncRequest's return type should be void. + * @returns ResultCode the result code of the translate operation. */ - virtual ResultCode HandleSyncRequest(Kernel::SharedPtr server_session) = 0; + ResultCode HandleSyncRequest(Kernel::SharedPtr server_session); + +protected: + /** + * Handles a sync request from the emulated application and writes the response to the command buffer. + * TODO(Subv): Use a wrapper structure to hold all the information relevant to + * this request (ServerSession, Originator thread, Translated command buffer, etc). + */ + virtual void HandleSyncRequestImpl(Kernel::SharedPtr server_session) = 0; + +private: + /** + * Performs command buffer translation for this request. + * The command buffer from the ServerSession thread's TLS is copied into a + * buffer and all descriptors in the buffer are processed. + * TODO(Subv): Implement this function, currently we do not support multiple processes running at once, + * but once that is implemented we'll need to properly translate all descriptors in the command buffer. + */ + ResultCode TranslateRequest(Kernel::SharedPtr server_session); }; /** @@ -231,9 +247,9 @@ public: return "[UNKNOWN SERVICE PORT]"; } - ResultCode HandleSyncRequest(Kernel::SharedPtr server_session) override; - protected: + void HandleSyncRequestImpl(Kernel::SharedPtr server_session) override; + /** * Registers the functions in the service */