mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2024-12-28 18:46:06 +00:00
core/fs: fix file path when using separated update folder for *nix (#1403)
This commit is contained in:
parent
181b005636
commit
ddc35639a8
|
@ -28,16 +28,11 @@ void MntPoints::UnmountAll() {
|
||||||
m_mnt_pairs.clear();
|
m_mnt_pairs.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::filesystem::path MntPoints::GetHostPath(std::string_view guest_directory, bool* is_read_only) {
|
std::filesystem::path MntPoints::GetHostPath(std::string_view path, bool* is_read_only) {
|
||||||
// Evil games like Turok2 pass double slashes e.g /app0//game.kpf
|
// Evil games like Turok2 pass double slashes e.g /app0//game.kpf
|
||||||
std::string corrected_path(guest_directory);
|
const auto normalized_path = std::filesystem::path(path).lexically_normal().string();
|
||||||
size_t pos = corrected_path.find("//");
|
|
||||||
while (pos != std::string::npos) {
|
|
||||||
corrected_path.replace(pos, 2, "/");
|
|
||||||
pos = corrected_path.find("//", pos + 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
const MntPair* mount = GetMount(corrected_path);
|
const MntPair* mount = GetMount(normalized_path);
|
||||||
if (!mount) {
|
if (!mount) {
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
@ -47,26 +42,27 @@ std::filesystem::path MntPoints::GetHostPath(std::string_view guest_directory, b
|
||||||
}
|
}
|
||||||
|
|
||||||
// Nothing to do if getting the mount itself.
|
// Nothing to do if getting the mount itself.
|
||||||
if (corrected_path == mount->mount) {
|
if (normalized_path == mount->mount) {
|
||||||
return mount->host_path;
|
return mount->host_path;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove device (e.g /app0) from path to retrieve relative path.
|
// Remove device (e.g /app0) from path to retrieve relative path.
|
||||||
pos = mount->mount.size() + 1;
|
const auto rel_path = std::string_view{normalized_path}.substr(mount->mount.size() + 1);
|
||||||
const auto rel_path = std::string_view(corrected_path).substr(pos);
|
|
||||||
std::filesystem::path host_path = mount->host_path / rel_path;
|
std::filesystem::path host_path = mount->host_path / rel_path;
|
||||||
|
|
||||||
std::filesystem::path patch_path = mount->host_path;
|
std::filesystem::path patch_path = mount->host_path;
|
||||||
patch_path += "-UPDATE";
|
patch_path += "-UPDATE";
|
||||||
if ((corrected_path.starts_with("/app0") || corrected_path.starts_with("/hostapp")) &&
|
patch_path /= rel_path;
|
||||||
std::filesystem::exists(patch_path / rel_path)) {
|
|
||||||
host_path = patch_path / rel_path;
|
if ((normalized_path.starts_with("/app0") || normalized_path.starts_with("/hostapp")) &&
|
||||||
|
std::filesystem::exists(patch_path)) {
|
||||||
|
return patch_path;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!NeedsCaseInsensitiveSearch) {
|
if (!NeedsCaseInsensitiveSearch) {
|
||||||
return host_path;
|
return host_path;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const auto search = [&](const auto host_path) {
|
||||||
// If the path does not exist attempt to verify this.
|
// If the path does not exist attempt to verify this.
|
||||||
// Retrieve parent path until we find one that exists.
|
// Retrieve parent path until we find one that exists.
|
||||||
std::scoped_lock lk{m_mutex};
|
std::scoped_lock lk{m_mutex};
|
||||||
|
@ -81,7 +77,6 @@ std::filesystem::path MntPoints::GetHostPath(std::string_view guest_directory, b
|
||||||
path_parts.emplace_back(current_path.filename());
|
path_parts.emplace_back(current_path.filename());
|
||||||
current_path = current_path.parent_path();
|
current_path = current_path.parent_path();
|
||||||
}
|
}
|
||||||
|
|
||||||
// We have found an anchor. Traverse parts we recoded and see if they
|
// We have found an anchor. Traverse parts we recoded and see if they
|
||||||
// exist in filesystem but in different case.
|
// exist in filesystem but in different case.
|
||||||
auto guest_path = current_path;
|
auto guest_path = current_path;
|
||||||
|
@ -93,7 +88,6 @@ std::filesystem::path MntPoints::GetHostPath(std::string_view guest_directory, b
|
||||||
path_cache[guest_path] = current_path;
|
path_cache[guest_path] = current_path;
|
||||||
path_parts.pop_back();
|
path_parts.pop_back();
|
||||||
};
|
};
|
||||||
|
|
||||||
// Can happen when the mismatch is in upper folder.
|
// Can happen when the mismatch is in upper folder.
|
||||||
if (std::filesystem::exists(current_path / part)) {
|
if (std::filesystem::exists(current_path / part)) {
|
||||||
add_match(part);
|
add_match(part);
|
||||||
|
@ -114,15 +108,23 @@ std::filesystem::path MntPoints::GetHostPath(std::string_view guest_directory, b
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (!found_match) {
|
if (!found_match) {
|
||||||
|
return std::optional<std::filesystem::path>({});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return std::optional<std::filesystem::path>(current_path);
|
||||||
|
};
|
||||||
|
|
||||||
|
if (const auto path = search(patch_path)) {
|
||||||
|
return *path;
|
||||||
|
}
|
||||||
|
if (const auto path = search(host_path)) {
|
||||||
|
return *path;
|
||||||
|
}
|
||||||
|
|
||||||
// Opening the guest path will surely fail but at least gives
|
// Opening the guest path will surely fail but at least gives
|
||||||
// a better error message than the empty path.
|
// a better error message than the empty path.
|
||||||
return host_path;
|
return host_path;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// The path was found.
|
|
||||||
return current_path;
|
|
||||||
}
|
|
||||||
|
|
||||||
int HandleTable::CreateHandle() {
|
int HandleTable::CreateHandle() {
|
||||||
std::scoped_lock lock{m_mutex};
|
std::scoped_lock lock{m_mutex};
|
||||||
|
|
Loading…
Reference in a new issue