mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2026-04-26 04:35:24 -06:00
symlinks on *dows
This commit is contained in:
parent
4c5d46f92c
commit
f603db3abb
@ -5,6 +5,7 @@
|
||||
#ifdef _WIN32
|
||||
|
||||
#include <cstdint>
|
||||
#include <unordered_map>
|
||||
#include <fcntl.h>
|
||||
#include <windows.h>
|
||||
|
||||
@ -15,6 +16,9 @@ namespace HostIODriver {
|
||||
|
||||
class HostIO_Win32 final : public HostIO_Base {
|
||||
|
||||
std::unordered_map<fs::path, fs::path> symlinks;
|
||||
fs::path GetSymlink(fs::path path);
|
||||
|
||||
public:
|
||||
//
|
||||
// Conversion helpers
|
||||
@ -50,21 +54,13 @@ public:
|
||||
if (quasi_flags & QUASI_O_APPEND)
|
||||
flags |= _O_APPEND;
|
||||
|
||||
// No info, maybe there are some equivalents
|
||||
// if (quasi_flags & QUASI_O_NONBLOCK)
|
||||
// flags |= _O_NONBLOCK;
|
||||
// if (quasi_flags & QUASI_O_SYNC)
|
||||
// flags |= _O_SYNC;
|
||||
// if (quasi_flags & QUASI_O_FSYNC)
|
||||
// flags |= _O_FSYNC;
|
||||
|
||||
if (quasi_flags & QUASI_O_DIRECTORY)
|
||||
flags |= _O_OBTAIN_DIR; // I don't like how this one looks
|
||||
|
||||
// if (quasi_flags & QUASI_O_DIRECT)
|
||||
// flags |= _O_DIRECT;
|
||||
// if (quasi_flags & QUASI_O_DSYNC)
|
||||
// flags |= _O_DSYNC;
|
||||
if (int status = quasi_flags & (QUASI_O_NONBLOCK | QUASI_O_SYNC | QUASI_O_FSYNC |
|
||||
QUASI_O_DIRECT | QUASI_O_DSYNC);
|
||||
0 != status)
|
||||
LOG_WARNING(Kernel_Fs, "Received unknown or unsupported flags: {:x}", status);
|
||||
|
||||
return flags;
|
||||
}
|
||||
|
||||
@ -12,18 +12,22 @@
|
||||
|
||||
namespace HostIODriver {
|
||||
|
||||
HostIO_Win32::HostIO_Win32() = default;
|
||||
HostIO_Win32::HostIO_Win32() {
|
||||
this->symlinks.clear();
|
||||
this->symlinks.reserve(16);
|
||||
}
|
||||
|
||||
HostIO_Win32::~HostIO_Win32() = default;
|
||||
|
||||
s32 HostIO_Win32::Open(const fs::path& path, s32 flags, u16 mode) {
|
||||
errno = 0;
|
||||
s32 status = _wopen(path.c_str(), ToWIN32OpenFlags(flags), mode);
|
||||
s32 status = _wopen(GetSymlink(path).c_str(), ToWIN32OpenFlags(flags), mode);
|
||||
return status >= 0 ? status : -unix2bsd(errno);
|
||||
}
|
||||
|
||||
s32 HostIO_Win32::Creat(const fs::path& path, u16 mode) {
|
||||
errno = 0;
|
||||
s32 status = _wcreat(path.c_str(), mode);
|
||||
s32 status = _wcreat(GetSymlink(path).c_str(), mode);
|
||||
return status >= 0 ? status : -unix2bsd(errno);
|
||||
}
|
||||
|
||||
@ -35,7 +39,7 @@ s32 HostIO_Win32::Close(const s32 fd) {
|
||||
|
||||
s32 HostIO_Win32::Link(const fs::path& src, const fs::path& dst) {
|
||||
errno = 0;
|
||||
s32 status = CreateHardLinkW(dst.c_str(), src.c_str(), nullptr);
|
||||
s32 status = CreateHardLinkW(dst.c_str(), GetSymlink(src).c_str(), nullptr);
|
||||
return 0 == status ? 0 : -win2bsd(GetLastError());
|
||||
}
|
||||
|
||||
@ -47,14 +51,14 @@ s32 HostIO_Win32::Link(const fs::path& src, const fs::path& dst) {
|
||||
|
||||
s32 HostIO_Win32::Unlink(const fs::path& path) {
|
||||
errno = 0;
|
||||
s32 status = DeleteFileW(path.c_str());
|
||||
s32 status = DeleteFileW(GetSymlink(path).c_str());
|
||||
|
||||
return status > 0 ? status : -win2bsd(GetLastError());
|
||||
}
|
||||
|
||||
s32 HostIO_Win32::Remove(const fs::path& path) {
|
||||
errno = 0;
|
||||
if (int status = DeleteFileW(path.c_str()); status > 0)
|
||||
if (int status = DeleteFileW(GetSymlink(path).c_str()); status > 0)
|
||||
return 0;
|
||||
auto last_error = GetLastError();
|
||||
// no idea if these are correlated (yet)
|
||||
@ -64,7 +68,7 @@ s32 HostIO_Win32::Remove(const fs::path& path) {
|
||||
if (last_error == ERROR_FILE_NOT_FOUND || last_error == ERROR_PATH_NOT_FOUND)
|
||||
return false;
|
||||
|
||||
return RemoveDirectoryW(path.c_str());
|
||||
return RemoveDirectoryW(GetSymlink(path).c_str());
|
||||
}
|
||||
|
||||
s32 HostIO_Win32::Flush(const s32 fd) {
|
||||
@ -90,7 +94,7 @@ s64 HostIO_Win32::Tell(const s32 fd) {
|
||||
|
||||
int HostIO_Win32::Truncate(const fs::path& path, u64 size) {
|
||||
errno = 0;
|
||||
s32 fd = _wopen(path.c_str(), _O_RDONLY);
|
||||
s32 fd = _wopen(GetSymlink(path).c_str(), _O_RDONLY);
|
||||
if (fd < 0)
|
||||
return -unix2bsd(errno);
|
||||
s32 status = _chsize_s(fd, size);
|
||||
@ -158,13 +162,13 @@ s64 HostIO_Win32::PWriteV(const s32 fd, const OrbisKernelIovec* iov, u32 iovcnt,
|
||||
|
||||
s32 HostIO_Win32::MKDir(const fs::path& path, u16 mode) {
|
||||
errno = 0;
|
||||
s32 status = _wmkdir(path.c_str());
|
||||
s32 status = _wmkdir(GetSymlink(path).c_str());
|
||||
return status >= 0 ? status : -unix2bsd(errno);
|
||||
}
|
||||
|
||||
s32 HostIO_Win32::RMDir(const fs::path& path) {
|
||||
errno = 0;
|
||||
s32 status = _wrmdir(path.c_str());
|
||||
s32 status = _wrmdir(GetSymlink(path).c_str());
|
||||
return status >= 0 ? status : -unix2bsd(errno);
|
||||
}
|
||||
|
||||
@ -176,7 +180,7 @@ s32 HostIO_Win32::RMDir(const fs::path& path) {
|
||||
|
||||
s32 HostIO_Win32::Copy(const fs::path& src, const fs::path& dst, bool fail_if_exists) {
|
||||
errno = 0;
|
||||
auto status = CopyFileW(src.c_str(), dst.c_str(), fail_if_exists);
|
||||
auto status = CopyFileW(GetSymlink(src).c_str(), dst.c_str(), fail_if_exists);
|
||||
return status > 0 ? status : -unix2bsd(GetLastError());
|
||||
}
|
||||
|
||||
@ -185,4 +189,15 @@ s32 HostIO_Win32::Move(const fs::path& src, const fs::path& dst, bool fail_if_ex
|
||||
return -unix2bsd(ENOSYS);
|
||||
}
|
||||
|
||||
fs::path HostIO_Win32::GetSymlink(fs::path path) {
|
||||
// this is a very, **very** bad implementation of symlinks
|
||||
// may work for files, but certainly not for directories
|
||||
// in fact, i am terribly ashamed of going this route, but
|
||||
// since games don't use symlinks often, i can get away with this
|
||||
auto sym = this->symlinks.find(path);
|
||||
if (this->symlinks.end() == sym)
|
||||
return path;
|
||||
return sym->second;
|
||||
}
|
||||
|
||||
} // namespace HostIODriver
|
||||
Loading…
Reference in New Issue
Block a user