| 1841 | } |
| 1842 | |
| 1843 | bool FileSystem::IsHidden(StringView path) |
| 1844 | { |
| 1845 | if (path.empty()) return false; |
| 1846 | |
| 1847 | #if defined(DEATH_TARGET_WINDOWS_RT) |
| 1848 | SmallVector<wchar_t, MAX_PATH + 1> pathW(DefaultInit, path.size() + 1); |
| 1849 | Utf8::ToUtf16(pathW.data(), std::int32_t(pathW.size()), path.data(), std::int32_t(path.size())); |
| 1850 | WIN32_FILE_ATTRIBUTE_DATA lpFileInfo; |
| 1851 | return (::GetFileAttributesExFromAppW(pathW.data(), GetFileExInfoStandard, &lpFileInfo) && (lpFileInfo.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN) == FILE_ATTRIBUTE_HIDDEN); |
| 1852 | #elif defined(DEATH_TARGET_WINDOWS) |
| 1853 | SmallVector<wchar_t, MAX_PATH + 1> pathW(DefaultInit, path.size() + 1); |
| 1854 | Utf8::ToUtf16(pathW.data(), std::int32_t(pathW.size()), path.data(), std::int32_t(path.size())); |
| 1855 | const DWORD attrs = ::GetFileAttributesW(pathW.data()); |
| 1856 | return (attrs != INVALID_FILE_ATTRIBUTES && (attrs & FILE_ATTRIBUTE_HIDDEN) == FILE_ATTRIBUTE_HIDDEN); |
| 1857 | #elif defined(DEATH_TARGET_APPLE) || defined(__FreeBSD__) |
| 1858 | auto nullTerminatedPath = String::nullTerminatedView(path); |
| 1859 | struct stat sb; |
| 1860 | return (::stat(nullTerminatedPath.data(), &sb) == 0 && (sb.st_flags & UF_HIDDEN) == UF_HIDDEN); |
| 1861 | #else |
| 1862 | auto nullTerminatedPath = String::nullTerminatedView(path); |
| 1863 | # if defined(DEATH_TARGET_ANDROID) |
| 1864 | if (AndroidAssetStream::TryGetAssetPath(nullTerminatedPath)) { |
| 1865 | return false; |
| 1866 | } |
| 1867 | # endif |
| 1868 | char buffer[MaxPathLength]; |
| 1869 | std::size_t pathLength = std::min((std::size_t)MaxPathLength - 1, path.size()); |
| 1870 | strncpy(buffer, path.data(), pathLength); |
| 1871 | buffer[pathLength] = '\0'; |
| 1872 | const char* baseName = ::basename(buffer); |
| 1873 | return (baseName != nullptr && baseName[0] == '.'); |
| 1874 | #endif |
| 1875 | } |
| 1876 | |
| 1877 | bool FileSystem::SetHidden(StringView path, bool hidden) |
| 1878 | { |