mirror of
https://github.com/shadps4-emu/shadPS4.git
synced 2025-07-12 04:35:56 +00:00
Merge 6277975bc4
into 27cbd6647f
This commit is contained in:
commit
eb00d0f2a5
3 changed files with 71 additions and 6 deletions
|
@ -11,11 +11,11 @@
|
||||||
#include "common/path_util.h"
|
#include "common/path_util.h"
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#include "common/ntapi.h"
|
#include <fcntl.h>
|
||||||
|
|
||||||
#include <io.h>
|
#include <io.h>
|
||||||
#include <share.h>
|
#include <share.h>
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
|
#include "common/ntapi.h"
|
||||||
#else
|
#else
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#endif
|
#endif
|
||||||
|
@ -172,8 +172,11 @@ IOFile& IOFile::operator=(IOFile&& other) noexcept {
|
||||||
|
|
||||||
int IOFile::Open(const fs::path& path, FileAccessMode mode, FileType type, FileShareFlag flag) {
|
int IOFile::Open(const fs::path& path, FileAccessMode mode, FileType type, FileShareFlag flag) {
|
||||||
Close();
|
Close();
|
||||||
|
#ifdef _WIN32
|
||||||
|
file_path = RemoveTrailingSeparator(path);
|
||||||
|
#else
|
||||||
file_path = path;
|
file_path = path;
|
||||||
|
#endif
|
||||||
file_access_mode = mode;
|
file_access_mode = mode;
|
||||||
file_type = type;
|
file_type = type;
|
||||||
|
|
||||||
|
@ -192,11 +195,24 @@ int IOFile::Open(const fs::path& path, FileAccessMode mode, FileType type, FileS
|
||||||
result = errno;
|
result = errno;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
if (!IsOpen()) {
|
||||||
|
#ifdef _WIN32
|
||||||
|
file = OpenDirAsFilePtr(
|
||||||
|
path.c_str(), AccessModeToWStr(mode, type),
|
||||||
|
fs::is_directory(
|
||||||
|
path)); // this can't be used with fread, fwrite etc . Let's hope it will not needed
|
||||||
|
result = errno;
|
||||||
if (!IsOpen()) {
|
if (!IsOpen()) {
|
||||||
const auto ec = std::error_code{result, std::generic_category()};
|
const auto ec = std::error_code{result, std::generic_category()};
|
||||||
LOG_ERROR(Common_Filesystem, "Failed to open the file at path={}, error_message={}",
|
LOG_ERROR(Common_Filesystem, "Failed to open the file at path={}, error_message={}",
|
||||||
PathToUTF8String(file_path), ec.message());
|
PathToUTF8String(file_path), ec.message());
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
const auto ec = std::error_code{result, std::generic_category()};
|
||||||
|
LOG_ERROR(Common_Filesystem, "Failed to open the file at path={}, error_message={}",
|
||||||
|
PathToUTF8String(file_path), ec.message());
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -415,5 +431,44 @@ u64 GetDirectorySize(const std::filesystem::path& path) {
|
||||||
}
|
}
|
||||||
return total;
|
return total;
|
||||||
}
|
}
|
||||||
|
#ifdef _WIN32
|
||||||
|
FILE* OpenDirAsFilePtr(const wchar_t* path, const wchar_t* mode, bool isDirectory = false) {
|
||||||
|
DWORD access = 0;
|
||||||
|
DWORD creation = OPEN_EXISTING;
|
||||||
|
DWORD flags = FILE_ATTRIBUTE_NORMAL;
|
||||||
|
DWORD share = FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE;
|
||||||
|
|
||||||
|
// Handle access based on mode
|
||||||
|
if (wcschr(mode, L'r'))
|
||||||
|
access |= GENERIC_READ;
|
||||||
|
if (wcschr(mode, L'w') || wcschr(mode, L'a'))
|
||||||
|
access |= GENERIC_WRITE;
|
||||||
|
|
||||||
|
// Add backup semantics if this is a directory
|
||||||
|
if (isDirectory) {
|
||||||
|
flags |= FILE_FLAG_BACKUP_SEMANTICS;
|
||||||
|
}
|
||||||
|
|
||||||
|
HANDLE hFile = CreateFileW(path, access, share, nullptr, creation, flags, nullptr);
|
||||||
|
|
||||||
|
if (hFile == INVALID_HANDLE_VALUE) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
int fd = _open_osfhandle((intptr_t)hFile, _O_BINARY);
|
||||||
|
if (fd == -1) {
|
||||||
|
CloseHandle(hFile);
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
FILE* file = _fdopen(fd, (wcschr(mode, L'w') || wcschr(mode, L'a')) ? "wb" : "rb");
|
||||||
|
if (!file) {
|
||||||
|
_close(fd);
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
return file;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
} // namespace Common::FS
|
} // namespace Common::FS
|
||||||
|
|
|
@ -213,7 +213,15 @@ public:
|
||||||
IOFile out(path, FileAccessMode::Write);
|
IOFile out(path, FileAccessMode::Write);
|
||||||
return out.Write(data);
|
return out.Write(data);
|
||||||
}
|
}
|
||||||
|
#ifdef _WIN32
|
||||||
|
std::filesystem::path RemoveTrailingSeparator(const std::filesystem::path& input) {
|
||||||
|
std::wstring str = input.native();
|
||||||
|
while (!str.empty() && (str.back() == L'\\' || str.back() == L'/')) {
|
||||||
|
str.pop_back();
|
||||||
|
}
|
||||||
|
return std::filesystem::path(str);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
private:
|
private:
|
||||||
std::filesystem::path file_path;
|
std::filesystem::path file_path;
|
||||||
FileAccessMode file_access_mode{};
|
FileAccessMode file_access_mode{};
|
||||||
|
@ -224,5 +232,7 @@ private:
|
||||||
};
|
};
|
||||||
|
|
||||||
u64 GetDirectorySize(const std::filesystem::path& path);
|
u64 GetDirectorySize(const std::filesystem::path& path);
|
||||||
|
#ifdef _WIN32
|
||||||
|
FILE* OpenDirAsFilePtr(const wchar_t* path, const wchar_t* mode, bool isDirectory);
|
||||||
|
#endif
|
||||||
} // namespace Common::FS
|
} // namespace Common::FS
|
||||||
|
|
|
@ -168,7 +168,7 @@ s32 PS4_SYSV_ABI open(const char* raw_path, s32 flags, u16 mode) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (e == EACCES) {
|
if (e == EACCES || e == ENOENT) {
|
||||||
// Hack to bypass some platform limitations, ignore the error and continue as normal.
|
// Hack to bypass some platform limitations, ignore the error and continue as normal.
|
||||||
LOG_WARNING(Kernel_Fs, "Opening directories is not fully supported on this platform");
|
LOG_WARNING(Kernel_Fs, "Opening directories is not fully supported on this platform");
|
||||||
e = 0;
|
e = 0;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue