From c8b0878352e81dc89a6500437c147a68dcc0715b Mon Sep 17 00:00:00 2001 From: KamFretoZ <14798312+kamfretoz@users.noreply.github.com> Date: Mon, 2 Sep 2024 19:49:09 +0700 Subject: [PATCH] FileSystem: Fix handling of symlinks Revert of https://github.com/PCSX2/pcsx2/pull/11739/commits/c8a3e5a9ec4b41ae8c268de78414942b726c9e1f --- common/FileSystem.cpp | 38 +++++++++++++++++++++++++++++++------- common/FileSystem.h | 1 + 2 files changed, 32 insertions(+), 7 deletions(-) diff --git a/common/FileSystem.cpp b/common/FileSystem.cpp index 31b6a28707200..5bcf03d4a386f 100644 --- a/common/FileSystem.cpp +++ b/common/FileSystem.cpp @@ -1650,6 +1650,21 @@ bool FileSystem::DirectoryExists(const char* path) return false; } +bool FileSystem::IsRealDirectory(const char* path) +{ + // convert to wide string + const std::wstring wpath = GetWin32Path(path); + if (wpath.empty()) + return false; + + // determine attributes for the path. if it's a directory, things have to be handled differently.. + const DWORD fileAttributes = GetFileAttributesW(wpath.c_str()); + if (fileAttributes == INVALID_FILE_ATTRIBUTES) + return false; + + return ((fileAttributes & (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_REPARSE_POINT)) != FILE_ATTRIBUTE_DIRECTORY); +} + bool FileSystem::DirectoryIsEmpty(const char* path) { std::wstring wpath = GetWin32Path(path); @@ -1962,7 +1977,7 @@ static u32 RecursiveFindFiles(const char* OriginPath, const char* ParentPath, co outData.Attributes = 0; struct stat sDir; - if (lstat(full_path.c_str(), &sDir) < 0) + if (stat(full_path.c_str(), &sDir) < 0) continue; if (S_ISDIR(sDir.st_mode)) @@ -2101,7 +2116,7 @@ bool FileSystem::StatFile(const char* path, FILESYSTEM_STAT_DATA* sd) // stat file struct stat sysStatData; - if (lstat(path, &sysStatData) < 0) + if (stat(path, &sysStatData) < 0) return false; // parse attributes @@ -2157,7 +2172,7 @@ bool FileSystem::FileExists(const char* path) // stat file struct stat sysStatData; - if (lstat(path, &sysStatData) < 0) + if (stat(path, &sysStatData) < 0) return false; if (S_ISDIR(sysStatData.st_mode)) @@ -2174,7 +2189,7 @@ bool FileSystem::DirectoryExists(const char* path) // stat file struct stat sysStatData; - if (lstat(path, &sysStatData) < 0) + if (stat(path, &sysStatData) < 0) return false; if (S_ISDIR(sysStatData.st_mode)) @@ -2183,6 +2198,15 @@ bool FileSystem::DirectoryExists(const char* path) return false; } +bool FileSystem::IsRealDirectory(const char* path) +{ + struct stat sysStatData; + if (lstat(path, &sysStatData) < 0) + return false; + + return (S_ISDIR(sysStatData.st_mode) && !S_ISLNK(sysStatData.st_mode)); +} + bool FileSystem::DirectoryIsEmpty(const char* path) { DIR* pDir = opendir(path); @@ -2224,7 +2248,7 @@ bool FileSystem::CreateDirectoryPath(const char* path, bool recursive, Error* er { // check the attributes struct stat sysStatData; - if (lstat(path, &sysStatData) == 0 && S_ISDIR(sysStatData.st_mode)) + if (stat(path, &sysStatData) == 0 && S_ISDIR(sysStatData.st_mode)) return true; } @@ -2294,7 +2318,7 @@ bool FileSystem::DeleteFilePath(const char* path, Error* error) } struct stat sysStatData; - if (lstat(path, &sysStatData) != 0 || S_ISDIR(sysStatData.st_mode)) + if (stat(path, &sysStatData) != 0 || S_ISDIR(sysStatData.st_mode)) { Error::SetStringView(error, "File does not exist."); return false; @@ -2334,7 +2358,7 @@ bool FileSystem::DeleteDirectory(const char* path) return false; struct stat sysStatData; - if (lstat(path, &sysStatData) != 0 || !S_ISDIR(sysStatData.st_mode)) + if (stat(path, &sysStatData) != 0 || !S_ISDIR(sysStatData.st_mode)) return false; return (rmdir(path) == 0); diff --git a/common/FileSystem.h b/common/FileSystem.h index 1b6c89ab082b3..a9bdee5a3bff8 100644 --- a/common/FileSystem.h +++ b/common/FileSystem.h @@ -84,6 +84,7 @@ namespace FileSystem /// Directory exists? bool DirectoryExists(const char* path); + bool IsRealDirectory(const char* path); /// Directory does not contain any files? bool DirectoryIsEmpty(const char* path);