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)
|
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()))
|
if (!RecursiveDeleteDirectory(fd.FileName.c_str()))
|
||||||
return false;
|
return false;
|
||||||
|
@ -1650,21 +1655,6 @@ bool FileSystem::DirectoryExists(const char* path)
|
||||||
return false;
|
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)
|
bool FileSystem::DirectoryIsEmpty(const char* path)
|
||||||
{
|
{
|
||||||
std::wstring wpath = GetWin32Path(path);
|
std::wstring wpath = GetWin32Path(path);
|
||||||
|
@ -1935,6 +1925,52 @@ bool FileSystem::SetPathCompression(const char* path, bool enable)
|
||||||
return result;
|
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
|
#else
|
||||||
|
|
||||||
// No 32-bit file offsets breaking stuff please.
|
// No 32-bit file offsets breaking stuff please.
|
||||||
|
@ -2216,15 +2252,6 @@ bool FileSystem::DirectoryExists(const char* path)
|
||||||
return false;
|
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)
|
bool FileSystem::DirectoryIsEmpty(const char* path)
|
||||||
{
|
{
|
||||||
DIR* pDir = opendir(path);
|
DIR* pDir = opendir(path);
|
||||||
|
@ -2478,6 +2505,26 @@ bool FileSystem::SetPathCompression(const char* path, bool enable)
|
||||||
return false;
|
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)
|
FileSystem::POSIXLock::POSIXLock(int fd)
|
||||||
{
|
{
|
||||||
if (lockf(fd, F_LOCK, 0) == 0)
|
if (lockf(fd, F_LOCK, 0) == 0)
|
||||||
|
|
|
@ -84,7 +84,6 @@ namespace FileSystem
|
||||||
|
|
||||||
/// Directory exists?
|
/// Directory exists?
|
||||||
bool DirectoryExists(const char* path);
|
bool DirectoryExists(const char* path);
|
||||||
bool IsRealDirectory(const char* path);
|
|
||||||
|
|
||||||
/// Directory does not contain any files?
|
/// Directory does not contain any files?
|
||||||
bool DirectoryIsEmpty(const char* path);
|
bool DirectoryIsEmpty(const char* path);
|
||||||
|
@ -170,6 +169,12 @@ namespace FileSystem
|
||||||
/// Does nothing and returns false on non-Windows platforms.
|
/// Does nothing and returns false on non-Windows platforms.
|
||||||
bool SetPathCompression(const char* path, bool enable);
|
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
|
#ifdef _WIN32
|
||||||
// Path limit remover, but also converts to a wide string at the same time.
|
// Path limit remover, but also converts to a wide string at the same time.
|
||||||
bool GetWin32Path(std::wstring* dest, std::string_view str);
|
bool GetWin32Path(std::wstring* dest, std::string_view str);
|
||||||
|
|
Loading…
Reference in New Issue