diff --git a/src/core/core.vcxproj b/src/core/core.vcxproj index b10ae8684..be750b24f 100644 --- a/src/core/core.vcxproj +++ b/src/core/core.vcxproj @@ -153,6 +153,7 @@ + @@ -187,6 +188,7 @@ + diff --git a/src/core/core.vcxproj.filters b/src/core/core.vcxproj.filters index 4844e78b8..29d680935 100644 --- a/src/core/core.vcxproj.filters +++ b/src/core/core.vcxproj.filters @@ -90,6 +90,9 @@ hle\service + + hle\service + @@ -175,6 +178,9 @@ hle + + hle\service + diff --git a/src/core/hle/hle.cpp b/src/core/hle/hle.cpp index a4ab61c0c..c173b82de 100644 --- a/src/core/hle/hle.cpp +++ b/src/core/hle/hle.cpp @@ -42,6 +42,7 @@ u8 *GetPointer(const u32 addr) { return g_command_buffer + (addr & CMD_BUFFER_MASK); } else { ERROR_LOG(HLE, "unknown pointer from address %08X", addr); + return 0; } } diff --git a/src/core/hle/service/apt.cpp b/src/core/hle/service/apt.cpp new file mode 100644 index 000000000..9ab5a361c --- /dev/null +++ b/src/core/hle/service/apt.cpp @@ -0,0 +1,21 @@ +// Copyright 2014 Citra Emulator Project +// Licensed under GPLv2 +// Refer to the license.txt file included. + + +#include "common/log.h" +#include "core/hle/service/apt.h" + + + + +namespace Service { + + +Syscall::Result APT::Sync() { + NOTICE_LOG(HLE, "APT::Sync - Initialize"); + return 0; +} + + +} diff --git a/src/core/hle/service/apt.h b/src/core/hle/service/apt.h new file mode 100644 index 000000000..05c544378 --- /dev/null +++ b/src/core/hle/service/apt.h @@ -0,0 +1,71 @@ +// Copyright 2014 Citra Emulator Project +// Licensed under GPLv2 +// Refer to the license.txt file included. + +#pragma once + +#include "core/hle/service/service.h" + +//////////////////////////////////////////////////////////////////////////////////////////////////// +// Namespace Service + +namespace Service { + +// Application and title launching service. These services handle signaling for home/power button as +// well. Only one session for either APT service can be open at a time, normally processes close the +// service handle immediately once finished using the service. The commands for APT:U and APT:S are +// exactly the same, however certain commands are only accessible with APT:S(NS module will call +// svcBreak when the command isn't accessible). See http://3dbrew.org/wiki/NS#APT_Services. + +class APT : public Interface { +public: + + APT() { + } + + ~APT() { + } + + enum { + CMD_OFFSET = 0x00000080, + + CMD_HEADER_INIT = 0x00020080, ///< Initialize service + CMD_HEADER_GET_LOCK_HANDLE = 0x00010040, ///< Get service Mutex + CMD_HEADER_ENABLE = 0x00030040, ///< Enable service + CMD_HEADER_INQUIRE_NOTIFICATION = 0x000B0040, ///< Inquire notification + CMD_HEADER_PREPARE_TO_JUMP_TO_HOME_MENU = 0x002B0000, ///< Prepare to jump to home menu + CMD_HEADER_JUMP_TO_HOME_MENU = 0x002C0044, ///< Jump to home menu + CMD_HEADER_NOTIFY_TO_WAIT = 0x00430040, ///< Notify to wait + CMD_HEADER_APPLET_UTILITY = 0x004B00C2, ///< Applet utility + CMD_HEADER_GLANCE_PARAMETER = 0x000E0080, ///< Glance parameter + CMD_HEADER_RECEIVE_PARAMETER = 0x000D0080, ///< Receive parameter + CMD_HEADER_REPLY_SLEEP_QUERY = 0x003E0080, ///< Reply sleep query + CMD_HEADER_PREPARE_TO_CLOSE_APP = 0x00220040, ///< Prepare to close application + CMD_HEADER_CLOSE_APP = 0x00270044, ///< Close application + }; + + /** + * Gets the string name used by CTROS for the APT service + * @return String name of service + */ + std::string GetName() const { + return "APT"; + } + + /** + * Gets the string port name used by CTROS for the APT service + * @return Port name of service + */ + std::string GetPortName() const { + return "APT:U"; + } + + /** + * Called when svcSendSyncRequest is called, loads command buffer and executes comand + * @return Return result of svcSendSyncRequest passed back to user app + */ + virtual Syscall::Result Sync(); + +}; + +} // namespace diff --git a/src/core/hle/service/service.cpp b/src/core/hle/service/service.cpp index b0b2b7b35..b2470d814 100644 --- a/src/core/hle/service/service.cpp +++ b/src/core/hle/service/service.cpp @@ -7,6 +7,7 @@ #include "core/hle/hle.h" #include "core/hle/service/service.h" +#include "core/hle/service/apt.h" namespace Service { @@ -104,19 +105,36 @@ public: */ Syscall::Result Sync() { u32 header = 0; - HLE::Read(header, (HLE::CMD_BUFFER_ADDR + CMD_OFFSET)); + Syscall::Result res = 0; + + u32* cmd_buff = (u32*)HLE::GetPointer(HLE::CMD_BUFFER_ADDR + CMD_OFFSET); + + switch (cmd_buff[0]) { - switch (header) { case CMD_HEADER_INIT: - NOTICE_LOG(HLE, "SRV::Sync - Initialize"); + NOTICE_LOG(OSHLE, "SRV::Sync - Initialize"); break; case CMD_HEADER_GET_HANDLE: - NOTICE_LOG(HLE, "SRV::Sync - GetHandle, port: %s", HLE::GetCharPointer(HLE::CMD_BUFFER_ADDR + CMD_OFFSET + 4)); + const char* port_name = (const char*)&cmd_buff[1]; + Interface* service = g_manager->FetchFromPortName(port_name); + + NOTICE_LOG(OSHLE, "SRV::Sync - GetHandle - port: %s, handle: 0x%08X", port_name, + service->GetUID()); + + if (NULL != service) { + cmd_buff[3] = service->GetUID(); + } else { + ERROR_LOG(OSHLE, "Service %s does not exist", port_name); + res = -1; + } + break; } - return 0; + cmd_buff[1] = res; + + return res; } }; @@ -128,6 +146,7 @@ public: void Init() { g_manager = new Manager; g_manager->AddService(new SRV); + g_manager->AddService(new APT); NOTICE_LOG(HLE, "Services initialized OK"); } diff --git a/src/core/hle/service/service.h b/src/core/hle/service/service.h index 3cad6c642..365583ed2 100644 --- a/src/core/hle/service/service.h +++ b/src/core/hle/service/service.h @@ -8,6 +8,7 @@ #include #include +#include "common/common.h" #include "common/common_types.h" #include "core/hle/syscall.h"