diff options
Diffstat (limited to 'src/core/hle/service')
37 files changed, 723 insertions, 192 deletions
diff --git a/src/core/hle/service/ac_u.cpp b/src/core/hle/service/ac_u.cpp index b39603bdf..9af96f6b8 100644 --- a/src/core/hle/service/ac_u.cpp +++ b/src/core/hle/service/ac_u.cpp @@ -22,12 +22,12 @@ const Interface::FunctionInfo FunctionTable[] = { {0x000E0042, nullptr, "GetCurrentAPInfo"}, {0x00100042, nullptr, "GetCurrentNZoneInfo"}, {0x00110042, nullptr, "GetNZoneApNumService"}, - {0x00240042, nullptr, "AddDenyApType "}, - {0x00270002, nullptr, "GetInfraPriority "}, + {0x00240042, nullptr, "AddDenyApType"}, + {0x00270002, nullptr, "GetInfraPriority"}, {0x002D0082, nullptr, "SetRequestEulaVersion"}, {0x00300004, nullptr, "RegisterDisconnectEvent"}, {0x003C0042, nullptr, "GetAPSSIDList"}, - {0x003E0042, nullptr, "IsConnected "}, + {0x003E0042, nullptr, "IsConnected"}, {0x00400042, nullptr, "SetClientVersion"}, }; diff --git a/src/core/hle/service/ac_u.h b/src/core/hle/service/ac_u.h index 3c5958d27..c91b28353 100644 --- a/src/core/hle/service/ac_u.h +++ b/src/core/hle/service/ac_u.h @@ -9,7 +9,7 @@ //////////////////////////////////////////////////////////////////////////////////////////////////// // Namespace AC_U -// socket service "ac:u" +// socket service "ac:u" namespace AC_U { @@ -21,7 +21,7 @@ public: * Gets the string port name used by CTROS for the service * @return Port name of service */ - std::string GetPortName() const { + std::string GetPortName() const override { return "ac:u"; } }; diff --git a/src/core/hle/service/am_net.cpp b/src/core/hle/service/am_net.cpp new file mode 100644 index 000000000..403cac353 --- /dev/null +++ b/src/core/hle/service/am_net.cpp @@ -0,0 +1,47 @@ +// Copyright 2014 Citra Emulator Project +// Licensed under GPLv2 +// Refer to the license.txt file included. + +#include "common/log.h" +#include "core/hle/hle.h" +#include "core/hle/service/am_net.h" + +//////////////////////////////////////////////////////////////////////////////////////////////////// +// Namespace AM_NET + +namespace AM_NET { + +const Interface::FunctionInfo FunctionTable[] = { + {0x08010000, nullptr, "OpenTicket"}, + {0x08020002, nullptr, "TicketAbortInstall"}, + {0x08030002, nullptr, "TicketFinalizeInstall"}, + {0x08040100, nullptr, "InstallTitleBegin"}, + {0x08050000, nullptr, "InstallTitleAbort"}, + {0x080600C0, nullptr, "InstallTitleResume"}, + {0x08070000, nullptr, "InstallTitleAbortTMD"}, + {0x08080000, nullptr, "InstallTitleFinish"}, + {0x080A0000, nullptr, "OpenTMD"}, + {0x080B0002, nullptr, "TMDAbortInstall"}, + {0x080C0042, nullptr, "TMDFinalizeInstall"}, + {0x080E0040, nullptr, "OpenContentCreate"}, + {0x080F0002, nullptr, "ContentAbortInstall"}, + {0x08100040, nullptr, "OpenContentResume"}, + {0x08120002, nullptr, "ContentFinalizeInstall"}, + {0x08130000, nullptr, "GetTotalContents"}, + {0x08140042, nullptr, "GetContentIndexes"}, + {0x08150044, nullptr, "GetContentsInfo"}, + {0x08190108, nullptr, "Unknown"}, + {0x081B00C2, nullptr, "InstallTitlesFinish"}, +}; + +//////////////////////////////////////////////////////////////////////////////////////////////////// +// Interface class + +Interface::Interface() { + Register(FunctionTable, ARRAY_SIZE(FunctionTable)); +} + +Interface::~Interface() { +} + +} // namespace diff --git a/src/core/hle/service/am_net.h b/src/core/hle/service/am_net.h new file mode 100644 index 000000000..4816e1697 --- /dev/null +++ b/src/core/hle/service/am_net.h @@ -0,0 +1,27 @@ +// Copyright 2014 Citra Emulator Project +// Licensed under GPLv2 +// Refer to the license.txt file included. + +#pragma once + +#include "core/hle/service/service.h" + +//////////////////////////////////////////////////////////////////////////////////////////////////// +// Namespace AM_NET + +namespace AM_NET { + +class Interface : public Service::Interface { +public: + Interface(); + ~Interface(); + /** + * Gets the string port name used by CTROS for the service + * @return Port name of service + */ + std::string GetPortName() const override { + return "am:net"; + } +}; + +} // namespace diff --git a/src/core/hle/service/apt_u.cpp b/src/core/hle/service/apt_u.cpp index 4f41ec5f4..4bb05ce40 100644 --- a/src/core/hle/service/apt_u.cpp +++ b/src/core/hle/service/apt_u.cpp @@ -27,7 +27,7 @@ enum class SignalType : u32 { void Initialize(Service::Interface* self) { u32* cmd_buff = Service::GetCommandBuffer(); - + cmd_buff[3] = Kernel::CreateEvent(RESETTYPE_ONESHOT, "APT_U:Menu"); // APT menu event handle cmd_buff[4] = Kernel::CreateEvent(RESETTYPE_ONESHOT, "APT_U:Pause"); // APT pause event handle @@ -168,7 +168,7 @@ void AppletUtility(Service::Interface* self) { cmd_buff[1] = 0; // No error WARN_LOG(KERNEL, "(STUBBED) called unk=0x%08X, buffer1_size=0x%08x, buffer2_size=0x%08x, " - "buffer1_addr=0x%08x, buffer2_addr=0x%08x", unk, buffer1_size, buffer2_size, + "buffer1_addr=0x%08x, buffer2_addr=0x%08x", unk, buffer1_size, buffer2_size, buffer1_addr, buffer2_addr); } diff --git a/src/core/hle/service/apt_u.h b/src/core/hle/service/apt_u.h index 5af39e085..306730400 100644 --- a/src/core/hle/service/apt_u.h +++ b/src/core/hle/service/apt_u.h @@ -13,8 +13,8 @@ namespace APT_U { // 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 +// 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. /// Interface to "APT:U" service diff --git a/src/core/hle/service/boss_u.cpp b/src/core/hle/service/boss_u.cpp new file mode 100644 index 000000000..b2ff4a756 --- /dev/null +++ b/src/core/hle/service/boss_u.cpp @@ -0,0 +1,28 @@ +// Copyright 2014 Citra Emulator Project +// Licensed under GPLv2 +// Refer to the license.txt file included. + +#include "common/log.h" +#include "core/hle/hle.h" +#include "core/hle/service/boss_u.h" + +//////////////////////////////////////////////////////////////////////////////////////////////////// +// Namespace BOSS_U + +namespace BOSS_U { + + const Interface::FunctionInfo FunctionTable[] = { + {0x00020100, nullptr, "GetStorageInfo"}, + }; + + //////////////////////////////////////////////////////////////////////////////////////////////////// + // Interface class + + Interface::Interface() { + Register(FunctionTable, ARRAY_SIZE(FunctionTable)); + } + + Interface::~Interface() { + } + +} // namespace diff --git a/src/core/hle/service/boss_u.h b/src/core/hle/service/boss_u.h new file mode 100644 index 000000000..af39b8e65 --- /dev/null +++ b/src/core/hle/service/boss_u.h @@ -0,0 +1,27 @@ +// Copyright 2014 Citra Emulator Project +// Licensed under GPLv2 +// Refer to the license.txt file included. + +#pragma once + +#include "core/hle/service/service.h" + +//////////////////////////////////////////////////////////////////////////////////////////////////// +// Namespace BOSS_U + +namespace BOSS_U { + + class Interface : public Service::Interface { + public: + Interface(); + ~Interface(); + /** + * Gets the string port name used by CTROS for the service + * @return Port name of service + */ + std::string GetPortName() const { + return "boss:U"; + } + }; + +} // namespace diff --git a/src/core/hle/service/cfg_i.cpp b/src/core/hle/service/cfg_i.cpp new file mode 100644 index 000000000..88d13d459 --- /dev/null +++ b/src/core/hle/service/cfg_i.cpp @@ -0,0 +1,59 @@ +// Copyright 2014 Citra Emulator Project +// Licensed under GPLv2 +// Refer to the license.txt file included. + +#include "common/log.h" +#include "core/hle/hle.h" +#include "core/hle/service/cfg_i.h" + +//////////////////////////////////////////////////////////////////////////////////////////////////// +// Namespace CFG_I + +namespace CFG_I { + +const Interface::FunctionInfo FunctionTable[] = { + {0x04010082, nullptr, "GetConfigInfoBlk8"}, + {0x04020082, nullptr, "GetConfigInfoBlk4"}, + {0x04030000, nullptr, "UpdateConfigNANDSavegame"}, + {0x04040042, nullptr, "GetLocalFriendCodeSeedData"}, + {0x04050000, nullptr, "GetLocalFriendCodeSeed"}, + {0x04060000, nullptr, "SecureInfoGetRegion"}, + {0x04070000, nullptr, "SecureInfoGetByte101"}, + {0x04080042, nullptr, "SecureInfoGetSerialNo"}, + {0x04090000, nullptr, "UpdateConfigBlk00040003"}, + {0x08010082, nullptr, "GetConfigInfoBlk8"}, + {0x08020082, nullptr, "GetConfigInfoBlk4"}, + {0x08030000, nullptr, "UpdateConfigNANDSavegame"}, + {0x080400C2, nullptr, "CreateConfigInfoBlk"}, + {0x08050000, nullptr, "DeleteConfigNANDSavefile"}, + {0x08060000, nullptr, "FormatConfig"}, + {0x08070000, nullptr, "Unknown"}, + {0x08080000, nullptr, "UpdateConfigBlk1"}, + {0x08090000, nullptr, "UpdateConfigBlk2"}, + {0x080A0000, nullptr, "UpdateConfigBlk3"}, + {0x080B0082, nullptr, "SetGetLocalFriendCodeSeedData"}, + {0x080C0042, nullptr, "SetLocalFriendCodeSeedSignature"}, + {0x080D0000, nullptr, "DeleteCreateNANDLocalFriendCodeSeed"}, + {0x080E0000, nullptr, "VerifySigLocalFriendCodeSeed"}, + {0x080F0042, nullptr, "GetLocalFriendCodeSeedData"}, + {0x08100000, nullptr, "GetLocalFriendCodeSeed"}, + {0x08110084, nullptr, "SetSecureInfo"}, + {0x08120000, nullptr, "DeleteCreateNANDSecureInfo"}, + {0x08130000, nullptr, "VerifySigSecureInfo"}, + {0x08140042, nullptr, "SecureInfoGetData"}, + {0x08150042, nullptr, "SecureInfoGetSignature"}, + {0x08160000, nullptr, "SecureInfoGetRegion"}, + {0x08170000, nullptr, "SecureInfoGetByte101"}, + {0x08180042, nullptr, "SecureInfoGetSerialNo"}, +}; +//////////////////////////////////////////////////////////////////////////////////////////////////// +// Interface class + +Interface::Interface() { + Register(FunctionTable, ARRAY_SIZE(FunctionTable)); +} + +Interface::~Interface() { +} + +} // namespace diff --git a/src/core/hle/service/cfg_i.h b/src/core/hle/service/cfg_i.h new file mode 100644 index 000000000..fe343c968 --- /dev/null +++ b/src/core/hle/service/cfg_i.h @@ -0,0 +1,27 @@ +// Copyright 2014 Citra Emulator Project +// Licensed under GPLv2 +// Refer to the license.txt file included. + +#pragma once + +#include "core/hle/service/service.h" + +//////////////////////////////////////////////////////////////////////////////////////////////////// +// Namespace CFG_I + +namespace CFG_I { + +class Interface : public Service::Interface { +public: + Interface(); + ~Interface(); + /** + * Gets the string port name used by CTROS for the service + * @return Port name of service + */ + std::string GetPortName() const override { + return "cfg:i"; + } +}; + +} // namespace diff --git a/src/core/hle/service/cfg_u.h b/src/core/hle/service/cfg_u.h index 7525bd7c6..8075d19a8 100644 --- a/src/core/hle/service/cfg_u.h +++ b/src/core/hle/service/cfg_u.h @@ -19,7 +19,7 @@ public: * Gets the string port name used by CTROS for the service * @return Port name of service */ - std::string GetPortName() const { + std::string GetPortName() const override { return "cfg:u"; } }; diff --git a/src/core/hle/service/csnd_snd.cpp b/src/core/hle/service/csnd_snd.cpp new file mode 100644 index 000000000..6e59a9bf3 --- /dev/null +++ b/src/core/hle/service/csnd_snd.cpp @@ -0,0 +1,39 @@ +// Copyright 2014 Citra Emulator Project +// Licensed under GPLv2 +// Refer to the license.txt file included. + +#include "common/log.h" +#include "core/hle/hle.h" +#include "core/hle/service/csnd_snd.h" + +//////////////////////////////////////////////////////////////////////////////////////////////////// +// Namespace CSND_SND + +namespace CSND_SND { + +const Interface::FunctionInfo FunctionTable[] = { + {0x00010140, nullptr, "Initialize"}, + {0x00020000, nullptr, "Shutdown"}, + {0x00030040, nullptr, "Unknown"}, + {0x00040080, nullptr, "Unknown"}, + {0x00050000, nullptr, "Unknown"}, + {0x00060000, nullptr, "Unknown"}, + {0x00070000, nullptr, "Unknown"}, + {0x00080040, nullptr, "Unknown"}, + {0x00090082, nullptr, "FlushDCache"}, + {0x000A0082, nullptr, "StoreDCache"}, + {0x000B0082, nullptr, "InvalidateDCache"}, + {0x000C0000, nullptr, "Unknown"}, +}; + +//////////////////////////////////////////////////////////////////////////////////////////////////// +// Interface class + +Interface::Interface() { + Register(FunctionTable, ARRAY_SIZE(FunctionTable)); +} + +Interface::~Interface() { +} + +} // namespace diff --git a/src/core/hle/service/csnd_snd.h b/src/core/hle/service/csnd_snd.h new file mode 100644 index 000000000..31cc85b07 --- /dev/null +++ b/src/core/hle/service/csnd_snd.h @@ -0,0 +1,27 @@ +// Copyright 2014 Citra Emulator Project +// Licensed under GPLv2 +// Refer to the license.txt file included. + +#pragma once + +#include "core/hle/service/service.h" + +//////////////////////////////////////////////////////////////////////////////////////////////////// +// Namespace CSND_SND + +namespace CSND_SND { + +class Interface : public Service::Interface { +public: + Interface(); + ~Interface(); + /** + * Gets the string port name used by CTROS for the service + * @return Port name of service + */ + std::string GetPortName() const override { + return "csnd:SND"; + } +}; + +} // namespace diff --git a/src/core/hle/service/dsp_dsp.cpp b/src/core/hle/service/dsp_dsp.cpp index 9e84ac938..bbcf26f61 100644 --- a/src/core/hle/service/dsp_dsp.cpp +++ b/src/core/hle/service/dsp_dsp.cpp @@ -26,12 +26,12 @@ const Interface::FunctionInfo FunctionTable[] = { {0x001100C2, nullptr, "LoadComponent"}, {0x00120000, nullptr, "UnloadComponent"}, {0x00130082, nullptr, "FlushDataCache"}, - {0x00140082, nullptr, "InvalidateDCache "}, + {0x00140082, nullptr, "InvalidateDCache"}, {0x00150082, nullptr, "RegisterInterruptEvents"}, {0x00160000, nullptr, "GetSemaphoreEventHandle"}, {0x00170040, nullptr, "SetSemaphoreMask"}, {0x00180040, nullptr, "GetPhysicalAddress"}, - {0x00190040, nullptr, "GetVirtualAddress" }, + {0x00190040, nullptr, "GetVirtualAddress"}, {0x001A0042, nullptr, "SetIirFilterI2S1_cmd1"}, {0x001B0042, nullptr, "SetIirFilterI2S1_cmd2"}, {0x001C0082, nullptr, "SetIirFilterEQ"}, diff --git a/src/core/hle/service/dsp_dsp.h b/src/core/hle/service/dsp_dsp.h index c439ed266..c4ce44245 100644 --- a/src/core/hle/service/dsp_dsp.h +++ b/src/core/hle/service/dsp_dsp.h @@ -19,7 +19,7 @@ public: * Gets the string port name used by CTROS for the service * @return Port name of service */ - std::string GetPortName() const { + std::string GetPortName() const override { return "dsp:DSP"; } }; diff --git a/src/core/hle/service/err_f.cpp b/src/core/hle/service/err_f.cpp index 917b2f8ca..785c351e9 100644 --- a/src/core/hle/service/err_f.cpp +++ b/src/core/hle/service/err_f.cpp @@ -20,8 +20,8 @@ namespace ERR_F { Interface::Interface() { Register(FunctionTable, ARRAY_SIZE(FunctionTable)); } - + Interface::~Interface() { } - + } // namespace diff --git a/src/core/hle/service/err_f.h b/src/core/hle/service/err_f.h index 5da663267..6d7141c1b 100644 --- a/src/core/hle/service/err_f.h +++ b/src/core/hle/service/err_f.h @@ -19,9 +19,9 @@ namespace ERR_F { * Gets the string port name used by CTROS for the service * @return Port name of service */ - std::string GetPortName() const { + std::string GetPortName() const override { return "err:f"; } }; - + } // namespace diff --git a/src/core/hle/service/frd_u.h b/src/core/hle/service/frd_u.h index 9df8a815a..4020c6664 100644 --- a/src/core/hle/service/frd_u.h +++ b/src/core/hle/service/frd_u.h @@ -19,7 +19,7 @@ namespace FRD_U { * Gets the string port name used by CTROS for the service * @return Port name of service */ - std::string GetPortName() const { + std::string GetPortName() const override { return "frd:u"; } }; diff --git a/src/core/hle/service/fs_user.cpp b/src/core/hle/service/fs_user.cpp index 9dc83291d..34af78cb9 100644 --- a/src/core/hle/service/fs_user.cpp +++ b/src/core/hle/service/fs_user.cpp @@ -4,31 +4,45 @@ #include "common/common.h" -#include "fs_user.h" #include "common/string_util.h" -#include "core/settings.h" #include "core/hle/kernel/archive.h" +#include "core/hle/kernel/archive.h" +#include "core/hle/result.h" +#include "core/hle/service/fs_user.h" +#include "core/settings.h" //////////////////////////////////////////////////////////////////////////////////////////////////// // Namespace FS_User namespace FS_User { -// We currently return 0 for success and -1 for failure in cmd_buff[1]. -1 was chosen because it -// puts all the sections of the http://3dbrew.org/wiki/Error_codes to something non-zero, to make -// sure we don't mislead the application into thinking something worked. - -void Initialize(Service::Interface* self) { +static void Initialize(Service::Interface* self) { u32* cmd_buff = Service::GetCommandBuffer(); // TODO(Link Mauve): check the behavior when cmd_buff[1] isn't 32, as per // http://3dbrew.org/wiki/FS:Initialize#Request - cmd_buff[1] = 0; + cmd_buff[1] = RESULT_SUCCESS.raw; DEBUG_LOG(KERNEL, "called"); } -void OpenFile(Service::Interface* self) { +/** + * FS_User::OpenFile service function + * Inputs: + * 1 : Transaction + * 2 : Archive handle lower word + * 3 : Archive handle upper word + * 4 : Low path type + * 5 : Low path size + * 6 : Open flags + * 7 : Attributes + * 8 : (LowPathSize << 14) | 2 + * 9 : Low path data pointer + * Outputs: + * 1 : Result of function, 0 on success, otherwise error code + * 3 : File handle + */ +static void OpenFile(Service::Interface* self) { u32* cmd_buff = Service::GetCommandBuffer(); // TODO(Link Mauve): cmd_buff[2], aka archive handle lower word, isn't used according to @@ -39,36 +53,41 @@ void OpenFile(Service::Interface* self) { FileSys::Mode mode; mode.hex = cmd_buff[6]; u32 attributes = cmd_buff[7]; // TODO(Link Mauve): do something with those attributes. u32 filename_ptr = cmd_buff[9]; - FileSys::Path file_path(filename_type, filename_size, filename_ptr); - std::string file_string; - switch (file_path.GetType()) { - case FileSys::Char: - case FileSys::Wchar: - file_string = file_path.AsString(); - break; - default: - WARN_LOG(KERNEL, "file LowPath type is currently unsupported; returning archive handle instead"); - return; - } - DEBUG_LOG(KERNEL, "type=%d size=%d mode=%d attrs=%d data=%s", - filename_type, filename_size, mode, attributes, file_string.c_str()); + DEBUG_LOG(KERNEL, "path=%s, mode=%d attrs=%u", file_path.DebugStr().c_str(), mode.hex, attributes); - Handle handle = Kernel::OpenFileFromArchive(archive_handle, file_string, mode); - if (handle) { - cmd_buff[1] = 0; - cmd_buff[3] = handle; + ResultVal<Handle> handle = Kernel::OpenFileFromArchive(archive_handle, file_path, mode); + cmd_buff[1] = handle.Code().raw; + if (handle.Succeeded()) { + cmd_buff[3] = *handle; } else { - ERROR_LOG(KERNEL, "failed to get a handle for file %s", file_string.c_str()); - // TODO(Link Mauve): check for the actual error values, this one was just chosen arbitrarily. - cmd_buff[1] = -1; + ERROR_LOG(KERNEL, "failed to get a handle for file %s", file_path.DebugStr().c_str()); } DEBUG_LOG(KERNEL, "called"); } -void OpenFileDirectly(Service::Interface* self) { +/** + * FS_User::OpenFileDirectly service function + * Inputs: + * 1 : Transaction + * 2 : Archive ID + * 3 : Archive low path type + * 4 : Archive low path size + * 5 : File low path type + * 6 : File low path size + * 7 : Flags + * 8 : Attributes + * 9 : (ArchiveLowPathSize << 14) | 0x802 + * 10 : Archive low path + * 11 : (FileLowPathSize << 14) | 2 + * 12 : File low path + * Outputs: + * 1 : Result of function, 0 on success, otherwise error code + * 3 : File handle + */ +static void OpenFileDirectly(Service::Interface* self) { u32* cmd_buff = Service::GetCommandBuffer(); auto archive_id = static_cast<FileSys::Archive::IdCode>(cmd_buff[2]); @@ -80,55 +99,103 @@ void OpenFileDirectly(Service::Interface* self) { u32 attributes = cmd_buff[8]; // TODO(Link Mauve): do something with those attributes. u32 archivename_ptr = cmd_buff[10]; u32 filename_ptr = cmd_buff[12]; + FileSys::Path archive_path(archivename_type, archivename_size, archivename_ptr); + FileSys::Path file_path(filename_type, filename_size, filename_ptr); - DEBUG_LOG(KERNEL, "archive_type=%d archive_size=%d file_type=%d file_size=%d file_mode=%d file_attrs=%d", - archivename_type, archivename_size, filename_type, filename_size, mode, attributes); + DEBUG_LOG(KERNEL, "archive_path=%s file_path=%s, mode=%u attributes=%d", + archive_path.DebugStr().c_str(), file_path.DebugStr().c_str(), mode.hex, attributes); - if (archivename_type != FileSys::Empty) { + if (archive_path.GetType() != FileSys::Empty) { ERROR_LOG(KERNEL, "archive LowPath type other than empty is currently unsupported"); - cmd_buff[1] = -1; + cmd_buff[1] = UnimplementedFunction(ErrorModule::FS).raw; return; } - // TODO(Link Mauve): check if we should even get a handle for the archive, and don't leak it. - Handle archive_handle = Kernel::OpenArchive(archive_id); - if (archive_handle) { - cmd_buff[1] = 0; - // cmd_buff[2] isn't used according to 3dmoo's implementation. - cmd_buff[3] = archive_handle; - } else { + // TODO(Link Mauve): Check if we should even get a handle for the archive, and don't leak it + // TODO(yuriks): Why is there all this duplicate (and seemingly useless) code up here? + ResultVal<Handle> archive_handle = Kernel::OpenArchive(archive_id); + cmd_buff[1] = archive_handle.Code().raw; + if (archive_handle.Failed()) { ERROR_LOG(KERNEL, "failed to get a handle for archive"); - // TODO(Link Mauve): check for the actual error values, this one was just chosen arbitrarily. - cmd_buff[1] = -1; - return; - } - - FileSys::Path file_path(filename_type, filename_size, filename_ptr); - std::string file_string; - switch (file_path.GetType()) { - case FileSys::Char: - case FileSys::Wchar: - file_string = file_path.AsString(); - break; - default: - WARN_LOG(KERNEL, "file LowPath type is currently unsupported; returning archive handle instead"); return; } + // cmd_buff[2] isn't used according to 3dmoo's implementation. + cmd_buff[3] = *archive_handle; - Handle handle = Kernel::OpenFileFromArchive(archive_handle, file_string, mode); - if (handle) { - cmd_buff[1] = 0; - cmd_buff[3] = handle; + ResultVal<Handle> handle = Kernel::OpenFileFromArchive(*archive_handle, file_path, mode); + cmd_buff[1] = handle.Code().raw; + if (handle.Succeeded()) { + cmd_buff[3] = *handle; } else { - ERROR_LOG(KERNEL, "failed to get a handle for file %s", file_string.c_str()); - // TODO(Link Mauve): check for the actual error values, this one was just chosen arbitrarily. - cmd_buff[1] = -1; + ERROR_LOG(KERNEL, "failed to get a handle for file %s", file_path.DebugStr().c_str()); } DEBUG_LOG(KERNEL, "called"); } /* + * FS_User::DeleteFile service function + * Inputs: + * 2 : Archive handle lower word + * 3 : Archive handle upper word + * 4 : File path string type + * 5 : File path string size + * 7 : File path string data + * Outputs: + * 1 : Result of function, 0 on success, otherwise error code + */ +void DeleteFile(Service::Interface* self) { + u32* cmd_buff = Service::GetCommandBuffer(); + + // TODO(Link Mauve): cmd_buff[2], aka archive handle lower word, isn't used according to + // 3dmoo's or ctrulib's implementations. Triple check if it's really the case. + Handle archive_handle = static_cast<Handle>(cmd_buff[3]); + auto filename_type = static_cast<FileSys::LowPathType>(cmd_buff[4]); + u32 filename_size = cmd_buff[5]; + u32 filename_ptr = cmd_buff[7]; + + FileSys::Path file_path(filename_type, filename_size, filename_ptr); + + DEBUG_LOG(KERNEL, "type=%d size=%d data=%s", + filename_type, filename_size, file_path.DebugStr().c_str()); + + cmd_buff[1] = Kernel::DeleteFileFromArchive(archive_handle, file_path); + + DEBUG_LOG(KERNEL, "called"); +} + +/* + * FS_User::DeleteDirectory service function + * Inputs: + * 2 : Archive handle lower word + * 3 : Archive handle upper word + * 4 : Directory path string type + * 5 : Directory path string size + * 7 : Directory path string data + * Outputs: + * 1 : Result of function, 0 on success, otherwise error code + */ +void DeleteDirectory(Service::Interface* self) { + u32* cmd_buff = Service::GetCommandBuffer(); + + // TODO(Link Mauve): cmd_buff[2], aka archive handle lower word, isn't used according to + // 3dmoo's or ctrulib's implementations. Triple check if it's really the case. + Handle archive_handle = static_cast<Handle>(cmd_buff[3]); + auto dirname_type = static_cast<FileSys::LowPathType>(cmd_buff[4]); + u32 dirname_size = cmd_buff[5]; + u32 dirname_ptr = cmd_buff[7]; + + FileSys::Path dir_path(dirname_type, dirname_size, dirname_ptr); + + DEBUG_LOG(KERNEL, "type=%d size=%d data=%s", + dirname_type, dirname_size, dir_path.DebugStr().c_str()); + + cmd_buff[1] = Kernel::DeleteDirectoryFromArchive(archive_handle, dir_path); + + DEBUG_LOG(KERNEL, "called"); +} + +/* * FS_User::CreateDirectory service function * Inputs: * 2 : Archive handle lower word @@ -139,7 +206,7 @@ void OpenFileDirectly(Service::Interface* self) { * Outputs: * 1 : Result of function, 0 on success, otherwise error code */ -void CreateDirectory(Service::Interface* self) { +static void CreateDirectory(Service::Interface* self) { u32* cmd_buff = Service::GetCommandBuffer(); // TODO: cmd_buff[2], aka archive handle lower word, isn't used according to @@ -150,25 +217,15 @@ void CreateDirectory(Service::Interface* self) { u32 dirname_ptr = cmd_buff[8]; FileSys::Path dir_path(dirname_type, dirname_size, dirname_ptr); - std::string dir_string; - switch (dir_path.GetType()) { - case FileSys::Char: - case FileSys::Wchar: - dir_string = dir_path.AsString(); - break; - default: - cmd_buff[1] = -1; - return; - } - DEBUG_LOG(KERNEL, "type=%d size=%d data=%s", dirname_type, dirname_size, dir_string.c_str()); + DEBUG_LOG(KERNEL, "type=%d size=%d data=%s", dirname_type, dirname_size, dir_path.DebugStr().c_str()); - cmd_buff[1] = Kernel::CreateDirectoryFromArchive(archive_handle, dir_string); + cmd_buff[1] = Kernel::CreateDirectoryFromArchive(archive_handle, dir_path); DEBUG_LOG(KERNEL, "called"); } -void OpenDirectory(Service::Interface* self) { +static void OpenDirectory(Service::Interface* self) { u32* cmd_buff = Service::GetCommandBuffer(); // TODO(Link Mauve): cmd_buff[2], aka archive handle lower word, isn't used according to @@ -179,57 +236,57 @@ void OpenDirectory(Service::Interface* self) { u32 dirname_ptr = cmd_buff[6]; FileSys::Path dir_path(dirname_type, dirname_size, dirname_ptr); - std::string dir_string; - switch (dir_path.GetType()) { - case FileSys::Char: - case FileSys::Wchar: - dir_string = dir_path.AsString(); - break; - default: - cmd_buff[1] = -1; - return; - } - DEBUG_LOG(KERNEL, "type=%d size=%d data=%s", dirname_type, dirname_size, dir_string.c_str()); + DEBUG_LOG(KERNEL, "type=%d size=%d data=%s", dirname_type, dirname_size, dir_path.DebugStr().c_str()); - Handle handle = Kernel::OpenDirectoryFromArchive(archive_handle, dir_string); - if (handle) { - cmd_buff[1] = 0; - cmd_buff[3] = handle; + ResultVal<Handle> handle = Kernel::OpenDirectoryFromArchive(archive_handle, dir_path); + cmd_buff[1] = handle.Code().raw; + if (handle.Succeeded()) { + cmd_buff[3] = *handle; } else { - ERROR_LOG(KERNEL, "failed to get a handle for directory %s", dir_string.c_str()); - // TODO(Link Mauve): check for the actual error values, this one was just chosen arbitrarily. - cmd_buff[1] = -1; + ERROR_LOG(KERNEL, "failed to get a handle for directory"); } DEBUG_LOG(KERNEL, "called"); } -void OpenArchive(Service::Interface* self) { +/** + * FS_User::OpenArchive service function + * Inputs: + * 1 : Archive ID + * 2 : Archive low path type + * 3 : Archive low path size + * 4 : (LowPathSize << 14) | 2 + * 5 : Archive low path + * Outputs: + * 1 : Result of function, 0 on success, otherwise error code + * 2 : Archive handle lower word (unused) + * 3 : Archive handle upper word (same as file handle) + */ +static void OpenArchive(Service::Interface* self) { u32* cmd_buff = Service::GetCommandBuffer(); - auto archive_id = static_cast<FileSys::Archive::IdCode>(cmd_buff[1]); + auto archive_id = static_cast<FileSys::Archive::IdCode>(cmd_buff[1]); auto archivename_type = static_cast<FileSys::LowPathType>(cmd_buff[2]); - u32 archivename_size = cmd_buff[3]; - u32 archivename_ptr = cmd_buff[5]; + u32 archivename_size = cmd_buff[3]; + u32 archivename_ptr = cmd_buff[5]; + FileSys::Path archive_path(archivename_type, archivename_size, archivename_ptr); - DEBUG_LOG(KERNEL, "type=%d size=%d", archivename_type, archivename_size); + DEBUG_LOG(KERNEL, "archive_path=%s", archive_path.DebugStr().c_str()); - if (archivename_type != FileSys::Empty) { + if (archive_path.GetType() != FileSys::Empty) { ERROR_LOG(KERNEL, "archive LowPath type other than empty is currently unsupported"); - cmd_buff[1] = -1; + cmd_buff[1] = UnimplementedFunction(ErrorModule::FS).raw; return; } - Handle handle = Kernel::OpenArchive(archive_id); - if (handle) { - cmd_buff[1] = 0; + ResultVal<Handle> handle = Kernel::OpenArchive(archive_id); + cmd_buff[1] = handle.Code().raw; + if (handle.Succeeded()) { // cmd_buff[2] isn't used according to 3dmoo's implementation. - cmd_buff[3] = handle; + cmd_buff[3] = *handle; } else { ERROR_LOG(KERNEL, "failed to get a handle for archive"); - // TODO(Link Mauve): check for the actual error values, this one was just chosen arbitrarily. - cmd_buff[1] = -1; } DEBUG_LOG(KERNEL, "called"); @@ -241,12 +298,12 @@ void OpenArchive(Service::Interface* self) { * 1 : Result of function, 0 on success, otherwise error code * 2 : Whether the Sdmc could be detected */ -void IsSdmcDetected(Service::Interface* self) { +static void IsSdmcDetected(Service::Interface* self) { u32* cmd_buff = Service::GetCommandBuffer(); cmd_buff[1] = 0; cmd_buff[2] = Settings::values.use_virtual_sd ? 1 : 0; - + DEBUG_LOG(KERNEL, "called"); } @@ -256,9 +313,9 @@ const Interface::FunctionInfo FunctionTable[] = { {0x08010002, Initialize, "Initialize"}, {0x080201C2, OpenFile, "OpenFile"}, {0x08030204, OpenFileDirectly, "OpenFileDirectly"}, - {0x08040142, nullptr, "DeleteFile"}, + {0x08040142, DeleteFile, "DeleteFile"}, {0x08050244, nullptr, "RenameFile"}, - {0x08060142, nullptr, "DeleteDirectory"}, + {0x08060142, DeleteDirectory, "DeleteDirectory"}, {0x08070142, nullptr, "DeleteDirectoryRecursively"}, {0x08080202, nullptr, "CreateFile"}, {0x08090182, CreateDirectory, "CreateDirectory"}, diff --git a/src/core/hle/service/gsp_gpu.cpp b/src/core/hle/service/gsp_gpu.cpp index 6119e6300..de1bd3f61 100644 --- a/src/core/hle/service/gsp_gpu.cpp +++ b/src/core/hle/service/gsp_gpu.cpp @@ -28,31 +28,26 @@ u32 g_thread_id = 1; ///< Thread index into interrupt relay queue, 1 /// Gets a pointer to a thread command buffer in GSP shared memory static inline u8* GetCommandBuffer(u32 thread_id) { - if (0 == g_shared_memory) - return nullptr; - - return Kernel::GetSharedMemoryPointer(g_shared_memory, - 0x800 + (thread_id * sizeof(CommandBuffer))); + ResultVal<u8*> ptr = Kernel::GetSharedMemoryPointer(g_shared_memory, 0x800 + (thread_id * sizeof(CommandBuffer))); + return ptr.ValueOr(nullptr); } static inline FrameBufferUpdate* GetFrameBufferInfo(u32 thread_id, u32 screen_index) { - if (0 == g_shared_memory) - return nullptr; - _dbg_assert_msg_(GSP, screen_index < 2, "Invalid screen index"); // For each thread there are two FrameBufferUpdate fields u32 offset = 0x200 + (2 * thread_id + screen_index) * sizeof(FrameBufferUpdate); - return (FrameBufferUpdate*)Kernel::GetSharedMemoryPointer(g_shared_memory, offset); + ResultVal<u8*> ptr = Kernel::GetSharedMemoryPointer(g_shared_memory, offset); + return reinterpret_cast<FrameBufferUpdate*>(ptr.ValueOr(nullptr)); } /// Gets a pointer to the interrupt relay queue for a given thread index static inline InterruptRelayQueue* GetInterruptRelayQueue(u32 thread_id) { - return (InterruptRelayQueue*)Kernel::GetSharedMemoryPointer(g_shared_memory, - sizeof(InterruptRelayQueue) * thread_id); + ResultVal<u8*> ptr = Kernel::GetSharedMemoryPointer(g_shared_memory, sizeof(InterruptRelayQueue) * thread_id); + return reinterpret_cast<InterruptRelayQueue*>(ptr.ValueOr(nullptr)); } -void WriteHWRegs(u32 base_address, u32 size_in_bytes, const u32* data) { +static void WriteHWRegs(u32 base_address, u32 size_in_bytes, const u32* data) { // TODO: Return proper error codes if (base_address + size_in_bytes >= 0x420000) { ERROR_LOG(GPU, "Write address out of range! (address=0x%08x, size=0x%08x)", @@ -76,7 +71,7 @@ void WriteHWRegs(u32 base_address, u32 size_in_bytes, const u32* data) { } /// Write a GSP GPU hardware register -void WriteHWRegs(Service::Interface* self) { +static void WriteHWRegs(Service::Interface* self) { u32* cmd_buff = Service::GetCommandBuffer(); u32 reg_addr = cmd_buff[1]; u32 size = cmd_buff[2]; @@ -87,7 +82,7 @@ void WriteHWRegs(Service::Interface* self) { } /// Read a GSP GPU hardware register -void ReadHWRegs(Service::Interface* self) { +static void ReadHWRegs(Service::Interface* self) { u32* cmd_buff = Service::GetCommandBuffer(); u32 reg_addr = cmd_buff[1]; u32 size = cmd_buff[2]; @@ -115,7 +110,7 @@ void ReadHWRegs(Service::Interface* self) { } } -void SetBufferSwap(u32 screen_id, const FrameBufferInfo& info) { +static void SetBufferSwap(u32 screen_id, const FrameBufferInfo& info) { u32 base_address = 0x400000; if (info.active_fb == 0) { WriteHWRegs(base_address + 4 * GPU_REG_INDEX(framebuffer_config[screen_id].address_left1), 4, &info.address_left); @@ -140,7 +135,7 @@ void SetBufferSwap(u32 screen_id, const FrameBufferInfo& info) { * Outputs: * 1: Result code */ -void SetBufferSwap(Service::Interface* self) { +static void SetBufferSwap(Service::Interface* self) { u32* cmd_buff = Service::GetCommandBuffer(); u32 screen_id = cmd_buff[1]; FrameBufferInfo* fb_info = (FrameBufferInfo*)&cmd_buff[2]; @@ -159,7 +154,7 @@ void SetBufferSwap(Service::Interface* self) { * 2 : Thread index into GSP command buffer * 4 : Handle to GSP shared memory */ -void RegisterInterruptRelayQueue(Service::Interface* self) { +static void RegisterInterruptRelayQueue(Service::Interface* self) { u32* cmd_buff = Service::GetCommandBuffer(); u32 flags = cmd_buff[1]; g_interrupt_event = cmd_buff[3]; @@ -202,7 +197,7 @@ void SignalInterrupt(InterruptId interrupt_id) { } /// Executes the next GSP command -void ExecuteCommand(const Command& command, u32 thread_id) { +static void ExecuteCommand(const Command& command, u32 thread_id) { // Utility function to convert register ID to address auto WriteGPURegister = [](u32 id, u32 data) { GPU::Write<u32>(0x1EF00000 + 4 * id, data); @@ -308,7 +303,7 @@ void ExecuteCommand(const Command& command, u32 thread_id) { } /// This triggers handling of the GX command written to the command buffer in shared memory. -void TriggerCmdReqQueue(Service::Interface* self) { +static void TriggerCmdReqQueue(Service::Interface* self) { // Iterate through each thread's command queue... for (unsigned thread_id = 0; thread_id < 0x4; ++thread_id) { diff --git a/src/core/hle/service/hid_user.cpp b/src/core/hle/service/hid_user.cpp index 0eb32ba4a..d29de1a52 100644 --- a/src/core/hle/service/hid_user.cpp +++ b/src/core/hle/service/hid_user.cpp @@ -34,10 +34,7 @@ static s16 next_circle_y = 0; * Gets a pointer to the PadData structure inside HID shared memory */ static inline PadData* GetPadData() { - if (0 == shared_mem) - return nullptr; - - return reinterpret_cast<PadData*>(Kernel::GetSharedMemoryPointer(shared_mem, 0)); + return reinterpret_cast<PadData*>(Kernel::GetSharedMemoryPointer(shared_mem, 0).ValueOr(nullptr)); } /** @@ -47,7 +44,7 @@ static inline PadData* GetPadData() { * * Indicate the circle pad is pushed completely to the edge in 1 of 8 directions. */ -void UpdateNextCirclePadState() { +static void UpdateNextCirclePadState() { static const s16 max_value = 0x9C; next_circle_x = next_state.circle_left ? -max_value : 0x0; next_circle_x += next_state.circle_right ? max_value : 0x0; @@ -155,7 +152,7 @@ void PadUpdateComplete() { * 7 : Gyroscope event * 8 : Event signaled by HID_User */ -void GetIPCHandles(Service::Interface* self) { +static void GetIPCHandles(Service::Interface* self) { u32* cmd_buff = Service::GetCommandBuffer(); cmd_buff[1] = 0; // No error diff --git a/src/core/hle/service/hid_user.h b/src/core/hle/service/hid_user.h index 9f6c4d5ed..5ed97085d 100644 --- a/src/core/hle/service/hid_user.h +++ b/src/core/hle/service/hid_user.h @@ -15,7 +15,7 @@ namespace HID_User { -/** +/** * Structure of a Pad controller state. */ struct PadState { diff --git a/src/core/hle/service/ir_rst.cpp b/src/core/hle/service/ir_rst.cpp new file mode 100644 index 000000000..be15db231 --- /dev/null +++ b/src/core/hle/service/ir_rst.cpp @@ -0,0 +1,36 @@ +// Copyright 2014 Citra Emulator Project +// Licensed under GPLv2 +// Refer to the license.txt file included. + +#include "common/log.h" +#include "core/hle/hle.h" +#include "core/hle/service/ir_rst.h" + +//////////////////////////////////////////////////////////////////////////////////////////////////// +// Namespace IR_RST + +namespace IR_RST { + +const Interface::FunctionInfo FunctionTable[] = { + {0x00010000, nullptr, "GetHandles"}, + {0x00020080, nullptr, "Initialize"}, + {0x00030000, nullptr, "Shutdown"}, + {0x00040000, nullptr, "Unknown"}, + {0x00050000, nullptr, "Unknown"}, + {0x00060000, nullptr, "Unknown"}, + {0x00070080, nullptr, "Unknown"}, + {0x00080000, nullptr, "Unknown"}, + {0x00090000, nullptr, "Unknown"}, +}; + +//////////////////////////////////////////////////////////////////////////////////////////////////// +// Interface class + +Interface::Interface() { + Register(FunctionTable, ARRAY_SIZE(FunctionTable)); +} + +Interface::~Interface() { +} + +} // namespace diff --git a/src/core/hle/service/ir_rst.h b/src/core/hle/service/ir_rst.h new file mode 100644 index 000000000..73effd7e3 --- /dev/null +++ b/src/core/hle/service/ir_rst.h @@ -0,0 +1,27 @@ +// Copyright 2014 Citra Emulator Project +// Licensed under GPLv2 +// Refer to the license.txt file included. + +#pragma once + +#include "core/hle/service/service.h" + +//////////////////////////////////////////////////////////////////////////////////////////////////// +// Namespace IR_RST + +namespace IR_RST { + +class Interface : public Service::Interface { +public: + Interface(); + ~Interface(); + /** + * Gets the string port name used by CTROS for the service + * @return Port name of service + */ + std::string GetPortName() const override { + return "ir:rst"; + } +}; + +} // namespace diff --git a/src/core/hle/service/ir_u.cpp b/src/core/hle/service/ir_u.cpp new file mode 100644 index 000000000..aa9db6f6d --- /dev/null +++ b/src/core/hle/service/ir_u.cpp @@ -0,0 +1,45 @@ +// Copyright 2014 Citra Emulator Project +// Licensed under GPLv2 +// Refer to the license.txt file included. + +#include "common/log.h" +#include "core/hle/hle.h" +#include "core/hle/service/ir_u.h" + +//////////////////////////////////////////////////////////////////////////////////////////////////// +// Namespace IR_U + +namespace IR_U { + +const Interface::FunctionInfo FunctionTable[] = { + {0x00010000, nullptr, "Initialize"}, + {0x00020000, nullptr, "Shutdown"}, + {0x00030042, nullptr, "StartSendTransfer"}, + {0x00040000, nullptr, "WaitSendTransfer"}, + {0x000500C2, nullptr, "StartRecvTransfer"}, + {0x00060000, nullptr, "WaitRecvTransfer"}, + {0x00070080, nullptr, "GetRecvTransferCount"}, + {0x00080000, nullptr, "GetSendState"}, + {0x00090040, nullptr, "SetBitRate"}, + {0x000A0000, nullptr, "GetBitRate"}, + {0x000B0040, nullptr, "SetIRLEDState"}, + {0x000C0000, nullptr, "GetIRLEDRecvState"}, + {0x000D0000, nullptr, "GetSendFinishedEvent"}, + {0x000E0000, nullptr, "GetRecvFinishedEvent"}, + {0x000F0000, nullptr, "GetTransferState"}, + {0x00100000, nullptr, "GetErrorStatus"}, + {0x00110040, nullptr, "SetSleepModeActive"}, + {0x00120040, nullptr, "SetSleepModeState"}, +}; + +//////////////////////////////////////////////////////////////////////////////////////////////////// +// Interface class + +Interface::Interface() { + Register(FunctionTable, ARRAY_SIZE(FunctionTable)); +} + +Interface::~Interface() { +} + +} // namespace diff --git a/src/core/hle/service/ir_u.h b/src/core/hle/service/ir_u.h new file mode 100644 index 000000000..86d98d079 --- /dev/null +++ b/src/core/hle/service/ir_u.h @@ -0,0 +1,27 @@ +// Copyright 2014 Citra Emulator Project +// Licensed under GPLv2 +// Refer to the license.txt file included. + +#pragma once + +#include "core/hle/service/service.h" + +//////////////////////////////////////////////////////////////////////////////////////////////////// +// Namespace IR_U + +namespace IR_U { + +class Interface : public Service::Interface { +public: + Interface(); + ~Interface(); + /** + * Gets the string port name used by CTROS for the service + * @return Port name of service + */ + std::string GetPortName() const override { + return "ir:u"; + } +}; + +} // namespace diff --git a/src/core/hle/service/mic_u.cpp b/src/core/hle/service/mic_u.cpp index 58051f133..d6f30e9ae 100644 --- a/src/core/hle/service/mic_u.cpp +++ b/src/core/hle/service/mic_u.cpp @@ -27,7 +27,7 @@ const Interface::FunctionInfo FunctionTable[] = { {0x000D0040, nullptr, "SetClamp"}, {0x000E0000, nullptr, "GetClamp"}, {0x000F0040, nullptr, "unknown_input1"}, - {0x00100040, nullptr, "unknown_input2"}, + {0x00100040, nullptr, "unknown_input2"}, }; //////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/src/core/hle/service/mic_u.h b/src/core/hle/service/mic_u.h index 72ba048ef..2a495f3a9 100644 --- a/src/core/hle/service/mic_u.h +++ b/src/core/hle/service/mic_u.h @@ -21,7 +21,7 @@ public: * Gets the string port name used by CTROS for the service * @return Port name of service */ - std::string GetPortName() const { + std::string GetPortName() const override { return "mic:u"; } }; diff --git a/src/core/hle/service/nwm_uds.h b/src/core/hle/service/nwm_uds.h index a956ca812..69d2c2002 100644 --- a/src/core/hle/service/nwm_uds.h +++ b/src/core/hle/service/nwm_uds.h @@ -21,7 +21,7 @@ public: * Gets the string port name used by CTROS for the service * @return Port name of service */ - std::string GetPortName() const { + std::string GetPortName() const override { return "nwm:UDS"; } }; diff --git a/src/core/hle/service/pm_app.cpp b/src/core/hle/service/pm_app.cpp new file mode 100644 index 000000000..90e9b1bfa --- /dev/null +++ b/src/core/hle/service/pm_app.cpp @@ -0,0 +1,35 @@ +// Copyright 2014 Citra Emulator Project +// Licensed under GPLv2 +// Refer to the license.txt file included. + +#include "common/log.h" +#include "core/hle/hle.h" +#include "core/hle/service/pm_app.h" + +//////////////////////////////////////////////////////////////////////////////////////////////////// +// Namespace PM_APP + +namespace PM_APP { + +const Interface::FunctionInfo FunctionTable[] = { + {0x00010140, nullptr, "LaunchTitle"}, + {0x00020082, nullptr, "LaunchFIRMSetParams"}, + {0x00030080, nullptr, "TerminateProcesse"}, + {0x00040100, nullptr, "TerminateProcessTID"}, + {0x000500C0, nullptr, "TerminateProcessTID_unknown"}, + {0x00070042, nullptr, "GetFIRMLaunchParams"}, + {0x00080100, nullptr, "GetTitleExheaderFlags"}, + {0x00090042, nullptr, "SetFIRMLaunchParams"}, +}; + +//////////////////////////////////////////////////////////////////////////////////////////////////// +// Interface class + +Interface::Interface() { + Register(FunctionTable, ARRAY_SIZE(FunctionTable)); +} + +Interface::~Interface() { +} + +} // namespace diff --git a/src/core/hle/service/pm_app.h b/src/core/hle/service/pm_app.h new file mode 100644 index 000000000..28c38f582 --- /dev/null +++ b/src/core/hle/service/pm_app.h @@ -0,0 +1,27 @@ +// Copyright 2014 Citra Emulator Project +// Licensed under GPLv2 +// Refer to the license.txt file included. + +#pragma once + +#include "core/hle/service/service.h" + +//////////////////////////////////////////////////////////////////////////////////////////////////// +// Namespace PM_APP + +namespace PM_APP { + +class Interface : public Service::Interface { +public: + Interface(); + ~Interface(); + /** + * Gets the string port name used by CTROS for the service + * @return Port name of service + */ + std::string GetPortName() const override { + return "pm:app"; + } +}; + +} // namespace diff --git a/src/core/hle/service/ptm_u.cpp b/src/core/hle/service/ptm_u.cpp index f6a14d509..d9122dbbc 100644 --- a/src/core/hle/service/ptm_u.cpp +++ b/src/core/hle/service/ptm_u.cpp @@ -17,13 +17,13 @@ const Interface::FunctionInfo FunctionTable[] = { {0x00030000, nullptr, "GetRtcAlarm"}, {0x00040000, nullptr, "CancelRtcAlarm"}, {0x00050000, nullptr, "GetAdapterState"}, - {0x00060000, nullptr, "GetShellState "}, + {0x00060000, nullptr, "GetShellState"}, {0x00070000, nullptr, "GetBatteryLevel"}, {0x00080000, nullptr, "GetBatteryChargeState"}, {0x00090000, nullptr, "GetPedometerState"}, {0x000A0042, nullptr, "GetStepHistoryEntry"}, - {0x000B00C2, nullptr, "GetStepHistory "}, - {0x000C0000, nullptr, "GetTotalStepCount "}, + {0x000B00C2, nullptr, "GetStepHistory"}, + {0x000C0000, nullptr, "GetTotalStepCount"}, {0x000D0040, nullptr, "SetPedometerRecordingMode"}, {0x000E0000, nullptr, "GetPedometerRecordingMode"}, {0x000F0084, nullptr, "GetStepHistoryAll"}, diff --git a/src/core/hle/service/ptm_u.h b/src/core/hle/service/ptm_u.h index 82749fa39..f8d9f57be 100644 --- a/src/core/hle/service/ptm_u.h +++ b/src/core/hle/service/ptm_u.h @@ -21,7 +21,7 @@ public: * Gets the string port name used by CTROS for the service * @return Port name of service */ - std::string GetPortName() const { + std::string GetPortName() const override { return "ptm:u"; } }; diff --git a/src/core/hle/service/service.cpp b/src/core/hle/service/service.cpp index bb0f80e98..fed2268a0 100644 --- a/src/core/hle/service/service.cpp +++ b/src/core/hle/service/service.cpp @@ -7,17 +7,24 @@ #include "core/hle/service/service.h" #include "core/hle/service/ac_u.h" +#include "core/hle/service/am_net.h" #include "core/hle/service/apt_u.h" +#include "core/hle/service/boss_u.h" +#include "core/hle/service/cfg_i.h" #include "core/hle/service/cfg_u.h" +#include "core/hle/service/csnd_snd.h" #include "core/hle/service/dsp_dsp.h" #include "core/hle/service/err_f.h" #include "core/hle/service/fs_user.h" #include "core/hle/service/frd_u.h" #include "core/hle/service/gsp_gpu.h" #include "core/hle/service/hid_user.h" +#include "core/hle/service/ir_rst.h" +#include "core/hle/service/ir_u.h" #include "core/hle/service/mic_u.h" #include "core/hle/service/ndm_u.h" #include "core/hle/service/nwm_uds.h" +#include "core/hle/service/pm_app.h" #include "core/hle/service/ptm_u.h" #include "core/hle/service/soc_u.h" #include "core/hle/service/srv.h" @@ -55,7 +62,7 @@ void Manager::DeleteService(const std::string& port_name) { /// Get a Service Interface from its Handle Interface* Manager::FetchFromHandle(Handle handle) { - return Kernel::g_object_pool.GetFast<Interface>(handle); + return Kernel::g_object_pool.Get<Interface>(handle); } /// Get a Service Interface from its port @@ -74,20 +81,27 @@ Interface* Manager::FetchFromPortName(const std::string& port_name) { /// Initialize ServiceManager void Init() { g_manager = new Manager; - + g_manager->AddService(new SRV::Interface); g_manager->AddService(new AC_U::Interface); + g_manager->AddService(new AM_NET::Interface); g_manager->AddService(new APT_U::Interface); + g_manager->AddService(new BOSS_U::Interface); + g_manager->AddService(new CFG_I::Interface); g_manager->AddService(new CFG_U::Interface); + g_manager->AddService(new CSND_SND::Interface); g_manager->AddService(new DSP_DSP::Interface); g_manager->AddService(new ERR_F::Interface); g_manager->AddService(new FRD_U::Interface); g_manager->AddService(new FS_User::Interface); g_manager->AddService(new GSP_GPU::Interface); g_manager->AddService(new HID_User::Interface); + g_manager->AddService(new IR_RST::Interface); + g_manager->AddService(new IR_U::Interface); g_manager->AddService(new MIC_U::Interface); g_manager->AddService(new NDM_U::Interface); g_manager->AddService(new NWM_UDS::Interface); + g_manager->AddService(new PM_APP::Interface); g_manager->AddService(new PTM_U::Interface); g_manager->AddService(new SOC_U::Interface); g_manager->AddService(new SSL_C::Interface); diff --git a/src/core/hle/service/service.h b/src/core/hle/service/service.h index 2f5a866c9..20e7fb4d3 100644 --- a/src/core/hle/service/service.h +++ b/src/core/hle/service/service.h @@ -38,7 +38,7 @@ class Manager; class Interface : public Kernel::Object { friend class Manager; public: - + std::string GetName() const override { return GetPortName(); } std::string GetTypeName() const override { return GetPortName(); } @@ -75,48 +75,38 @@ public: m_handles.erase(std::remove(m_handles.begin(), m_handles.end(), handle), m_handles.end()); } - /** - * Synchronize kernel object - * @param wait Boolean wait set if current thread should wait as a result of sync operation - * @return Result of operation, 0 on success, otherwise error code - */ - Result SyncRequest(bool* wait) override { + ResultVal<bool> SyncRequest() override { u32* cmd_buff = GetCommandBuffer(); auto itr = m_functions.find(cmd_buff[0]); if (itr == m_functions.end()) { - ERROR_LOG(OSHLE, "unknown/unimplemented function: port=%s, command=0x%08X", + ERROR_LOG(OSHLE, "unknown/unimplemented function: port=%s, command=0x%08X", GetPortName().c_str(), cmd_buff[0]); // TODO(bunnei): Hack - ignore error u32* cmd_buff = Service::GetCommandBuffer(); cmd_buff[1] = 0; - return 0; + return MakeResult<bool>(false); } if (itr->second.func == nullptr) { - ERROR_LOG(OSHLE, "unimplemented function: port=%s, name=%s", + ERROR_LOG(OSHLE, "unimplemented function: port=%s, name=%s", GetPortName().c_str(), itr->second.name.c_str()); // TODO(bunnei): Hack - ignore error u32* cmd_buff = Service::GetCommandBuffer(); cmd_buff[1] = 0; - return 0; - } + return MakeResult<bool>(false); + } itr->second.func(this); - return 0; // TODO: Implement return from actual function + return MakeResult<bool>(false); // TODO: Implement return from actual function } - /** - * Wait for kernel object to synchronize - * @param wait Boolean wait set if current thread should wait as a result of sync operation - * @return Result of operation, 0 on success, otherwise error code - */ - Result WaitSynchronization(bool* wait) override { + ResultVal<bool> WaitSynchronization() override { // TODO(bunnei): ImplementMe ERROR_LOG(OSHLE, "unimplemented function"); - return 0; + return UnimplementedFunction(ErrorModule::OS); } protected: diff --git a/src/core/hle/service/soc_u.h b/src/core/hle/service/soc_u.h index e27a2b1fe..d5590a683 100644 --- a/src/core/hle/service/soc_u.h +++ b/src/core/hle/service/soc_u.h @@ -19,7 +19,7 @@ public: * Gets the string port name used by CTROS for the service * @return Port name of service */ - std::string GetPortName() const { + std::string GetPortName() const override { return "soc:U"; } }; diff --git a/src/core/hle/service/srv.cpp b/src/core/hle/service/srv.cpp index 6c02a43d9..0e7fa9e3b 100644 --- a/src/core/hle/service/srv.cpp +++ b/src/core/hle/service/srv.cpp @@ -11,9 +11,9 @@ namespace SRV { -Handle g_event_handle = 0; +static Handle g_event_handle = 0; -void Initialize(Service::Interface* self) { +static void Initialize(Service::Interface* self) { DEBUG_LOG(OSHLE, "called"); u32* cmd_buff = Service::GetCommandBuffer(); @@ -21,7 +21,7 @@ void Initialize(Service::Interface* self) { cmd_buff[1] = 0; // No error } -void GetProcSemaphore(Service::Interface* self) { +static void GetProcSemaphore(Service::Interface* self) { DEBUG_LOG(OSHLE, "called"); u32* cmd_buff = Service::GetCommandBuffer(); @@ -34,8 +34,8 @@ void GetProcSemaphore(Service::Interface* self) { cmd_buff[3] = g_event_handle; } -void GetServiceHandle(Service::Interface* self) { - Result res = 0; +static void GetServiceHandle(Service::Interface* self) { + ResultCode res = RESULT_SUCCESS; u32* cmd_buff = Service::GetCommandBuffer(); std::string port_name = std::string((const char*)&cmd_buff[1], 0, Service::kMaxPortSize); @@ -46,9 +46,9 @@ void GetServiceHandle(Service::Interface* self) { DEBUG_LOG(OSHLE, "called port=%s, handle=0x%08X", port_name.c_str(), cmd_buff[3]); } else { ERROR_LOG(OSHLE, "(UNIMPLEMENTED) called port=%s", port_name.c_str()); - res = -1; + res = UnimplementedFunction(ErrorModule::SRV); } - cmd_buff[1] = res; + cmd_buff[1] = res.raw; } const Interface::FunctionInfo FunctionTable[] = { |