| 1875 | } |
| 1876 | |
| 1877 | bool FileSystem::SetHidden(StringView path, bool hidden) |
| 1878 | { |
| 1879 | if (path.empty()) return false; |
| 1880 | |
| 1881 | #if defined(DEATH_TARGET_WINDOWS_RT) |
| 1882 | SmallVector<wchar_t, MAX_PATH + 1> pathW(DefaultInit, path.size() + 1); |
| 1883 | Utf8::ToUtf16(pathW.data(), std::int32_t(pathW.size()), path.data(), std::int32_t(path.size())); |
| 1884 | WIN32_FILE_ATTRIBUTE_DATA lpFileInfo; |
| 1885 | if (!::GetFileAttributesExFromAppW(pathW.data(), GetFileExInfoStandard, &lpFileInfo)) { |
| 1886 | return false; |
| 1887 | } |
| 1888 | |
| 1889 | if (hidden == ((lpFileInfo.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN) == FILE_ATTRIBUTE_HIDDEN)) { |
| 1890 | return true; |
| 1891 | } else if (hidden) { |
| 1892 | return ::SetFileAttributes(pathW.data(), lpFileInfo.dwFileAttributes | FILE_ATTRIBUTE_HIDDEN); |
| 1893 | } else { |
| 1894 | return ::SetFileAttributes(pathW.data(), lpFileInfo.dwFileAttributes & ~FILE_ATTRIBUTE_HIDDEN); |
| 1895 | } |
| 1896 | #elif defined(DEATH_TARGET_WINDOWS) |
| 1897 | SmallVector<wchar_t, MAX_PATH + 1> pathW(DefaultInit, path.size() + 1); |
| 1898 | Utf8::ToUtf16(pathW.data(), std::int32_t(pathW.size()), path.data(), std::int32_t(path.size())); |
| 1899 | DWORD attrs = ::GetFileAttributesW(pathW.data()); |
| 1900 | if (attrs == INVALID_FILE_ATTRIBUTES) { |
| 1901 | return false; |
| 1902 | } |
| 1903 | |
| 1904 | if (hidden == ((attrs & FILE_ATTRIBUTE_HIDDEN) == FILE_ATTRIBUTE_HIDDEN)) { |
| 1905 | return true; |
| 1906 | } else if (hidden) { |
| 1907 | return ::SetFileAttributesW(pathW.data(), attrs | FILE_ATTRIBUTE_HIDDEN); |
| 1908 | } else { |
| 1909 | return ::SetFileAttributesW(pathW.data(), attrs & ~FILE_ATTRIBUTE_HIDDEN); |
| 1910 | } |
| 1911 | #elif defined(DEATH_TARGET_APPLE) || defined(__FreeBSD__) |
| 1912 | auto nullTerminatedPath = String::nullTerminatedView(path); |
| 1913 | struct stat sb; |
| 1914 | if (::stat(nullTerminatedPath.data(), &sb) != 0) { |
| 1915 | return false; |
| 1916 | } |
| 1917 | |
| 1918 | if (hidden == ((sb.st_flags & UF_HIDDEN) == UF_HIDDEN)) { |
| 1919 | return true; |
| 1920 | } else if (hidden) { |
| 1921 | return ::chflags(nullTerminatedPath.data(), sb.st_flags | UF_HIDDEN) == 0; |
| 1922 | } else { |
| 1923 | return ::chflags(nullTerminatedPath.data(), sb.st_flags & ~UF_HIDDEN) == 0; |
| 1924 | } |
| 1925 | #else |
| 1926 | auto nullTerminatedPath = String::nullTerminatedView(path); |
| 1927 | # if defined(DEATH_TARGET_ANDROID) |
| 1928 | if (AndroidAssetStream::TryGetAssetPath(nullTerminatedPath)) { |
| 1929 | return false; |
| 1930 | } |
| 1931 | # endif |
| 1932 | char buffer[MaxPathLength]; |
| 1933 | std::size_t pathLength = std::min((std::size_t)MaxPathLength - 1, path.size()); |
| 1934 | strncpy(buffer, nullTerminatedPath.data(), pathLength); |