diff --git a/src/xenia/kernel/xam/content_manager.cc b/src/xenia/kernel/xam/content_manager.cc index 9c08ac737..bdc09af8b 100644 --- a/src/xenia/kernel/xam/content_manager.cc +++ b/src/xenia/kernel/xam/content_manager.cc @@ -15,6 +15,7 @@ #include "xenia/base/filesystem.h" #include "xenia/base/string.h" #include "xenia/kernel/kernel_state.h" +#include "xenia/kernel/xfile.h" #include "xenia/kernel/xobject.h" #include "xenia/vfs/devices/host_path_device.h" @@ -197,6 +198,7 @@ X_RESULT ContentManager::CloseContent(const std::string_view root_name) { if (it == open_packages_.end()) { return X_ERROR_FILE_NOT_FOUND; } + CloseOpenedFilesFromContent(root_name); auto package = it->second; open_packages_.erase(it); @@ -272,6 +274,28 @@ bool ContentManager::IsContentOpen(const ContentData& data) const { }); } +void ContentManager::CloseOpenedFilesFromContent( + const std::string_view root_name) { + // TODO(Gliniak): Cleanup this code to care only about handles + // related to provided content + const std::vector> all_files_handles = + kernel_state_->object_table()->GetObjectsByType( + XObject::Type::File); + + std::string resolved_path = ""; + kernel_state_->file_system()->FindSymbolicLink(std::string(root_name) + ':', + resolved_path); + + for (const object_ref& file : all_files_handles) { + std::string file_path = file->entry()->absolute_path(); + bool is_file_inside_content = utf8::starts_with(file_path, resolved_path); + + if (is_file_inside_content) { + file->ReleaseHandle(); + } + } +} + } // namespace xam } // namespace kernel } // namespace xe diff --git a/src/xenia/kernel/xam/content_manager.h b/src/xenia/kernel/xam/content_manager.h index e6f6f7e12..5eef60b4f 100644 --- a/src/xenia/kernel/xam/content_manager.h +++ b/src/xenia/kernel/xam/content_manager.h @@ -159,6 +159,7 @@ class ContentManager { X_RESULT DeleteContent(const ContentData& data); std::filesystem::path ResolveGameUserContentPath(); bool IsContentOpen(const ContentData& data) const; + void CloseOpenedFilesFromContent(const std::string_view root_name); private: std::filesystem::path ResolvePackageRoot(uint32_t content_type);