mirror of https://github.com/PCSX2/pcsx2.git
FileSystem: Don't follow symlinks when recursively deleting directories
This commit is contained in:
parent
46d17fcb20
commit
6e4dc1e8ab
|
@ -1225,7 +1225,12 @@ bool FileSystem::RecursiveDeleteDirectory(const char* path)
|
|||
{
|
||||
for (const FILESYSTEM_FIND_DATA& fd : results)
|
||||
{
|
||||
if (fd.Attributes & FILESYSTEM_FILE_ATTRIBUTE_DIRECTORY)
|
||||
if (IsSymbolicLink(fd.FileName.c_str()))
|
||||
{
|
||||
if (!DeleteSymbolicLink(fd.FileName.c_str()))
|
||||
return false;
|
||||
}
|
||||
else if ((fd.Attributes & FILESYSTEM_FILE_ATTRIBUTE_DIRECTORY))
|
||||
{
|
||||
if (!RecursiveDeleteDirectory(fd.FileName.c_str()))
|
||||
return false;
|
||||
|
@ -1650,21 +1655,6 @@ 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);
|
||||
|
@ -1935,6 +1925,52 @@ bool FileSystem::SetPathCompression(const char* path, bool enable)
|
|||
return result;
|
||||
}
|
||||
|
||||
bool FileSystem::IsSymbolicLink(const char* path)
|
||||
{
|
||||
// convert to wide string
|
||||
const std::wstring wpath = GetWin32Path(path);
|
||||
if (wpath.empty())
|
||||
return false;
|
||||
|
||||
// determine attributes for the path
|
||||
const DWORD fileAttributes = GetFileAttributesW(wpath.c_str());
|
||||
if (fileAttributes == INVALID_FILE_ATTRIBUTES)
|
||||
return false;
|
||||
|
||||
return fileAttributes & FILE_ATTRIBUTE_REPARSE_POINT;
|
||||
}
|
||||
|
||||
bool FileSystem::DeleteSymbolicLink(const char* path, Error* error)
|
||||
{
|
||||
// convert to wide string
|
||||
const std::wstring wpath = GetWin32Path(path);
|
||||
if (wpath.empty())
|
||||
{
|
||||
Error::SetStringView(error, "Invalid path.");
|
||||
return false;
|
||||
}
|
||||
|
||||
// delete the symbolic link
|
||||
if (DirectoryExists(path))
|
||||
{
|
||||
if (!RemoveDirectoryW(wpath.c_str()))
|
||||
{
|
||||
Error::SetWin32(error, "RemoveDirectoryW() failed: ", GetLastError());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!DeleteFileW(wpath.c_str()))
|
||||
{
|
||||
Error::SetWin32(error, "DeleteFileW() failed: ", GetLastError());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
// No 32-bit file offsets breaking stuff please.
|
||||
|
@ -2216,15 +2252,6 @@ 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);
|
||||
|
@ -2478,6 +2505,26 @@ bool FileSystem::SetPathCompression(const char* path, bool enable)
|
|||
return false;
|
||||
}
|
||||
|
||||
bool FileSystem::IsSymbolicLink(const char* path)
|
||||
{
|
||||
struct stat sysStatData;
|
||||
if (lstat(path, &sysStatData) < 0)
|
||||
return false;
|
||||
|
||||
return S_ISLNK(sysStatData.st_mode);
|
||||
}
|
||||
|
||||
bool FileSystem::DeleteSymbolicLink(const char* path, Error* error)
|
||||
{
|
||||
if (unlink(path) != 0)
|
||||
{
|
||||
Error::SetErrno(error, "unlink() failed: ", errno);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
FileSystem::POSIXLock::POSIXLock(int fd)
|
||||
{
|
||||
if (lockf(fd, F_LOCK, 0) == 0)
|
||||
|
|
|
@ -84,7 +84,6 @@ 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);
|
||||
|
@ -170,6 +169,12 @@ namespace FileSystem
|
|||
/// Does nothing and returns false on non-Windows platforms.
|
||||
bool SetPathCompression(const char* path, bool enable);
|
||||
|
||||
/// Checks if a file or directory is a symbolic link.
|
||||
bool IsSymbolicLink(const char* path);
|
||||
|
||||
/// Deletes a symbolic link (either a file or directory).
|
||||
bool DeleteSymbolicLink(const char* path, Error* error = nullptr);
|
||||
|
||||
#ifdef _WIN32
|
||||
// Path limit remover, but also converts to a wide string at the same time.
|
||||
bool GetWin32Path(std::wstring* dest, std::string_view str);
|
||||
|
|
Loading…
Reference in New Issue