| 1973 | } |
| 1974 | |
| 1975 | bool FileSystem::SetReadOnly(StringView path, bool readonly) |
| 1976 | { |
| 1977 | if (path.empty()) return false; |
| 1978 | |
| 1979 | #if defined(DEATH_TARGET_WINDOWS_RT) |
| 1980 | SmallVector<wchar_t, MAX_PATH + 1> pathW(DefaultInit, path.size() + 1); |
| 1981 | Utf8::ToUtf16(pathW.data(), std::int32_t(pathW.size()), path.data(), std::int32_t(path.size())); |
| 1982 | WIN32_FILE_ATTRIBUTE_DATA lpFileInfo; |
| 1983 | if (!::GetFileAttributesExFromAppW(pathW.data(), GetFileExInfoStandard, &lpFileInfo)) { |
| 1984 | return false; |
| 1985 | } |
| 1986 | |
| 1987 | if (readonly == ((lpFileInfo.dwFileAttributes & FILE_ATTRIBUTE_READONLY) == FILE_ATTRIBUTE_READONLY)) { |
| 1988 | return true; |
| 1989 | } else if (readonly) { |
| 1990 | return ::SetFileAttributes(pathW.data(), lpFileInfo.dwFileAttributes | FILE_ATTRIBUTE_READONLY); |
| 1991 | } else { |
| 1992 | return ::SetFileAttributes(pathW.data(), lpFileInfo.dwFileAttributes & ~FILE_ATTRIBUTE_READONLY); |
| 1993 | } |
| 1994 | #elif defined(DEATH_TARGET_WINDOWS) |
| 1995 | SmallVector<wchar_t, MAX_PATH + 1> pathW(DefaultInit, path.size() + 1); |
| 1996 | Utf8::ToUtf16(pathW.data(), std::int32_t(pathW.size()), path.data(), std::int32_t(path.size())); |
| 1997 | DWORD attrs = ::GetFileAttributesW(pathW.data()); |
| 1998 | if (attrs == INVALID_FILE_ATTRIBUTES) { |
| 1999 | return false; |
| 2000 | } |
| 2001 | |
| 2002 | if (readonly == ((attrs & FILE_ATTRIBUTE_READONLY) == FILE_ATTRIBUTE_READONLY)) { |
| 2003 | return true; |
| 2004 | } else if (readonly) { |
| 2005 | return ::SetFileAttributesW(pathW.data(), attrs | FILE_ATTRIBUTE_READONLY); |
| 2006 | } else { |
| 2007 | return ::SetFileAttributesW(pathW.data(), attrs & ~FILE_ATTRIBUTE_READONLY); |
| 2008 | } |
| 2009 | #elif defined(DEATH_TARGET_APPLE) || defined(__FreeBSD__) |
| 2010 | auto nullTerminatedPath = String::nullTerminatedView(path); |
| 2011 | struct stat sb; |
| 2012 | if (::stat(nullTerminatedPath.data(), &sb) != 0) { |
| 2013 | return false; |
| 2014 | } |
| 2015 | |
| 2016 | if (readonly == ((sb.st_flags & UF_IMMUTABLE) == UF_IMMUTABLE)) { |
| 2017 | return true; |
| 2018 | } else if (readonly) { |
| 2019 | return ::chflags(nullTerminatedPath.data(), sb.st_flags | UF_IMMUTABLE) == 0; |
| 2020 | } else { |
| 2021 | return ::chflags(nullTerminatedPath.data(), sb.st_flags & ~UF_IMMUTABLE) == 0; |
| 2022 | } |
| 2023 | #endif |
| 2024 | return false; |
| 2025 | } |
| 2026 | |
| 2027 | bool FileSystem::CreateDirectories(StringView path) |
| 2028 | { |