aboutsummaryrefslogtreecommitdiff
path: root/src/core/hle/service
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/hle/service')
-rw-r--r--src/core/hle/service/acc/acc.cpp28
-rw-r--r--src/core/hle/service/acc/profile_manager.cpp33
-rw-r--r--src/core/hle/service/am/applets/software_keyboard.cpp25
-rw-r--r--src/core/hle/service/am/applets/web_browser.cpp47
-rw-r--r--src/core/hle/service/am/applets/web_browser.h5
-rw-r--r--src/core/hle/service/bcat/backend/boxcat.cpp68
-rw-r--r--src/core/hle/service/fatal/fatal.cpp1
-rw-r--r--src/core/hle/service/filesystem/filesystem.cpp21
-rw-r--r--src/core/hle/service/hid/controllers/gesture.cpp92
-rw-r--r--src/core/hle/service/hid/controllers/gesture.h36
-rw-r--r--src/core/hle/service/hid/controllers/touchscreen.cpp13
-rw-r--r--src/core/hle/service/hid/controllers/touchscreen.h7
-rw-r--r--src/core/hle/service/hid/hid.cpp11
-rw-r--r--src/core/hle/service/ldn/ldn.cpp141
-rw-r--r--src/core/hle/service/mii/manager.cpp1
-rw-r--r--src/core/hle/service/ns/pl_u.cpp2
-rw-r--r--src/core/hle/service/service.cpp4
-rw-r--r--src/core/hle/service/sm/controller.cpp39
-rw-r--r--src/core/hle/service/sm/sm.cpp20
-rw-r--r--src/core/hle/service/sm/sm.h2
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);