summaryrefslogtreecommitdiffstats
path: root/src/core
diff options
context:
space:
mode:
Diffstat (limited to 'src/core')
-rw-r--r--src/core/file_sys/vfs.cpp46
-rw-r--r--src/core/file_sys/vfs.h20
-rw-r--r--src/core/hle/kernel/svc.cpp2
-rw-r--r--src/core/hle/service/audio/audout_u.cpp4
-rw-r--r--src/core/hle/service/erpt/erpt.cpp12
-rw-r--r--src/core/hle/service/filesystem/filesystem.cpp12
-rw-r--r--src/core/hle/service/filesystem/filesystem.h12
-rw-r--r--src/core/hle/service/filesystem/fsp_srv.cpp12
-rw-r--r--src/core/hle/service/hid/controllers/npad.cpp5
-rw-r--r--src/core/hle/service/set/set.cpp21
-rw-r--r--src/core/hle/service/set/set.h1
-rw-r--r--src/core/hle/service/usb/usb.cpp2
-rw-r--r--src/core/hle/service/vi/vi.cpp2
13 files changed, 133 insertions, 18 deletions
diff --git a/src/core/file_sys/vfs.cpp b/src/core/file_sys/vfs.cpp
index 7b584de7f..e33327ef0 100644
--- a/src/core/file_sys/vfs.cpp
+++ b/src/core/file_sys/vfs.cpp
@@ -384,6 +384,28 @@ bool VfsDirectory::DeleteSubdirectoryRecursive(std::string_view name) {
return success;
}
+bool VfsDirectory::CleanSubdirectoryRecursive(std::string_view name) {
+ auto dir = GetSubdirectory(name);
+ if (dir == nullptr) {
+ return false;
+ }
+
+ bool success = true;
+ for (const auto& file : dir->GetFiles()) {
+ if (!dir->DeleteFile(file->GetName())) {
+ success = false;
+ }
+ }
+
+ for (const auto& sdir : dir->GetSubdirectories()) {
+ if (!dir->DeleteSubdirectoryRecursive(sdir->GetName())) {
+ success = false;
+ }
+ }
+
+ return success;
+}
+
bool VfsDirectory::Copy(std::string_view src, std::string_view dest) {
const auto f1 = GetFile(src);
auto f2 = CreateFile(dest);
@@ -431,10 +453,34 @@ std::shared_ptr<VfsFile> ReadOnlyVfsDirectory::CreateFile(std::string_view name)
return nullptr;
}
+std::shared_ptr<VfsFile> ReadOnlyVfsDirectory::CreateFileAbsolute(std::string_view path) {
+ return nullptr;
+}
+
+std::shared_ptr<VfsFile> ReadOnlyVfsDirectory::CreateFileRelative(std::string_view path) {
+ return nullptr;
+}
+
+std::shared_ptr<VfsDirectory> ReadOnlyVfsDirectory::CreateDirectoryAbsolute(std::string_view path) {
+ return nullptr;
+}
+
+std::shared_ptr<VfsDirectory> ReadOnlyVfsDirectory::CreateDirectoryRelative(std::string_view path) {
+ return nullptr;
+}
+
bool ReadOnlyVfsDirectory::DeleteSubdirectory(std::string_view name) {
return false;
}
+bool ReadOnlyVfsDirectory::DeleteSubdirectoryRecursive(std::string_view name) {
+ return false;
+}
+
+bool ReadOnlyVfsDirectory::CleanSubdirectoryRecursive(std::string_view name) {
+ return false;
+}
+
bool ReadOnlyVfsDirectory::DeleteFile(std::string_view name) {
return false;
}
diff --git a/src/core/file_sys/vfs.h b/src/core/file_sys/vfs.h
index 002f99d4e..e5641b255 100644
--- a/src/core/file_sys/vfs.h
+++ b/src/core/file_sys/vfs.h
@@ -245,12 +245,18 @@ public:
// any failure.
virtual std::shared_ptr<VfsDirectory> CreateDirectoryAbsolute(std::string_view path);
- // Deletes the subdirectory with name and returns true on success.
+ // Deletes the subdirectory with the given name and returns true on success.
virtual bool DeleteSubdirectory(std::string_view name) = 0;
- // Deletes all subdirectories and files of subdirectory with name recirsively and then deletes
- // the subdirectory. Returns true on success.
+
+ // Deletes all subdirectories and files within the provided directory and then deletes
+ // the directory itself. Returns true on success.
virtual bool DeleteSubdirectoryRecursive(std::string_view name);
- // Returnes whether or not the file with name name was deleted successfully.
+
+ // Deletes all subdirectories and files within the provided directory.
+ // Unlike DeleteSubdirectoryRecursive, this does not delete the provided directory.
+ virtual bool CleanSubdirectoryRecursive(std::string_view name);
+
+ // Returns whether or not the file with name name was deleted successfully.
virtual bool DeleteFile(std::string_view name) = 0;
// Returns whether or not this directory was renamed to name.
@@ -276,7 +282,13 @@ public:
bool IsReadable() const override;
std::shared_ptr<VfsDirectory> CreateSubdirectory(std::string_view name) override;
std::shared_ptr<VfsFile> CreateFile(std::string_view name) override;
+ std::shared_ptr<VfsFile> CreateFileAbsolute(std::string_view path) override;
+ std::shared_ptr<VfsFile> CreateFileRelative(std::string_view path) override;
+ std::shared_ptr<VfsDirectory> CreateDirectoryAbsolute(std::string_view path) override;
+ std::shared_ptr<VfsDirectory> CreateDirectoryRelative(std::string_view path) override;
bool DeleteSubdirectory(std::string_view name) override;
+ bool DeleteSubdirectoryRecursive(std::string_view name) override;
+ bool CleanSubdirectoryRecursive(std::string_view name) override;
bool DeleteFile(std::string_view name) override;
bool Rename(std::string_view name) override;
};
diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp
index abc48ee54..051b09d00 100644
--- a/src/core/hle/kernel/svc.cpp
+++ b/src/core/hle/kernel/svc.cpp
@@ -1045,7 +1045,7 @@ static ResultCode CreateThread(Handle* out_handle, VAddr entry_point, u64 arg, V
LOG_TRACE(Kernel_SVC,
"called entrypoint=0x{:08X} ({}), arg=0x{:08X}, stacktop=0x{:08X}, "
"threadpriority=0x{:08X}, processorid=0x{:08X} : created handle=0x{:08X}",
- entry_point, name, arg, stack_top, priority, processor_id, *out_handle);
+ entry_point, arg, stack_top, priority, processor_id, *out_handle);
if (priority > THREADPRIO_LOWEST) {
LOG_ERROR(Kernel_SVC, "An invalid priority was specified, expected {} but got {}",
diff --git a/src/core/hle/service/audio/audout_u.cpp b/src/core/hle/service/audio/audout_u.cpp
index 22e5c85ab..dc6a6b188 100644
--- a/src/core/hle/service/audio/audout_u.cpp
+++ b/src/core/hle/service/audio/audout_u.cpp
@@ -48,8 +48,8 @@ class IAudioOut final : public ServiceFramework<IAudioOut> {
public:
IAudioOut(AudoutParams audio_params, AudioCore::AudioOut& audio_core, std::string&& device_name,
std::string&& unique_name)
- : ServiceFramework("IAudioOut"), audio_core(audio_core), audio_params(audio_params),
- device_name(std::move(device_name)) {
+ : ServiceFramework("IAudioOut"), audio_core(audio_core),
+ device_name(std::move(device_name)), audio_params(audio_params) {
static const FunctionInfo functions[] = {
{0, &IAudioOut::GetAudioOutState, "GetAudioOutState"},
diff --git a/src/core/hle/service/erpt/erpt.cpp b/src/core/hle/service/erpt/erpt.cpp
index ee11cd78e..d9b32954e 100644
--- a/src/core/hle/service/erpt/erpt.cpp
+++ b/src/core/hle/service/erpt/erpt.cpp
@@ -17,11 +17,13 @@ public:
static const FunctionInfo functions[] = {
{0, nullptr, "SubmitContext"},
{1, nullptr, "CreateReport"},
- {2, nullptr, "Unknown1"},
- {3, nullptr, "Unknown2"},
- {4, nullptr, "Unknown3"},
- {5, nullptr, "Unknown4"},
- {6, nullptr, "Unknown5"},
+ {2, nullptr, "SetInitialLaunchSettingsCompletionTime"},
+ {3, nullptr, "ClearInitialLaunchSettingsCompletionTime"},
+ {4, nullptr, "UpdatePowerOnTime"},
+ {5, nullptr, "UpdateAwakeTime"},
+ {6, nullptr, "SubmitMultipleCategoryContext"},
+ {7, nullptr, "UpdateApplicationLaunchTime"},
+ {8, nullptr, "ClearApplicationLaunchTime"},
};
// clang-format on
diff --git a/src/core/hle/service/filesystem/filesystem.cpp b/src/core/hle/service/filesystem/filesystem.cpp
index 2aa77f68d..3bdff4036 100644
--- a/src/core/hle/service/filesystem/filesystem.cpp
+++ b/src/core/hle/service/filesystem/filesystem.cpp
@@ -113,6 +113,18 @@ ResultCode VfsDirectoryServiceWrapper::DeleteDirectoryRecursively(const std::str
return RESULT_SUCCESS;
}
+ResultCode VfsDirectoryServiceWrapper::CleanDirectoryRecursively(const std::string& path) const {
+ const std::string sanitized_path(FileUtil::SanitizePath(path));
+ auto dir = GetDirectoryRelativeWrapped(backing, FileUtil::GetParentPath(sanitized_path));
+
+ if (!dir->CleanSubdirectoryRecursive(FileUtil::GetFilename(sanitized_path))) {
+ // TODO(DarkLordZach): Find a better error code for this
+ return ResultCode(-1);
+ }
+
+ return RESULT_SUCCESS;
+}
+
ResultCode VfsDirectoryServiceWrapper::RenameFile(const std::string& src_path_,
const std::string& dest_path_) const {
std::string src_path(FileUtil::SanitizePath(src_path_));
diff --git a/src/core/hle/service/filesystem/filesystem.h b/src/core/hle/service/filesystem/filesystem.h
index 0a6cb6635..278cf90ab 100644
--- a/src/core/hle/service/filesystem/filesystem.h
+++ b/src/core/hle/service/filesystem/filesystem.h
@@ -114,6 +114,18 @@ public:
ResultCode DeleteDirectoryRecursively(const std::string& path) const;
/**
+ * Cleans the specified directory. This is similar to DeleteDirectoryRecursively,
+ * in that it deletes all the contents of the specified directory, however, this
+ * function does *not* delete the directory itself. It only deletes everything
+ * within it.
+ *
+ * @param path Path relative to the archive.
+ *
+ * @return Result of the operation.
+ */
+ ResultCode CleanDirectoryRecursively(const std::string& path) const;
+
+ /**
* Rename a File specified by its path
* @param src_path Source path relative to the archive
* @param dest_path Destination path relative to the archive
diff --git a/src/core/hle/service/filesystem/fsp_srv.cpp b/src/core/hle/service/filesystem/fsp_srv.cpp
index 99d9ebc39..694ec40ec 100644
--- a/src/core/hle/service/filesystem/fsp_srv.cpp
+++ b/src/core/hle/service/filesystem/fsp_srv.cpp
@@ -291,7 +291,7 @@ public:
{10, &IFileSystem::Commit, "Commit"},
{11, nullptr, "GetFreeSpaceSize"},
{12, nullptr, "GetTotalSpaceSize"},
- {13, nullptr, "CleanDirectoryRecursively"},
+ {13, &IFileSystem::CleanDirectoryRecursively, "CleanDirectoryRecursively"},
{14, nullptr, "GetFileTimeStampRaw"},
{15, nullptr, "QueryEntry"},
};
@@ -361,6 +361,16 @@ public:
rb.Push(backend.DeleteDirectoryRecursively(name));
}
+ void CleanDirectoryRecursively(Kernel::HLERequestContext& ctx) {
+ const auto file_buffer = ctx.ReadBuffer();
+ const std::string name = Common::StringFromBuffer(file_buffer);
+
+ LOG_DEBUG(Service_FS, "called. Directory: {}", name);
+
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(backend.CleanDirectoryRecursively(name));
+ }
+
void RenameFile(Kernel::HLERequestContext& ctx) {
IPC::RequestParser rp{ctx};
diff --git a/src/core/hle/service/hid/controllers/npad.cpp b/src/core/hle/service/hid/controllers/npad.cpp
index 342c2eb81..d6829d0b8 100644
--- a/src/core/hle/service/hid/controllers/npad.cpp
+++ b/src/core/hle/service/hid/controllers/npad.cpp
@@ -520,8 +520,9 @@ Controller_NPad::NpadHoldType Controller_NPad::GetHoldType() const {
}
void Controller_NPad::SetNpadMode(u32 npad_id, NPadAssignments assignment_mode) {
- ASSERT(npad_id < shared_memory_entries.size());
- shared_memory_entries[npad_id].pad_assignment = assignment_mode;
+ const std::size_t npad_index = NPadIdToIndex(npad_id);
+ ASSERT(npad_index < shared_memory_entries.size());
+ shared_memory_entries[npad_index].pad_assignment = assignment_mode;
}
void Controller_NPad::VibrateController(const std::vector<u32>& controller_ids,
diff --git a/src/core/hle/service/set/set.cpp b/src/core/hle/service/set/set.cpp
index 40a9144f9..1afc43f75 100644
--- a/src/core/hle/service/set/set.cpp
+++ b/src/core/hle/service/set/set.cpp
@@ -35,6 +35,8 @@ constexpr std::array<LanguageCode, 17> available_language_codes = {{
constexpr std::size_t pre4_0_0_max_entries = 0xF;
constexpr std::size_t post4_0_0_max_entries = 0x40;
+constexpr ResultCode ERR_INVALID_LANGUAGE{ErrorModule::Settings, 625};
+
LanguageCode GetLanguageCodeFromIndex(std::size_t index) {
return available_language_codes.at(index);
}
@@ -67,6 +69,21 @@ void SET::GetAvailableLanguageCodes(Kernel::HLERequestContext& ctx) {
PushResponseLanguageCode(ctx, pre4_0_0_max_entries);
}
+void SET::MakeLanguageCode(Kernel::HLERequestContext& ctx) {
+ IPC::RequestParser rp{ctx};
+ const auto index = rp.Pop<u32>();
+
+ if (index >= available_language_codes.size()) {
+ IPC::ResponseBuilder rb{ctx, 2};
+ rb.Push(ERR_INVALID_LANGUAGE);
+ return;
+ }
+
+ IPC::ResponseBuilder rb{ctx, 4};
+ rb.Push(RESULT_SUCCESS);
+ rb.PushEnum(available_language_codes[index]);
+}
+
void SET::GetAvailableLanguageCodes2(Kernel::HLERequestContext& ctx) {
LOG_DEBUG(Service_SET, "called");
@@ -95,14 +112,14 @@ void SET::GetLanguageCode(Kernel::HLERequestContext& ctx) {
IPC::ResponseBuilder rb{ctx, 4};
rb.Push(RESULT_SUCCESS);
- rb.Push(static_cast<u64>(available_language_codes[Settings::values.language_index]));
+ rb.PushEnum(available_language_codes[Settings::values.language_index]);
}
SET::SET() : ServiceFramework("set") {
static const FunctionInfo functions[] = {
{0, &SET::GetLanguageCode, "GetLanguageCode"},
{1, &SET::GetAvailableLanguageCodes, "GetAvailableLanguageCodes"},
- {2, nullptr, "MakeLanguageCode"},
+ {2, &SET::MakeLanguageCode, "MakeLanguageCode"},
{3, &SET::GetAvailableLanguageCodeCount, "GetAvailableLanguageCodeCount"},
{4, nullptr, "GetRegionCode"},
{5, &SET::GetAvailableLanguageCodes2, "GetAvailableLanguageCodes2"},
diff --git a/src/core/hle/service/set/set.h b/src/core/hle/service/set/set.h
index 266f13e46..31f9cb296 100644
--- a/src/core/hle/service/set/set.h
+++ b/src/core/hle/service/set/set.h
@@ -38,6 +38,7 @@ public:
private:
void GetLanguageCode(Kernel::HLERequestContext& ctx);
void GetAvailableLanguageCodes(Kernel::HLERequestContext& ctx);
+ void MakeLanguageCode(Kernel::HLERequestContext& ctx);
void GetAvailableLanguageCodes2(Kernel::HLERequestContext& ctx);
void GetAvailableLanguageCodeCount(Kernel::HLERequestContext& ctx);
void GetAvailableLanguageCodeCount2(Kernel::HLERequestContext& ctx);
diff --git a/src/core/hle/service/usb/usb.cpp b/src/core/hle/service/usb/usb.cpp
index f082a63bc..58a9845fc 100644
--- a/src/core/hle/service/usb/usb.cpp
+++ b/src/core/hle/service/usb/usb.cpp
@@ -73,7 +73,7 @@ public:
{3, nullptr, "Populate"},
{4, nullptr, "PostBufferAsync"},
{5, nullptr, "GetXferReport"},
- {6, nullptr, "Unknown2"},
+ {6, nullptr, "PostBufferMultiAsync"},
{7, nullptr, "Unknown3"},
{8, nullptr, "Unknown4"},
};
diff --git a/src/core/hle/service/vi/vi.cpp b/src/core/hle/service/vi/vi.cpp
index 717eae36a..311b0c765 100644
--- a/src/core/hle/service/vi/vi.cpp
+++ b/src/core/hle/service/vi/vi.cpp
@@ -543,6 +543,8 @@ private:
// Repeat TransactParcel DequeueBuffer when a buffer is available
auto buffer_queue = nv_flinger->GetBufferQueue(id);
std::optional<u32> slot = buffer_queue->DequeueBuffer(width, height);
+ ASSERT_MSG(slot != std::nullopt, "Could not dequeue buffer.");
+
IGBPDequeueBufferResponseParcel response{*slot};
ctx.WriteBuffer(response.Serialize());
IPC::ResponseBuilder rb{ctx, 2};