diff options
Diffstat (limited to 'src/core/hle/service')
20 files changed, 391 insertions, 205 deletions
diff --git a/src/core/hle/service/acc/acc.cpp b/src/core/hle/service/acc/acc.cpp index 49c09a570..39cd1efc1 100644 --- a/src/core/hle/service/acc/acc.cpp +++ b/src/core/hle/service/acc/acc.cpp @@ -4,9 +4,9 @@ #include <algorithm> #include <array> -#include "common/common_paths.h" #include "common/common_types.h" -#include "common/file_util.h" +#include "common/fs/file.h" +#include "common/fs/path_util.h" #include "common/logging/log.h" #include "common/string_util.h" #include "common/swap.h" @@ -41,9 +41,9 @@ constexpr ResultCode ERR_FAILED_SAVE_DATA{ErrorModule::Account, 100}; // Thumbnails are hard coded to be at least this size constexpr std::size_t THUMBNAIL_SIZE = 0x24000; -static std::string GetImagePath(Common::UUID uuid) { - return Common::FS::GetUserPath(Common::FS::UserPath::NANDDir) + - "/system/save/8000000000000010/su/avators/" + uuid.FormatSwitch() + ".jpg"; +static std::filesystem::path GetImagePath(Common::UUID uuid) { + return Common::FS::GetYuzuPath(Common::FS::YuzuPath::NANDDir) / + fmt::format("system/save/8000000000000010/su/avators/{}.jpg", uuid.FormatSwitch()); } static constexpr u32 SanitizeJPEGSize(std::size_t size) { @@ -328,7 +328,8 @@ protected: IPC::ResponseBuilder rb{ctx, 3}; rb.Push(RESULT_SUCCESS); - const Common::FS::IOFile image(GetImagePath(user_id), "rb"); + const Common::FS::IOFile image(GetImagePath(user_id), Common::FS::FileAccessMode::Read, + Common::FS::FileType::BinaryFile); if (!image.IsOpen()) { LOG_WARNING(Service_ACC, "Failed to load user provided image! Falling back to built-in backup..."); @@ -339,7 +340,10 @@ protected: const u32 size = SanitizeJPEGSize(image.GetSize()); std::vector<u8> buffer(size); - image.ReadBytes(buffer.data(), buffer.size()); + + if (image.Read(buffer) != buffer.size()) { + LOG_ERROR(Service_ACC, "Failed to read all the bytes in the user provided image."); + } ctx.WriteBuffer(buffer); rb.Push<u32>(size); @@ -350,7 +354,8 @@ protected: IPC::ResponseBuilder rb{ctx, 3}; rb.Push(RESULT_SUCCESS); - const Common::FS::IOFile image(GetImagePath(user_id), "rb"); + const Common::FS::IOFile image(GetImagePath(user_id), Common::FS::FileAccessMode::Read, + Common::FS::FileType::BinaryFile); if (!image.IsOpen()) { LOG_WARNING(Service_ACC, @@ -415,10 +420,11 @@ protected: ProfileData data; std::memcpy(&data, user_data.data(), sizeof(ProfileData)); - Common::FS::IOFile image(GetImagePath(user_id), "wb"); + Common::FS::IOFile image(GetImagePath(user_id), Common::FS::FileAccessMode::Write, + Common::FS::FileType::BinaryFile); - if (!image.IsOpen() || !image.Resize(image_data.size()) || - image.WriteBytes(image_data.data(), image_data.size()) != image_data.size() || + if (!image.IsOpen() || !image.SetSize(image_data.size()) || + image.Write(image_data) != image_data.size() || !profile_manager.SetProfileBaseAndData(user_id, base, data)) { LOG_ERROR(Service_ACC, "Failed to update profile data, base, and image!"); IPC::ResponseBuilder rb{ctx, 2}; diff --git a/src/core/hle/service/acc/profile_manager.cpp b/src/core/hle/service/acc/profile_manager.cpp index de83d82a4..77510489c 100644 --- a/src/core/hle/service/acc/profile_manager.cpp +++ b/src/core/hle/service/acc/profile_manager.cpp @@ -7,7 +7,9 @@ #include <fmt/format.h> -#include "common/file_util.h" +#include "common/fs/file.h" +#include "common/fs/fs.h" +#include "common/fs/path_util.h" #include "common/settings.h" #include "core/hle/service/acc/profile_manager.h" @@ -36,7 +38,7 @@ constexpr ResultCode ERROR_TOO_MANY_USERS(ErrorModule::Account, u32(-1)); constexpr ResultCode ERROR_USER_ALREADY_EXISTS(ErrorModule::Account, u32(-2)); constexpr ResultCode ERROR_ARGUMENT_IS_NULL(ErrorModule::Account, 20); -constexpr char ACC_SAVE_AVATORS_BASE_PATH[] = "/system/save/8000000000000010/su/avators/"; +constexpr char ACC_SAVE_AVATORS_BASE_PATH[] = "system/save/8000000000000010/su/avators"; ProfileManager::ProfileManager() { ParseUserSaveFile(); @@ -325,8 +327,9 @@ bool ProfileManager::SetProfileBaseAndData(Common::UUID uuid, const ProfileBase& } void ProfileManager::ParseUserSaveFile() { - const FS::IOFile save( - FS::GetUserPath(FS::UserPath::NANDDir) + ACC_SAVE_AVATORS_BASE_PATH + "profiles.dat", "rb"); + const auto save_path(FS::GetYuzuPath(FS::YuzuPath::NANDDir) / ACC_SAVE_AVATORS_BASE_PATH / + "profiles.dat"); + const FS::IOFile save(save_path, FS::FileAccessMode::Read, FS::FileType::BinaryFile); if (!save.IsOpen()) { LOG_WARNING(Service_ACC, "Failed to load profile data from save data... Generating new " @@ -335,7 +338,7 @@ void ProfileManager::ParseUserSaveFile() { } ProfileDataRaw data; - if (save.ReadBytes(&data, sizeof(ProfileDataRaw)) != sizeof(ProfileDataRaw)) { + if (!save.ReadObject(data)) { LOG_WARNING(Service_ACC, "profiles.dat is smaller than expected... Generating new user " "'yuzu' with random UUID."); return; @@ -372,31 +375,27 @@ void ProfileManager::WriteUserSaveFile() { }; } - const auto raw_path = FS::GetUserPath(FS::UserPath::NANDDir) + "/system/save/8000000000000010"; - if (FS::Exists(raw_path) && !FS::IsDirectory(raw_path)) { - FS::Delete(raw_path); + const auto raw_path(FS::GetYuzuPath(FS::YuzuPath::NANDDir) / "system/save/8000000000000010"); + if (FS::IsFile(raw_path) && !FS::RemoveFile(raw_path)) { + return; } - const auto path = - FS::GetUserPath(FS::UserPath::NANDDir) + ACC_SAVE_AVATORS_BASE_PATH + "profiles.dat"; + const auto save_path(FS::GetYuzuPath(FS::YuzuPath::NANDDir) / ACC_SAVE_AVATORS_BASE_PATH / + "profiles.dat"); - if (!FS::CreateFullPath(path)) { + if (!FS::CreateParentDirs(save_path)) { LOG_WARNING(Service_ACC, "Failed to create full path of profiles.dat. Create the directory " "nand/system/save/8000000000000010/su/avators to mitigate this " "issue."); return; } - FS::IOFile save(path, "wb"); + FS::IOFile save(save_path, FS::FileAccessMode::Write, FS::FileType::BinaryFile); - if (!save.IsOpen()) { + if (!save.IsOpen() || !save.SetSize(sizeof(ProfileDataRaw)) || !save.WriteObject(raw)) { LOG_WARNING(Service_ACC, "Failed to write save data to file... No changes to user data " "made in current session will be saved."); - return; } - - save.Resize(sizeof(ProfileDataRaw)); - save.WriteBytes(&raw, sizeof(ProfileDataRaw)); } }; // namespace Service::Account diff --git a/src/core/hle/service/am/applets/software_keyboard.cpp b/src/core/hle/service/am/applets/software_keyboard.cpp index b05a5da04..b1a81810b 100644 --- a/src/core/hle/service/am/applets/software_keyboard.cpp +++ b/src/core/hle/service/am/applets/software_keyboard.cpp @@ -273,8 +273,13 @@ void SoftwareKeyboard::ProcessTextCheck() { std::memcpy(&swkbd_text_check, text_check_data.data(), sizeof(SwkbdTextCheck)); - std::u16string text_check_message = Common::UTF16StringFromFixedZeroTerminatedBuffer( - swkbd_text_check.text_check_message.data(), swkbd_text_check.text_check_message.size()); + std::u16string text_check_message = + swkbd_text_check.text_check_result == SwkbdTextCheckResult::Failure || + swkbd_text_check.text_check_result == SwkbdTextCheckResult::Confirm + ? Common::UTF16StringFromFixedZeroTerminatedBuffer( + swkbd_text_check.text_check_message.data(), + swkbd_text_check.text_check_message.size()) + : u""; LOG_INFO(Service_AM, "\nTextCheckResult: {}\nTextCheckMessage: {}", GetTextCheckResultName(swkbd_text_check.text_check_result), @@ -285,10 +290,10 @@ void SoftwareKeyboard::ProcessTextCheck() { SubmitNormalOutputAndExit(SwkbdResult::Ok, current_text); break; case SwkbdTextCheckResult::Failure: - ShowTextCheckDialog(SwkbdTextCheckResult::Failure, text_check_message); + ShowTextCheckDialog(SwkbdTextCheckResult::Failure, std::move(text_check_message)); break; case SwkbdTextCheckResult::Confirm: - ShowTextCheckDialog(SwkbdTextCheckResult::Confirm, text_check_message); + ShowTextCheckDialog(SwkbdTextCheckResult::Confirm, std::move(text_check_message)); break; case SwkbdTextCheckResult::Silent: default: @@ -482,7 +487,7 @@ void SoftwareKeyboard::InitializeFrontendKeyboard() { max_text_length <= 32 ? SwkbdTextDrawType::Line : SwkbdTextDrawType::Box; Core::Frontend::KeyboardInitializeParameters initialize_parameters{ - .ok_text{ok_text}, + .ok_text{std::move(ok_text)}, .header_text{}, .sub_text{}, .guide_text{}, @@ -558,10 +563,10 @@ void SoftwareKeyboard::InitializeFrontendKeyboard() { : false; Core::Frontend::KeyboardInitializeParameters initialize_parameters{ - .ok_text{ok_text}, - .header_text{header_text}, - .sub_text{sub_text}, - .guide_text{guide_text}, + .ok_text{std::move(ok_text)}, + .header_text{std::move(header_text)}, + .sub_text{std::move(sub_text)}, + .guide_text{std::move(guide_text)}, .initial_text{initial_text}, .max_text_length{max_text_length}, .min_text_length{min_text_length}, @@ -590,7 +595,7 @@ void SoftwareKeyboard::ShowNormalKeyboard() { void SoftwareKeyboard::ShowTextCheckDialog(SwkbdTextCheckResult text_check_result, std::u16string text_check_message) { - frontend.ShowTextCheckDialog(text_check_result, text_check_message); + frontend.ShowTextCheckDialog(text_check_result, std::move(text_check_message)); } void SoftwareKeyboard::ShowInlineKeyboard() { diff --git a/src/core/hle/service/am/applets/web_browser.cpp b/src/core/hle/service/am/applets/web_browser.cpp index e5f4a4485..3b28e829b 100644 --- a/src/core/hle/service/am/applets/web_browser.cpp +++ b/src/core/hle/service/am/applets/web_browser.cpp @@ -3,8 +3,9 @@ // Refer to the license.txt file included. #include "common/assert.h" -#include "common/common_paths.h" -#include "common/file_util.h" +#include "common/fs/file.h" +#include "common/fs/fs.h" +#include "common/fs/path_util.h" #include "common/logging/log.h" #include "common/string_util.h" #include "core/core.h" @@ -135,14 +136,10 @@ void ExtractSharedFonts(Core::System& system) { "FontNintendoExtended2.ttf", }; - for (std::size_t i = 0; i < NS::SHARED_FONTS.size(); ++i) { - const auto fonts_dir = Common::FS::SanitizePath( - fmt::format("{}/fonts", Common::FS::GetUserPath(Common::FS::UserPath::CacheDir)), - Common::FS::DirectorySeparator::PlatformDefault); + const auto fonts_dir = Common::FS::GetYuzuPath(Common::FS::YuzuPath::CacheDir) / "fonts"; - const auto font_file_path = - Common::FS::SanitizePath(fmt::format("{}/{}", fonts_dir, DECRYPTED_SHARED_FONTS[i]), - Common::FS::DirectorySeparator::PlatformDefault); + for (std::size_t i = 0; i < NS::SHARED_FONTS.size(); ++i) { + const auto font_file_path = fonts_dir / DECRYPTED_SHARED_FONTS[i]; if (Common::FS::Exists(font_file_path)) { continue; @@ -197,8 +194,8 @@ void ExtractSharedFonts(Core::System& system) { FileSys::VirtualFile decrypted_font = std::make_shared<FileSys::VectorVfsFile>( std::move(decrypted_data), DECRYPTED_SHARED_FONTS[i]); - const auto temp_dir = - system.GetFilesystem()->CreateDirectory(fonts_dir, FileSys::Mode::ReadWrite); + const auto temp_dir = system.GetFilesystem()->CreateDirectory( + Common::FS::PathToUTF8String(fonts_dir), FileSys::Mode::ReadWrite); const auto out_file = temp_dir->CreateFile(DECRYPTED_SHARED_FONTS[i]); @@ -312,13 +309,14 @@ void WebBrowser::Execute() { } void WebBrowser::ExtractOfflineRomFS() { - LOG_DEBUG(Service_AM, "Extracting RomFS to {}", offline_cache_dir); + LOG_DEBUG(Service_AM, "Extracting RomFS to {}", + Common::FS::PathToUTF8String(offline_cache_dir)); const auto extracted_romfs_dir = FileSys::ExtractRomFS(offline_romfs, FileSys::RomFSExtractionType::SingleDiscard); - const auto temp_dir = - system.GetFilesystem()->CreateDirectory(offline_cache_dir, FileSys::Mode::ReadWrite); + const auto temp_dir = system.GetFilesystem()->CreateDirectory( + Common::FS::PathToUTF8String(offline_cache_dir), FileSys::Mode::ReadWrite); FileSys::VfsRawCopyD(extracted_romfs_dir, temp_dir); } @@ -397,15 +395,12 @@ void WebBrowser::InitializeOffline() { "system_data", }; - offline_cache_dir = Common::FS::SanitizePath( - fmt::format("{}/offline_web_applet_{}/{:016X}", - Common::FS::GetUserPath(Common::FS::UserPath::CacheDir), - RESOURCE_TYPES[static_cast<u32>(document_kind) - 1], title_id), - Common::FS::DirectorySeparator::PlatformDefault); + offline_cache_dir = Common::FS::GetYuzuPath(Common::FS::YuzuPath::CacheDir) / + fmt::format("offline_web_applet_{}/{:016X}", + RESOURCE_TYPES[static_cast<u32>(document_kind) - 1], title_id); - offline_document = Common::FS::SanitizePath( - fmt::format("{}/{}/{}", offline_cache_dir, additional_paths, document_path), - Common::FS::DirectorySeparator::PlatformDefault); + offline_document = Common::FS::ConcatPathSafe( + offline_cache_dir, fmt::format("{}/{}", additional_paths, document_path)); } void WebBrowser::InitializeShare() {} @@ -429,8 +424,7 @@ void WebBrowser::ExecuteLogin() { } void WebBrowser::ExecuteOffline() { - const auto main_url = Common::FS::SanitizePath(GetMainURL(offline_document), - Common::FS::DirectorySeparator::PlatformDefault); + const auto main_url = GetMainURL(Common::FS::PathToUTF8String(offline_document)); if (!Common::FS::Exists(main_url)) { offline_romfs = GetOfflineRomFS(system, title_id, nca_type); @@ -444,10 +438,11 @@ void WebBrowser::ExecuteOffline() { } } - LOG_INFO(Service_AM, "Opening offline document at {}", offline_document); + LOG_INFO(Service_AM, "Opening offline document at {}", + Common::FS::PathToUTF8String(offline_document)); frontend.OpenLocalWebPage( - offline_document, [this] { ExtractOfflineRomFS(); }, + Common::FS::PathToUTF8String(offline_document), [this] { ExtractOfflineRomFS(); }, [this](WebExitReason exit_reason, std::string last_url) { WebBrowserExit(exit_reason, last_url); }); diff --git a/src/core/hle/service/am/applets/web_browser.h b/src/core/hle/service/am/applets/web_browser.h index 1e1812f36..cdeaf2c40 100644 --- a/src/core/hle/service/am/applets/web_browser.h +++ b/src/core/hle/service/am/applets/web_browser.h @@ -4,6 +4,7 @@ #pragma once +#include <filesystem> #include <optional> #include "common/common_funcs.h" @@ -75,8 +76,8 @@ private: u64 title_id{}; FileSys::ContentRecordType nca_type{}; - std::string offline_cache_dir; - std::string offline_document; + std::filesystem::path offline_cache_dir; + std::filesystem::path offline_document; FileSys::VirtualFile offline_romfs; std::string external_url; diff --git a/src/core/hle/service/bcat/backend/boxcat.cpp b/src/core/hle/service/bcat/backend/boxcat.cpp index d6d2f52e5..3cc397604 100644 --- a/src/core/hle/service/bcat/backend/boxcat.cpp +++ b/src/core/hle/service/bcat/backend/boxcat.cpp @@ -15,6 +15,9 @@ #pragma GCC diagnostic pop #endif +#include "common/fs/file.h" +#include "common/fs/fs.h" +#include "common/fs/path_util.h" #include "common/hex_util.h" #include "common/logging/backend.h" #include "common/logging/log.h" @@ -96,14 +99,14 @@ constexpr u32 PORT = 443; constexpr u32 TIMEOUT_SECONDS = 30; [[maybe_unused]] constexpr u64 VFS_COPY_BLOCK_SIZE = 1ULL << 24; // 4MB -std::string GetBINFilePath(u64 title_id) { - return fmt::format("{}bcat/{:016X}/launchparam.bin", - Common::FS::GetUserPath(Common::FS::UserPath::CacheDir), title_id); +std::filesystem::path GetBINFilePath(u64 title_id) { + return Common::FS::GetYuzuPath(Common::FS::YuzuPath::CacheDir) / "bcat" / + fmt::format("{:016X}/launchparam.bin", title_id); } -std::string GetZIPFilePath(u64 title_id) { - return fmt::format("{}bcat/{:016X}/data.zip", - Common::FS::GetUserPath(Common::FS::UserPath::CacheDir), title_id); +std::filesystem::path GetZIPFilePath(u64 title_id) { + return Common::FS::GetYuzuPath(Common::FS::YuzuPath::CacheDir) / "bcat" / + fmt::format("{:016X}/data.zip", title_id); } // If the error is something the user should know about (build ID mismatch, bad client version), @@ -187,7 +190,7 @@ bool VfsRawCopyDProgress(FileSys::VirtualDir src, FileSys::VirtualDir dest, class Boxcat::Client { public: - Client(std::string path_, u64 title_id_, u64 build_id_) + Client(std::filesystem::path path_, u64 title_id_, u64 build_id_) : path(std::move(path_)), title_id(title_id_), build_id(build_id_) {} DownloadResult DownloadDataZip() { @@ -217,10 +220,11 @@ private: }; if (Common::FS::Exists(path)) { - Common::FS::IOFile file{path, "rb"}; + Common::FS::IOFile file{path, Common::FS::FileAccessMode::Read, + Common::FS::FileType::BinaryFile}; if (file.IsOpen()) { std::vector<u8> bytes(file.GetSize()); - file.ReadBytes(bytes.data(), bytes.size()); + void(file.Read(bytes)); const auto digest = DigestFile(bytes); headers.insert({std::string("If-None-Match"), Common::HexToString(digest, false)}); } @@ -247,14 +251,23 @@ private: return DownloadResult::InvalidContentType; } - Common::FS::CreateFullPath(path); - Common::FS::IOFile file{path, "wb"}; - if (!file.IsOpen()) + if (!Common::FS::CreateDirs(path)) { return DownloadResult::GeneralFSError; - if (!file.Resize(response->body.size())) + } + + Common::FS::IOFile file{path, Common::FS::FileAccessMode::Append, + Common::FS::FileType::BinaryFile}; + if (!file.IsOpen()) { + return DownloadResult::GeneralFSError; + } + + if (!file.SetSize(response->body.size())) { return DownloadResult::GeneralFSError; - if (file.WriteBytes(response->body.data(), response->body.size()) != response->body.size()) + } + + if (file.Write(response->body) != response->body.size()) { return DownloadResult::GeneralFSError; + } return DownloadResult::Success; } @@ -267,7 +280,7 @@ private: } std::unique_ptr<httplib::SSLClient> client; - std::string path; + std::filesystem::path path; u64 title_id; u64 build_id; }; @@ -291,7 +304,7 @@ void SynchronizeInternal(AM::Applets::AppletManager& applet_manager, DirectoryGe return; } - const auto zip_path{GetZIPFilePath(title.title_id)}; + const auto zip_path = GetZIPFilePath(title.title_id); Boxcat::Client client{zip_path, title.title_id, title.build_id}; progress.StartConnecting(); @@ -301,7 +314,7 @@ void SynchronizeInternal(AM::Applets::AppletManager& applet_manager, DirectoryGe LOG_ERROR(Service_BCAT, "Boxcat synchronization failed with error '{}'!", res); if (res == DownloadResult::NoMatchBuildId || res == DownloadResult::NoMatchTitleId) { - Common::FS::Delete(zip_path); + void(Common::FS::RemoveFile(zip_path)); } HandleDownloadDisplayResult(applet_manager, res); @@ -311,11 +324,13 @@ void SynchronizeInternal(AM::Applets::AppletManager& applet_manager, DirectoryGe progress.StartProcessingDataList(); - Common::FS::IOFile zip{zip_path, "rb"}; + Common::FS::IOFile zip{zip_path, Common::FS::FileAccessMode::Read, + Common::FS::FileType::BinaryFile}; const auto size = zip.GetSize(); std::vector<u8> bytes(size); - if (!zip.IsOpen() || size == 0 || zip.ReadBytes(bytes.data(), bytes.size()) != bytes.size()) { - LOG_ERROR(Service_BCAT, "Boxcat failed to read ZIP file at path '{}'!", zip_path); + if (!zip.IsOpen() || size == 0 || zip.Read(bytes) != bytes.size()) { + LOG_ERROR(Service_BCAT, "Boxcat failed to read ZIP file at path '{}'!", + Common::FS::PathToUTF8String(zip_path)); progress.FinishDownload(ERROR_GENERAL_BCAT_FAILURE); return; } @@ -419,19 +434,19 @@ void Boxcat::SetPassphrase(u64 title_id, const Passphrase& passphrase) { } std::optional<std::vector<u8>> Boxcat::GetLaunchParameter(TitleIDVersion title) { - const auto path{GetBINFilePath(title.title_id)}; + const auto bin_file_path = GetBINFilePath(title.title_id); if (Settings::values.bcat_boxcat_local) { LOG_INFO(Service_BCAT, "Boxcat using local data by override, skipping download."); } else { - Client launch_client{path, title.title_id, title.build_id}; + Client launch_client{bin_file_path, title.title_id, title.build_id}; const auto res = launch_client.DownloadLaunchParam(); if (res != DownloadResult::Success) { LOG_ERROR(Service_BCAT, "Boxcat synchronization failed with error '{}'!", res); if (res == DownloadResult::NoMatchBuildId || res == DownloadResult::NoMatchTitleId) { - Common::FS::Delete(path); + void(Common::FS::RemoveFile(bin_file_path)); } HandleDownloadDisplayResult(applet_manager, res); @@ -439,12 +454,13 @@ std::optional<std::vector<u8>> Boxcat::GetLaunchParameter(TitleIDVersion title) } } - Common::FS::IOFile bin{path, "rb"}; + Common::FS::IOFile bin{bin_file_path, Common::FS::FileAccessMode::Read, + Common::FS::FileType::BinaryFile}; const auto size = bin.GetSize(); std::vector<u8> bytes(size); - if (!bin.IsOpen() || size == 0 || bin.ReadBytes(bytes.data(), bytes.size()) != bytes.size()) { + if (!bin.IsOpen() || size == 0 || bin.Read(bytes) != bytes.size()) { LOG_ERROR(Service_BCAT, "Boxcat failed to read launch parameter binary at path '{}'!", - path); + Common::FS::PathToUTF8String(bin_file_path)); return std::nullopt; } diff --git a/src/core/hle/service/fatal/fatal.cpp b/src/core/hle/service/fatal/fatal.cpp index 432abde76..b7666e95a 100644 --- a/src/core/hle/service/fatal/fatal.cpp +++ b/src/core/hle/service/fatal/fatal.cpp @@ -6,7 +6,6 @@ #include <cstring> #include <ctime> #include <fmt/chrono.h> -#include "common/file_util.h" #include "common/logging/log.h" #include "common/scm_rev.h" #include "common/swap.h" diff --git a/src/core/hle/service/filesystem/filesystem.cpp b/src/core/hle/service/filesystem/filesystem.cpp index 67baaee9b..78664439d 100644 --- a/src/core/hle/service/filesystem/filesystem.cpp +++ b/src/core/hle/service/filesystem/filesystem.cpp @@ -5,7 +5,7 @@ #include <utility> #include "common/assert.h" -#include "common/file_util.h" +#include "common/fs/path_util.h" #include "common/settings.h" #include "core/core.h" #include "core/file_sys/bis_factory.h" @@ -728,14 +728,17 @@ void FileSystemController::CreateFactories(FileSys::VfsFilesystem& vfs, bool ove sdmc_factory = nullptr; } - auto nand_directory = vfs.OpenDirectory(Common::FS::GetUserPath(Common::FS::UserPath::NANDDir), - FileSys::Mode::ReadWrite); - auto sd_directory = vfs.OpenDirectory(Common::FS::GetUserPath(Common::FS::UserPath::SDMCDir), - FileSys::Mode::ReadWrite); - auto load_directory = vfs.OpenDirectory(Common::FS::GetUserPath(Common::FS::UserPath::LoadDir), - FileSys::Mode::ReadWrite); - auto dump_directory = vfs.OpenDirectory(Common::FS::GetUserPath(Common::FS::UserPath::DumpDir), - FileSys::Mode::ReadWrite); + using YuzuPath = Common::FS::YuzuPath; + const auto rw_mode = FileSys::Mode::ReadWrite; + + auto nand_directory = + vfs.OpenDirectory(Common::FS::GetYuzuPathString(YuzuPath::NANDDir), rw_mode); + auto sd_directory = + vfs.OpenDirectory(Common::FS::GetYuzuPathString(YuzuPath::SDMCDir), rw_mode); + auto load_directory = + vfs.OpenDirectory(Common::FS::GetYuzuPathString(YuzuPath::LoadDir), FileSys::Mode::Read); + auto dump_directory = + vfs.OpenDirectory(Common::FS::GetYuzuPathString(YuzuPath::DumpDir), rw_mode); if (bis_factory == nullptr) { bis_factory = diff --git a/src/core/hle/service/hid/controllers/gesture.cpp b/src/core/hle/service/hid/controllers/gesture.cpp index d311f754b..764abb5b6 100644 --- a/src/core/hle/service/hid/controllers/gesture.cpp +++ b/src/core/hle/service/hid/controllers/gesture.cpp @@ -91,8 +91,7 @@ bool Controller_Gesture::ShouldUpdateGesture(const GestureProperties& gesture, // Update if coordinates change for (size_t id = 0; id < MAX_POINTS; id++) { - if (gesture.points[id].x != last_gesture.points[id].x || - gesture.points[id].y != last_gesture.points[id].y) { + if (gesture.points[id] != last_gesture.points[id]) { return true; } } @@ -124,8 +123,7 @@ void Controller_Gesture::UpdateGestureSharedMemory(u8* data, std::size_t size, cur_entry.sampling_number2 = cur_entry.sampling_number; // Reset values to default - cur_entry.delta_x = 0; - cur_entry.delta_y = 0; + cur_entry.delta = {}; cur_entry.vel_x = 0; cur_entry.vel_y = 0; cur_entry.direction = Direction::None; @@ -146,13 +144,9 @@ void Controller_Gesture::UpdateGestureSharedMemory(u8* data, std::size_t size, cur_entry.detection_count = gesture.detection_count; cur_entry.type = type; cur_entry.attributes = attributes; - cur_entry.x = gesture.mid_point.x; - cur_entry.y = gesture.mid_point.y; + cur_entry.pos = gesture.mid_point; cur_entry.point_count = static_cast<s32>(gesture.active_points); - for (size_t id = 0; id < MAX_POINTS; id++) { - cur_entry.points[id].x = gesture.points[id].x; - cur_entry.points[id].y = gesture.points[id].y; - } + cur_entry.points = gesture.points; last_gesture = gesture; std::memcpy(data + SHARED_MEMORY_OFFSET, &shared_memory, sizeof(SharedMemory)); @@ -160,8 +154,8 @@ void Controller_Gesture::UpdateGestureSharedMemory(u8* data, std::size_t size, void Controller_Gesture::NewGesture(GestureProperties& gesture, TouchType& type, Attribute& attributes) { - const auto& last_entry = - shared_memory.gesture_states[(shared_memory.header.last_entry_index + 16) % 17]; + const auto& last_entry = GetLastGestureEntry(); + gesture.detection_count++; type = TouchType::Touch; @@ -174,13 +168,11 @@ void Controller_Gesture::NewGesture(GestureProperties& gesture, TouchType& type, void Controller_Gesture::UpdateExistingGesture(GestureProperties& gesture, TouchType& type, f32 time_difference) { - const auto& last_entry = - shared_memory.gesture_states[(shared_memory.header.last_entry_index + 16) % 17]; + const auto& last_entry = GetLastGestureEntry(); // Promote to pan type if touch moved for (size_t id = 0; id < MAX_POINTS; id++) { - if (gesture.points[id].x != last_gesture.points[id].x || - gesture.points[id].y != last_gesture.points[id].y) { + if (gesture.points[id] != last_gesture.points[id]) { type = TouchType::Pan; break; } @@ -192,10 +184,7 @@ void Controller_Gesture::UpdateExistingGesture(GestureProperties& gesture, Touch enable_press_and_tap = false; gesture.active_points = 0; gesture.mid_point = {}; - for (size_t id = 0; id < MAX_POINTS; id++) { - gesture.points[id].x = 0; - gesture.points[id].y = 0; - } + gesture.points.fill({}); return; } @@ -214,8 +203,8 @@ void Controller_Gesture::UpdateExistingGesture(GestureProperties& gesture, Touch void Controller_Gesture::EndGesture(GestureProperties& gesture, GestureProperties& last_gesture_props, TouchType& type, Attribute& attributes, f32 time_difference) { - const auto& last_entry = - shared_memory.gesture_states[(shared_memory.header.last_entry_index + 16) % 17]; + const auto& last_entry = GetLastGestureEntry(); + if (last_gesture_props.active_points != 0) { switch (last_entry.type) { case TouchType::Touch: @@ -265,13 +254,11 @@ void Controller_Gesture::UpdatePanEvent(GestureProperties& gesture, GestureProperties& last_gesture_props, TouchType& type, f32 time_difference) { auto& cur_entry = shared_memory.gesture_states[shared_memory.header.last_entry_index]; - const auto& last_entry = - shared_memory.gesture_states[(shared_memory.header.last_entry_index + 16) % 17]; - cur_entry.delta_x = gesture.mid_point.x - last_entry.x; - cur_entry.delta_y = gesture.mid_point.y - last_entry.y; + const auto& last_entry = GetLastGestureEntry(); - cur_entry.vel_x = static_cast<f32>(cur_entry.delta_x) / time_difference; - cur_entry.vel_y = static_cast<f32>(cur_entry.delta_y) / time_difference; + cur_entry.delta = gesture.mid_point - last_entry.pos; + cur_entry.vel_x = static_cast<f32>(cur_entry.delta.x) / time_difference; + cur_entry.vel_y = static_cast<f32>(cur_entry.delta.y) / time_difference; last_pan_time_difference = time_difference; // Promote to pinch type @@ -295,12 +282,11 @@ void Controller_Gesture::EndPanEvent(GestureProperties& gesture, GestureProperties& last_gesture_props, TouchType& type, f32 time_difference) { auto& cur_entry = shared_memory.gesture_states[shared_memory.header.last_entry_index]; - const auto& last_entry = - shared_memory.gesture_states[(shared_memory.header.last_entry_index + 16) % 17]; + const auto& last_entry = GetLastGestureEntry(); cur_entry.vel_x = - static_cast<f32>(last_entry.delta_x) / (last_pan_time_difference + time_difference); + static_cast<f32>(last_entry.delta.x) / (last_pan_time_difference + time_difference); cur_entry.vel_y = - static_cast<f32>(last_entry.delta_y) / (last_pan_time_difference + time_difference); + static_cast<f32>(last_entry.delta.y) / (last_pan_time_difference + time_difference); const f32 curr_vel = std::sqrt((cur_entry.vel_x * cur_entry.vel_x) + (cur_entry.vel_y * cur_entry.vel_y)); @@ -320,22 +306,22 @@ void Controller_Gesture::EndPanEvent(GestureProperties& gesture, void Controller_Gesture::SetSwipeEvent(GestureProperties& gesture, GestureProperties& last_gesture_props, TouchType& type) { auto& cur_entry = shared_memory.gesture_states[shared_memory.header.last_entry_index]; - const auto& last_entry = - shared_memory.gesture_states[(shared_memory.header.last_entry_index + 16) % 17]; + const auto& last_entry = GetLastGestureEntry(); + type = TouchType::Swipe; gesture = last_gesture_props; force_update = true; - cur_entry.delta_x = last_entry.delta_x; - cur_entry.delta_y = last_entry.delta_y; - if (std::abs(cur_entry.delta_x) > std::abs(cur_entry.delta_y)) { - if (cur_entry.delta_x > 0) { + cur_entry.delta = last_entry.delta; + + if (std::abs(cur_entry.delta.x) > std::abs(cur_entry.delta.y)) { + if (cur_entry.delta.x > 0) { cur_entry.direction = Direction::Right; return; } cur_entry.direction = Direction::Left; return; } - if (cur_entry.delta_y > 0) { + if (cur_entry.delta.y > 0) { cur_entry.direction = Direction::Down; return; } @@ -364,6 +350,14 @@ std::optional<std::size_t> Controller_Gesture::GetUnusedFingerID() const { return std::nullopt; } +Controller_Gesture::GestureState& Controller_Gesture::GetLastGestureEntry() { + return shared_memory.gesture_states[(shared_memory.header.last_entry_index + 16) % 17]; +} + +const Controller_Gesture::GestureState& Controller_Gesture::GetLastGestureEntry() const { + return shared_memory.gesture_states[(shared_memory.header.last_entry_index + 16) % 17]; +} + std::size_t Controller_Gesture::UpdateTouchInputEvent( const std::tuple<float, float, bool>& touch_input, std::size_t finger_id) { const auto& [x, y, pressed] = touch_input; @@ -381,8 +375,7 @@ std::size_t Controller_Gesture::UpdateTouchInputEvent( finger_id = first_free_id.value(); fingers[finger_id].pressed = true; } - fingers[finger_id].x = x; - fingers[finger_id].y = y; + fingers[finger_id].pos = {x, y}; return finger_id; } @@ -402,17 +395,18 @@ Controller_Gesture::GestureProperties Controller_Gesture::GetGestureProperties() static_cast<std::size_t>(std::distance(active_fingers.begin(), end_iter)); for (size_t id = 0; id < gesture.active_points; ++id) { - gesture.points[id].x = - static_cast<s32>(active_fingers[id].x * Layout::ScreenUndocked::Width); - gesture.points[id].y = - static_cast<s32>(active_fingers[id].y * Layout::ScreenUndocked::Height); + const auto& [active_x, active_y] = active_fingers[id].pos; + gesture.points[id] = { + .x = static_cast<s32>(active_x * Layout::ScreenUndocked::Width), + .y = static_cast<s32>(active_y * Layout::ScreenUndocked::Height), + }; // Hack: There is no touch in docked but games still allow it if (Settings::values.use_docked_mode.GetValue()) { - gesture.points[id].x = - static_cast<s32>(active_fingers[id].x * Layout::ScreenDocked::Width); - gesture.points[id].y = - static_cast<s32>(active_fingers[id].y * Layout::ScreenDocked::Height); + gesture.points[id] = { + .x = static_cast<s32>(active_x * Layout::ScreenDocked::Width), + .y = static_cast<s32>(active_y * Layout::ScreenDocked::Height), + }; } gesture.mid_point.x += static_cast<s32>(gesture.points[id].x / gesture.active_points); diff --git a/src/core/hle/service/hid/controllers/gesture.h b/src/core/hle/service/hid/controllers/gesture.h index f46e29411..7e7ae6625 100644 --- a/src/core/hle/service/hid/controllers/gesture.h +++ b/src/core/hle/service/hid/controllers/gesture.h @@ -7,6 +7,7 @@ #include <array> #include "common/bit_field.h" #include "common/common_types.h" +#include "common/point.h" #include "core/frontend/input.h" #include "core/hle/service/hid/controllers/controller_base.h" @@ -63,29 +64,21 @@ private: }; static_assert(sizeof(Attribute) == 4, "Attribute is an invalid size"); - struct Points { - s32_le x; - s32_le y; - }; - static_assert(sizeof(Points) == 8, "Points is an invalid size"); - struct GestureState { s64_le sampling_number; s64_le sampling_number2; s64_le detection_count; TouchType type; Direction direction; - s32_le x; - s32_le y; - s32_le delta_x; - s32_le delta_y; + Common::Point<s32_le> pos; + Common::Point<s32_le> delta; f32 vel_x; f32 vel_y; Attribute attributes; f32 scale; f32 rotation_angle; s32_le point_count; - std::array<Points, 4> points; + std::array<Common::Point<s32_le>, 4> points; }; static_assert(sizeof(GestureState) == 0x68, "GestureState is an invalid size"); @@ -96,15 +89,14 @@ private: static_assert(sizeof(SharedMemory) == 0x708, "SharedMemory is an invalid size"); struct Finger { - f32 x{}; - f32 y{}; + Common::Point<f32> pos{}; bool pressed{}; }; struct GestureProperties { - std::array<Points, MAX_POINTS> points{}; + std::array<Common::Point<s32_le>, MAX_POINTS> points{}; std::size_t active_points{}; - Points mid_point{}; + Common::Point<s32_le> mid_point{}; s64_le detection_count{}; u64_le delta_time{}; f32 average_distance{}; @@ -148,7 +140,11 @@ private: TouchType& type); // Returns an unused finger id, if there is no fingers available std::nullopt is returned. - std::optional<size_t> GetUnusedFingerID() const; + [[nodiscard]] std::optional<size_t> GetUnusedFingerID() const; + + // Retrieves the last gesture entry, as indicated by shared memory indices. + [[nodiscard]] GestureState& GetLastGestureEntry(); + [[nodiscard]] const GestureState& GetLastGestureEntry() const; /** * If the touch is new it tries to assign a new finger id, if there is no fingers available no @@ -166,10 +162,10 @@ private: std::unique_ptr<Input::TouchDevice> touch_mouse_device; std::unique_ptr<Input::TouchDevice> touch_udp_device; std::unique_ptr<Input::TouchDevice> touch_btn_device; - std::array<size_t, MAX_FINGERS> mouse_finger_id; - std::array<size_t, MAX_FINGERS> keyboard_finger_id; - std::array<size_t, MAX_FINGERS> udp_finger_id; - std::array<Finger, MAX_POINTS> fingers; + std::array<size_t, MAX_FINGERS> mouse_finger_id{}; + std::array<size_t, MAX_FINGERS> keyboard_finger_id{}; + std::array<size_t, MAX_FINGERS> udp_finger_id{}; + std::array<Finger, MAX_POINTS> fingers{}; GestureProperties last_gesture{}; s64_le last_update_timestamp{}; s64_le last_tap_timestamp{}; diff --git a/src/core/hle/service/hid/controllers/touchscreen.cpp b/src/core/hle/service/hid/controllers/touchscreen.cpp index ac9112c40..6ef17acc5 100644 --- a/src/core/hle/service/hid/controllers/touchscreen.cpp +++ b/src/core/hle/service/hid/controllers/touchscreen.cpp @@ -74,8 +74,11 @@ void Controller_Touchscreen::OnUpdate(const Core::Timing::CoreTiming& core_timin for (std::size_t id = 0; id < MAX_FINGERS; ++id) { auto& touch_entry = cur_entry.states[id]; if (id < active_fingers_count) { - touch_entry.x = static_cast<u16>(active_fingers[id].x * Layout::ScreenUndocked::Width); - touch_entry.y = static_cast<u16>(active_fingers[id].y * Layout::ScreenUndocked::Height); + const auto& [active_x, active_y] = active_fingers[id].position; + touch_entry.position = { + .x = static_cast<u16>(active_x * Layout::ScreenUndocked::Width), + .y = static_cast<u16>(active_y * Layout::ScreenUndocked::Height), + }; touch_entry.diameter_x = Settings::values.touchscreen.diameter_x; touch_entry.diameter_y = Settings::values.touchscreen.diameter_y; touch_entry.rotation_angle = Settings::values.touchscreen.rotation_angle; @@ -86,8 +89,7 @@ void Controller_Touchscreen::OnUpdate(const Core::Timing::CoreTiming& core_timin } else { // Clear touch entry touch_entry.attribute.raw = 0; - touch_entry.x = 0; - touch_entry.y = 0; + touch_entry.position = {}; touch_entry.diameter_x = 0; touch_entry.diameter_y = 0; touch_entry.rotation_angle = 0; @@ -140,8 +142,7 @@ std::size_t Controller_Touchscreen::UpdateTouchInputEvent( fingers[finger_id].id = static_cast<u32_le>(finger_id); attribute.start_touch.Assign(1); } - fingers[finger_id].x = x; - fingers[finger_id].y = y; + fingers[finger_id].position = {x, y}; fingers[finger_id].attribute = attribute; return finger_id; } diff --git a/src/core/hle/service/hid/controllers/touchscreen.h b/src/core/hle/service/hid/controllers/touchscreen.h index 2869d0cfd..ef2becefd 100644 --- a/src/core/hle/service/hid/controllers/touchscreen.h +++ b/src/core/hle/service/hid/controllers/touchscreen.h @@ -7,6 +7,7 @@ #include "common/bit_field.h" #include "common/common_funcs.h" #include "common/common_types.h" +#include "common/point.h" #include "common/swap.h" #include "core/frontend/input.h" #include "core/hle/service/hid/controllers/controller_base.h" @@ -55,8 +56,7 @@ private: u64_le delta_time; Attributes attribute; u32_le finger; - u32_le x; - u32_le y; + Common::Point<u32_le> position; u32_le diameter_x; u32_le diameter_y; u32_le rotation_angle; @@ -81,8 +81,7 @@ private: struct Finger { u64_le last_touch{}; - float x{}; - float y{}; + Common::Point<float> position; u32_le id{}; bool pressed{}; Attributes attribute; diff --git a/src/core/hle/service/hid/hid.cpp b/src/core/hle/service/hid/hid.cpp index 49c17fd14..df0fe1c8e 100644 --- a/src/core/hle/service/hid/hid.cpp +++ b/src/core/hle/service/hid/hid.cpp @@ -1770,7 +1770,7 @@ public: {232, nullptr, "GetIrSensorState"}, {233, nullptr, "GetXcdHandleForNpadWithIrSensor"}, {301, nullptr, "ActivateNpadSystem"}, - {303, nullptr, "ApplyNpadSystemCommonPolicy"}, + {303, &HidSys::ApplyNpadSystemCommonPolicy, "ApplyNpadSystemCommonPolicy"}, {304, nullptr, "EnableAssigningSingleOnSlSrPress"}, {305, nullptr, "DisableAssigningSingleOnSlSrPress"}, {306, nullptr, "GetLastActiveNpad"}, @@ -1949,6 +1949,15 @@ public: RegisterHandlers(functions); } + +private: + void ApplyNpadSystemCommonPolicy(Kernel::HLERequestContext& ctx) { + // We already do this for homebrew so we can just stub it out + LOG_WARNING(Service_HID, "called"); + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(RESULT_SUCCESS); + } }; class HidTmp final : public ServiceFramework<HidTmp> { diff --git a/src/core/hle/service/ldn/ldn.cpp b/src/core/hle/service/ldn/ldn.cpp index d160ffe87..c709a8028 100644 --- a/src/core/hle/service/ldn/ldn.cpp +++ b/src/core/hle/service/ldn/ldn.cpp @@ -215,10 +215,151 @@ public: } }; +class INetworkService final : public ServiceFramework<INetworkService> { +public: + explicit INetworkService(Core::System& system_) : ServiceFramework{system_, "INetworkService"} { + // clang-format off + static const FunctionInfo functions[] = { + {0, nullptr, "Initialize"}, + {256, nullptr, "AttachNetworkInterfaceStateChangeEvent"}, + {264, nullptr, "GetNetworkInterfaceLastError"}, + {272, nullptr, "GetRole"}, + {280, nullptr, "GetAdvertiseData"}, + {288, nullptr, "GetGroupInfo"}, + {296, nullptr, "GetGroupInfo2"}, + {304, nullptr, "GetGroupOwner"}, + {312, nullptr, "GetIpConfig"}, + {320, nullptr, "GetLinkLevel"}, + {512, nullptr, "Scan"}, + {768, nullptr, "CreateGroup"}, + {776, nullptr, "DestroyGroup"}, + {784, nullptr, "SetAdvertiseData"}, + {1536, nullptr, "SendToOtherGroup"}, + {1544, nullptr, "RecvFromOtherGroup"}, + {1552, nullptr, "AddAcceptableGroupId"}, + {1560, nullptr, "ClearAcceptableGroupId"}, + }; + // clang-format on + + RegisterHandlers(functions); + } +}; + +class INetworkServiceMonitor final : public ServiceFramework<INetworkServiceMonitor> { +public: + explicit INetworkServiceMonitor(Core::System& system_) + : ServiceFramework{system_, "INetworkServiceMonitor"} { + // clang-format off + static const FunctionInfo functions[] = { + {0, &INetworkServiceMonitor::Initialize, "Initialize"}, + {256, nullptr, "AttachNetworkInterfaceStateChangeEvent"}, + {264, nullptr, "GetNetworkInterfaceLastError"}, + {272, nullptr, "GetRole"}, + {280, nullptr, "GetAdvertiseData"}, + {281, nullptr, "GetAdvertiseData2"}, + {288, nullptr, "GetGroupInfo"}, + {296, nullptr, "GetGroupInfo2"}, + {304, nullptr, "GetGroupOwner"}, + {312, nullptr, "GetIpConfig"}, + {320, nullptr, "GetLinkLevel"}, + {328, nullptr, "AttachJoinEvent"}, + {336, nullptr, "GetMembers"}, + }; + // clang-format on + + RegisterHandlers(functions); + } + + void Initialize(Kernel::HLERequestContext& ctx) { + LOG_WARNING(Service_LDN, "(STUBBED) called"); + + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(ERROR_DISABLED); + } +}; + +class LP2PAPP final : public ServiceFramework<LP2PAPP> { +public: + explicit LP2PAPP(Core::System& system_) : ServiceFramework{system_, "lp2p:app"} { + // clang-format off + static const FunctionInfo functions[] = { + {0, &LP2PAPP::CreateMonitorService, "CreateNetworkService"}, + {8, &LP2PAPP::CreateMonitorService, "CreateNetworkServiceMonitor"}, + }; + // clang-format on + + RegisterHandlers(functions); + } + + void CreateNetworkervice(Kernel::HLERequestContext& ctx) { + IPC::RequestParser rp{ctx}; + const u64 reserved_input = rp.Pop<u64>(); + const u32 input = rp.Pop<u32>(); + + LOG_WARNING(Service_LDN, "(STUBBED) called reserved_input={} input={}", reserved_input, + input); + + IPC::ResponseBuilder rb{ctx, 2, 0, 1}; + rb.Push(RESULT_SUCCESS); + rb.PushIpcInterface<INetworkService>(system); + } + + void CreateMonitorService(Kernel::HLERequestContext& ctx) { + IPC::RequestParser rp{ctx}; + const u64 reserved_input = rp.Pop<u64>(); + + LOG_WARNING(Service_LDN, "(STUBBED) called reserved_input={}", reserved_input); + + IPC::ResponseBuilder rb{ctx, 2, 0, 1}; + rb.Push(RESULT_SUCCESS); + rb.PushIpcInterface<INetworkServiceMonitor>(system); + } +}; + +class LP2PSYS final : public ServiceFramework<LP2PSYS> { +public: + explicit LP2PSYS(Core::System& system_) : ServiceFramework{system_, "lp2p:sys"} { + // clang-format off + static const FunctionInfo functions[] = { + {0, &LP2PSYS::CreateMonitorService, "CreateNetworkService"}, + {8, &LP2PSYS::CreateMonitorService, "CreateNetworkServiceMonitor"}, + }; + // clang-format on + + RegisterHandlers(functions); + } + + void CreateNetworkervice(Kernel::HLERequestContext& ctx) { + IPC::RequestParser rp{ctx}; + const u64 reserved_input = rp.Pop<u64>(); + const u32 input = rp.Pop<u32>(); + + LOG_WARNING(Service_LDN, "(STUBBED) called reserved_input={} input={}", reserved_input, + input); + + IPC::ResponseBuilder rb{ctx, 2, 0, 1}; + rb.Push(RESULT_SUCCESS); + rb.PushIpcInterface<INetworkService>(system); + } + + void CreateMonitorService(Kernel::HLERequestContext& ctx) { + IPC::RequestParser rp{ctx}; + const u64 reserved_input = rp.Pop<u64>(); + + LOG_WARNING(Service_LDN, "(STUBBED) called reserved_input={}", reserved_input); + + IPC::ResponseBuilder rb{ctx, 2, 0, 1}; + rb.Push(RESULT_SUCCESS); + rb.PushIpcInterface<INetworkServiceMonitor>(system); + } +}; + void InstallInterfaces(SM::ServiceManager& sm, Core::System& system) { std::make_shared<LDNM>(system)->InstallAsService(sm); std::make_shared<LDNS>(system)->InstallAsService(sm); std::make_shared<LDNU>(system)->InstallAsService(sm); + std::make_shared<LP2PAPP>(system)->InstallAsService(sm); + std::make_shared<LP2PSYS>(system)->InstallAsService(sm); } } // namespace Service::LDN diff --git a/src/core/hle/service/mii/manager.cpp b/src/core/hle/service/mii/manager.cpp index 70350a2a3..114aff31c 100644 --- a/src/core/hle/service/mii/manager.cpp +++ b/src/core/hle/service/mii/manager.cpp @@ -6,7 +6,6 @@ #include <random> #include "common/assert.h" -#include "common/file_util.h" #include "common/logging/log.h" #include "common/string_util.h" diff --git a/src/core/hle/service/ns/pl_u.cpp b/src/core/hle/service/ns/pl_u.cpp index e14acce58..90ba5c752 100644 --- a/src/core/hle/service/ns/pl_u.cpp +++ b/src/core/hle/service/ns/pl_u.cpp @@ -7,9 +7,7 @@ #include <vector> #include "common/assert.h" -#include "common/common_paths.h" #include "common/common_types.h" -#include "common/file_util.h" #include "common/logging/log.h" #include "common/swap.h" #include "core/core.h" diff --git a/src/core/hle/service/service.cpp b/src/core/hle/service/service.cpp index 2c9b2ce6d..fa61a5c7b 100644 --- a/src/core/hle/service/service.cpp +++ b/src/core/hle/service/service.cpp @@ -107,7 +107,7 @@ void ServiceFrameworkBase::InstallAsService(SM::ServiceManager& service_manager) ASSERT(!port_installed); auto port = service_manager.RegisterService(service_name, max_sessions).Unwrap(); - port->SetHleHandler(shared_from_this()); + port->SetSessionHandler(shared_from_this()); port_installed = true; } @@ -118,7 +118,7 @@ Kernel::KClientPort& ServiceFrameworkBase::CreatePort(Kernel::KernelCore& kernel auto* port = Kernel::KPort::Create(kernel); port->Initialize(max_sessions, false, service_name); - port->GetServerPort().SetHleHandler(shared_from_this()); + port->GetServerPort().SetSessionHandler(shared_from_this()); port_installed = true; diff --git a/src/core/hle/service/sm/controller.cpp b/src/core/hle/service/sm/controller.cpp index de530cbfb..147f12147 100644 --- a/src/core/hle/service/sm/controller.cpp +++ b/src/core/hle/service/sm/controller.cpp @@ -4,8 +4,13 @@ #include "common/assert.h" #include "common/logging/log.h" +#include "core/core.h" #include "core/hle/ipc_helpers.h" +#include "core/hle/kernel/k_client_port.h" #include "core/hle/kernel/k_client_session.h" +#include "core/hle/kernel/k_port.h" +#include "core/hle/kernel/k_scoped_resource_reservation.h" +#include "core/hle/kernel/k_server_port.h" #include "core/hle/kernel/k_server_session.h" #include "core/hle/kernel/k_session.h" #include "core/hle/service/sm/controller.h" @@ -13,7 +18,7 @@ namespace Service::SM { void Controller::ConvertCurrentObjectToDomain(Kernel::HLERequestContext& ctx) { - ASSERT_MSG(ctx.Session()->IsSession(), "Session is already a domain"); + ASSERT_MSG(!ctx.Session()->IsDomain(), "Session is already a domain"); LOG_DEBUG(Service, "called, server_session={}", ctx.Session()->GetId()); ctx.Session()->ConvertToDomain(); @@ -29,16 +34,36 @@ void Controller::CloneCurrentObject(Kernel::HLERequestContext& ctx) { LOG_DEBUG(Service, "called"); - auto session = ctx.Session()->GetParent(); + auto& kernel = system.Kernel(); + auto* session = ctx.Session()->GetParent(); + auto* port = session->GetParent()->GetParent(); - // Open a reference to the session to simulate a new one being created. - session->Open(); - session->GetClientSession().Open(); - session->GetServerSession().Open(); + // Reserve a new session from the process resource limit. + Kernel::KScopedResourceReservation session_reservation( + kernel.CurrentProcess()->GetResourceLimit(), Kernel::LimitableResource::Sessions); + if (!session_reservation.Succeeded()) { + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(Kernel::ResultLimitReached); + } + // Create a new session. + auto* clone = Kernel::KSession::Create(kernel); + clone->Initialize(&port->GetClientPort(), session->GetName()); + + // Commit the session reservation. + session_reservation.Commit(); + + // Enqueue the session with the named port. + port->EnqueueSession(&clone->GetServerSession()); + + // Set the session request manager. + clone->GetServerSession().SetSessionRequestManager( + session->GetServerSession().GetSessionRequestManager()); + + // We succeeded. IPC::ResponseBuilder rb{ctx, 2, 0, 1, IPC::ResponseBuilder::Flags::AlwaysMoveHandles}; rb.Push(RESULT_SUCCESS); - rb.PushMoveObjects(session->GetClientSession()); + rb.PushMoveObjects(clone->GetClientSession()); } void Controller::CloneCurrentObjectEx(Kernel::HLERequestContext& ctx) { diff --git a/src/core/hle/service/sm/sm.cpp b/src/core/hle/service/sm/sm.cpp index 8cc9aee8a..a9bc7da74 100644 --- a/src/core/hle/service/sm/sm.cpp +++ b/src/core/hle/service/sm/sm.cpp @@ -150,31 +150,31 @@ ResultVal<Kernel::KClientSession*> SM::GetServiceImpl(Kernel::HLERequestContext& IPC::RequestParser rp{ctx}; std::string name(PopServiceName(rp)); + // Find the named port. auto result = service_manager.GetServicePort(name); if (result.Failed()) { LOG_ERROR(Service_SM, "called service={} -> error 0x{:08X}", name, result.Code().raw); return result.Code(); } - auto* port = result.Unwrap(); - // Kernel::KScopedResourceReservation session_reservation( - // kernel.CurrentProcess()->GetResourceLimit(), Kernel::LimitableResource::Sessions); - // R_UNLESS(session_reservation.Succeeded(), Kernel::ResultLimitReached); + // Reserve a new session from the process resource limit. + Kernel::KScopedResourceReservation session_reservation( + kernel.CurrentProcess()->GetResourceLimit(), Kernel::LimitableResource::Sessions); + R_UNLESS(session_reservation.Succeeded(), Kernel::ResultLimitReached); + // Create a new session. auto* session = Kernel::KSession::Create(kernel); session->Initialize(&port->GetClientPort(), std::move(name)); // Commit the session reservation. - // session_reservation.Commit(); + session_reservation.Commit(); - if (port->GetServerPort().GetHLEHandler()) { - port->GetServerPort().GetHLEHandler()->ClientConnected(&session->GetServerSession()); - } else { - port->EnqueueSession(&session->GetServerSession()); - } + // Enqueue the session with the named port. + port->EnqueueSession(&session->GetServerSession()); LOG_DEBUG(Service_SM, "called service={} -> session={}", name, session->GetId()); + return MakeResult(&session->GetClientSession()); } diff --git a/src/core/hle/service/sm/sm.h b/src/core/hle/service/sm/sm.h index 60f0b3f8a..ea37f11d4 100644 --- a/src/core/hle/service/sm/sm.h +++ b/src/core/hle/service/sm/sm.h @@ -73,7 +73,7 @@ public: if (port == nullptr) { return nullptr; } - return std::static_pointer_cast<T>(port->GetServerPort().GetHLEHandler()); + return std::static_pointer_cast<T>(port->GetServerPort().GetSessionRequestHandler()); } void InvokeControlRequest(Kernel::HLERequestContext& context); |
