diff --git a/core/io/file_access.cpp b/core/io/file_access.cpp index b669afdc991..6026dbf8962 100644 --- a/core/io/file_access.cpp +++ b/core/io/file_access.cpp @@ -583,7 +583,7 @@ uint64_t FileAccess::get_modified_time(const String &p_file) { return mt; } -uint32_t FileAccess::get_unix_permissions(const String &p_file) { +BitField FileAccess::get_unix_permissions(const String &p_file) { if (PackedData::get_singleton() && !PackedData::get_singleton()->is_disabled() && (PackedData::get_singleton()->has_path(p_file) || PackedData::get_singleton()->has_directory(p_file))) { return 0; } @@ -591,11 +591,10 @@ uint32_t FileAccess::get_unix_permissions(const String &p_file) { Ref fa = create_for_path(p_file); ERR_FAIL_COND_V_MSG(fa.is_null(), 0, "Cannot create FileAccess for path '" + p_file + "'."); - uint32_t mt = fa->_get_unix_permissions(p_file); - return mt; + return fa->_get_unix_permissions(p_file); } -Error FileAccess::set_unix_permissions(const String &p_file, uint32_t p_permissions) { +Error FileAccess::set_unix_permissions(const String &p_file, BitField p_permissions) { if (PackedData::get_singleton() && !PackedData::get_singleton()->is_disabled() && (PackedData::get_singleton()->has_path(p_file) || PackedData::get_singleton()->has_directory(p_file))) { return ERR_UNAVAILABLE; } @@ -607,6 +606,52 @@ Error FileAccess::set_unix_permissions(const String &p_file, uint32_t p_permissi return err; } +bool FileAccess::get_hidden_attribute(const String &p_file) { + if (PackedData::get_singleton() && !PackedData::get_singleton()->is_disabled() && (PackedData::get_singleton()->has_path(p_file) || PackedData::get_singleton()->has_directory(p_file))) { + return false; + } + + Ref fa = create_for_path(p_file); + ERR_FAIL_COND_V_MSG(fa.is_null(), false, "Cannot create FileAccess for path '" + p_file + "'."); + + return fa->_get_hidden_attribute(p_file); +} + +Error FileAccess::set_hidden_attribute(const String &p_file, bool p_hidden) { + if (PackedData::get_singleton() && !PackedData::get_singleton()->is_disabled() && (PackedData::get_singleton()->has_path(p_file) || PackedData::get_singleton()->has_directory(p_file))) { + return ERR_UNAVAILABLE; + } + + Ref fa = create_for_path(p_file); + ERR_FAIL_COND_V_MSG(fa.is_null(), ERR_CANT_CREATE, "Cannot create FileAccess for path '" + p_file + "'."); + + Error err = fa->_set_hidden_attribute(p_file, p_hidden); + return err; +} + +bool FileAccess::get_read_only_attribute(const String &p_file) { + if (PackedData::get_singleton() && !PackedData::get_singleton()->is_disabled() && (PackedData::get_singleton()->has_path(p_file) || PackedData::get_singleton()->has_directory(p_file))) { + return false; + } + + Ref fa = create_for_path(p_file); + ERR_FAIL_COND_V_MSG(fa.is_null(), false, "Cannot create FileAccess for path '" + p_file + "'."); + + return fa->_get_read_only_attribute(p_file); +} + +Error FileAccess::set_read_only_attribute(const String &p_file, bool p_ro) { + if (PackedData::get_singleton() && !PackedData::get_singleton()->is_disabled() && (PackedData::get_singleton()->has_path(p_file) || PackedData::get_singleton()->has_directory(p_file))) { + return ERR_UNAVAILABLE; + } + + Ref fa = create_for_path(p_file); + ERR_FAIL_COND_V_MSG(fa.is_null(), ERR_CANT_CREATE, "Cannot create FileAccess for path '" + p_file + "'."); + + Error err = fa->_set_read_only_attribute(p_file, p_ro); + return err; +} + void FileAccess::store_string(const String &p_string) { if (p_string.length() == 0) { return; @@ -865,6 +910,14 @@ void FileAccess::_bind_methods() { ClassDB::bind_static_method("FileAccess", D_METHOD("file_exists", "path"), &FileAccess::exists); ClassDB::bind_static_method("FileAccess", D_METHOD("get_modified_time", "file"), &FileAccess::get_modified_time); + ClassDB::bind_static_method("FileAccess", D_METHOD("get_unix_permissions", "file"), &FileAccess::get_unix_permissions); + ClassDB::bind_static_method("FileAccess", D_METHOD("set_unix_permissions", "file", "permissions"), &FileAccess::set_unix_permissions); + + ClassDB::bind_static_method("FileAccess", D_METHOD("get_hidden_attribute", "file"), &FileAccess::get_hidden_attribute); + ClassDB::bind_static_method("FileAccess", D_METHOD("set_hidden_attribute", "file", "hidden"), &FileAccess::set_hidden_attribute); + ClassDB::bind_static_method("FileAccess", D_METHOD("set_read_only_attribute", "file", "ro"), &FileAccess::set_read_only_attribute); + ClassDB::bind_static_method("FileAccess", D_METHOD("get_read_only_attribute", "file"), &FileAccess::get_read_only_attribute); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "big_endian"), "set_big_endian", "is_big_endian"); BIND_ENUM_CONSTANT(READ); @@ -877,4 +930,17 @@ void FileAccess::_bind_methods() { BIND_ENUM_CONSTANT(COMPRESSION_ZSTD); BIND_ENUM_CONSTANT(COMPRESSION_GZIP); BIND_ENUM_CONSTANT(COMPRESSION_BROTLI); + + BIND_BITFIELD_FLAG(UNIX_READ_OWNER); + BIND_BITFIELD_FLAG(UNIX_WRITE_OWNER); + BIND_BITFIELD_FLAG(UNIX_EXECUTE_OWNER); + BIND_BITFIELD_FLAG(UNIX_READ_GROUP); + BIND_BITFIELD_FLAG(UNIX_WRITE_GROUP); + BIND_BITFIELD_FLAG(UNIX_EXECUTE_GROUP); + BIND_BITFIELD_FLAG(UNIX_READ_OTHER); + BIND_BITFIELD_FLAG(UNIX_WRITE_OTHER); + BIND_BITFIELD_FLAG(UNIX_EXECUTE_OTHER); + BIND_BITFIELD_FLAG(UNIX_SET_USER_ID); + BIND_BITFIELD_FLAG(UNIX_SET_GROUP_ID); + BIND_BITFIELD_FLAG(UNIX_RESTRICTED_DELETE); } diff --git a/core/io/file_access.h b/core/io/file_access.h index ad1ac665f31..7b9e66bb835 100644 --- a/core/io/file_access.h +++ b/core/io/file_access.h @@ -60,6 +60,21 @@ public: WRITE_READ = 7, }; + enum UnixPermissionFlags { + UNIX_EXECUTE_OTHER = 0x001, + UNIX_WRITE_OTHER = 0x002, + UNIX_READ_OTHER = 0x004, + UNIX_EXECUTE_GROUP = 0x008, + UNIX_WRITE_GROUP = 0x010, + UNIX_READ_GROUP = 0x020, + UNIX_EXECUTE_OWNER = 0x040, + UNIX_WRITE_OWNER = 0x080, + UNIX_READ_OWNER = 0x100, + UNIX_RESTRICTED_DELETE = 0x200, + UNIX_SET_GROUP_ID = 0x400, + UNIX_SET_USER_ID = 0x800, + }; + enum CompressionMode { COMPRESSION_FASTLZ = Compression::MODE_FASTLZ, COMPRESSION_DEFLATE = Compression::MODE_DEFLATE, @@ -74,8 +89,13 @@ public: bool big_endian = false; bool real_is_double = false; - virtual uint32_t _get_unix_permissions(const String &p_file) = 0; - virtual Error _set_unix_permissions(const String &p_file, uint32_t p_permissions) = 0; + virtual BitField _get_unix_permissions(const String &p_file) = 0; + virtual Error _set_unix_permissions(const String &p_file, BitField p_permissions) = 0; + + virtual bool _get_hidden_attribute(const String &p_file) = 0; + virtual Error _set_hidden_attribute(const String &p_file, bool p_hidden) = 0; + virtual bool _get_read_only_attribute(const String &p_file) = 0; + virtual Error _set_read_only_attribute(const String &p_file, bool p_ro) = 0; protected: static void _bind_methods(); @@ -185,8 +205,13 @@ public: static CreateFunc get_create_func(AccessType p_access); static bool exists(const String &p_name); ///< return true if a file exists static uint64_t get_modified_time(const String &p_file); - static uint32_t get_unix_permissions(const String &p_file); - static Error set_unix_permissions(const String &p_file, uint32_t p_permissions); + static BitField get_unix_permissions(const String &p_file); + static Error set_unix_permissions(const String &p_file, BitField p_permissions); + + static bool get_hidden_attribute(const String &p_file); + static Error set_hidden_attribute(const String &p_file, bool p_hidden); + static bool get_read_only_attribute(const String &p_file); + static Error set_read_only_attribute(const String &p_file, bool p_ro); static void set_backup_save(bool p_enable) { backup_save = p_enable; }; static bool is_backup_save_enabled() { return backup_save; }; @@ -212,5 +237,6 @@ public: VARIANT_ENUM_CAST(FileAccess::CompressionMode); VARIANT_ENUM_CAST(FileAccess::ModeFlags); +VARIANT_BITFIELD_CAST(FileAccess::UnixPermissionFlags); #endif // FILE_ACCESS_H diff --git a/core/io/file_access_compressed.cpp b/core/io/file_access_compressed.cpp index 3e5a1217dd6..0f00bd292cd 100644 --- a/core/io/file_access_compressed.cpp +++ b/core/io/file_access_compressed.cpp @@ -365,20 +365,48 @@ uint64_t FileAccessCompressed::_get_modified_time(const String &p_file) { } } -uint32_t FileAccessCompressed::_get_unix_permissions(const String &p_file) { +BitField FileAccessCompressed::_get_unix_permissions(const String &p_file) { if (f.is_valid()) { return f->_get_unix_permissions(p_file); } return 0; } -Error FileAccessCompressed::_set_unix_permissions(const String &p_file, uint32_t p_permissions) { +Error FileAccessCompressed::_set_unix_permissions(const String &p_file, BitField p_permissions) { if (f.is_valid()) { return f->_set_unix_permissions(p_file, p_permissions); } return FAILED; } +bool FileAccessCompressed::_get_hidden_attribute(const String &p_file) { + if (f.is_valid()) { + return f->_get_hidden_attribute(p_file); + } + return false; +} + +Error FileAccessCompressed::_set_hidden_attribute(const String &p_file, bool p_hidden) { + if (f.is_valid()) { + return f->_set_hidden_attribute(p_file, p_hidden); + } + return FAILED; +} + +bool FileAccessCompressed::_get_read_only_attribute(const String &p_file) { + if (f.is_valid()) { + return f->_get_read_only_attribute(p_file); + } + return false; +} + +Error FileAccessCompressed::_set_read_only_attribute(const String &p_file, bool p_ro) { + if (f.is_valid()) { + return f->_set_read_only_attribute(p_file, p_ro); + } + return FAILED; +} + void FileAccessCompressed::close() { _close(); } diff --git a/core/io/file_access_compressed.h b/core/io/file_access_compressed.h index 601b74a9c14..bf57eaa07c0 100644 --- a/core/io/file_access_compressed.h +++ b/core/io/file_access_compressed.h @@ -94,8 +94,13 @@ public: virtual bool file_exists(const String &p_name) override; ///< return true if a file exists virtual uint64_t _get_modified_time(const String &p_file) override; - virtual uint32_t _get_unix_permissions(const String &p_file) override; - virtual Error _set_unix_permissions(const String &p_file, uint32_t p_permissions) override; + virtual BitField _get_unix_permissions(const String &p_file) override; + virtual Error _set_unix_permissions(const String &p_file, BitField p_permissions) override; + + virtual bool _get_hidden_attribute(const String &p_file) override; + virtual Error _set_hidden_attribute(const String &p_file, bool p_hidden) override; + virtual bool _get_read_only_attribute(const String &p_file) override; + virtual Error _set_read_only_attribute(const String &p_file, bool p_ro) override; virtual void close() override; diff --git a/core/io/file_access_encrypted.cpp b/core/io/file_access_encrypted.cpp index c39d19d52b0..b689f5b6284 100644 --- a/core/io/file_access_encrypted.cpp +++ b/core/io/file_access_encrypted.cpp @@ -285,13 +285,46 @@ uint64_t FileAccessEncrypted::_get_modified_time(const String &p_file) { return 0; } -uint32_t FileAccessEncrypted::_get_unix_permissions(const String &p_file) { +BitField FileAccessEncrypted::_get_unix_permissions(const String &p_file) { + if (file.is_valid()) { + return file->_get_unix_permissions(p_file); + } return 0; } -Error FileAccessEncrypted::_set_unix_permissions(const String &p_file, uint32_t p_permissions) { - ERR_PRINT("Setting UNIX permissions on encrypted files is not implemented yet."); - return ERR_UNAVAILABLE; +Error FileAccessEncrypted::_set_unix_permissions(const String &p_file, BitField p_permissions) { + if (file.is_valid()) { + return file->_set_unix_permissions(p_file, p_permissions); + } + return FAILED; +} + +bool FileAccessEncrypted::_get_hidden_attribute(const String &p_file) { + if (file.is_valid()) { + return file->_get_hidden_attribute(p_file); + } + return false; +} + +Error FileAccessEncrypted::_set_hidden_attribute(const String &p_file, bool p_hidden) { + if (file.is_valid()) { + return file->_set_hidden_attribute(p_file, p_hidden); + } + return FAILED; +} + +bool FileAccessEncrypted::_get_read_only_attribute(const String &p_file) { + if (file.is_valid()) { + return file->_get_read_only_attribute(p_file); + } + return false; +} + +Error FileAccessEncrypted::_set_read_only_attribute(const String &p_file, bool p_ro) { + if (file.is_valid()) { + return file->_set_read_only_attribute(p_file, p_ro); + } + return FAILED; } void FileAccessEncrypted::close() { diff --git a/core/io/file_access_encrypted.h b/core/io/file_access_encrypted.h index 9702b5a5171..489d213b8fd 100644 --- a/core/io/file_access_encrypted.h +++ b/core/io/file_access_encrypted.h @@ -85,8 +85,13 @@ public: virtual bool file_exists(const String &p_name) override; ///< return true if a file exists virtual uint64_t _get_modified_time(const String &p_file) override; - virtual uint32_t _get_unix_permissions(const String &p_file) override; - virtual Error _set_unix_permissions(const String &p_file, uint32_t p_permissions) override; + virtual BitField _get_unix_permissions(const String &p_file) override; + virtual Error _set_unix_permissions(const String &p_file, BitField p_permissions) override; + + virtual bool _get_hidden_attribute(const String &p_file) override; + virtual Error _set_hidden_attribute(const String &p_file, bool p_hidden) override; + virtual bool _get_read_only_attribute(const String &p_file) override; + virtual Error _set_read_only_attribute(const String &p_file, bool p_ro) override; virtual void close() override; diff --git a/core/io/file_access_memory.h b/core/io/file_access_memory.h index 43fe6ab6588..ac08e5406fa 100644 --- a/core/io/file_access_memory.h +++ b/core/io/file_access_memory.h @@ -68,8 +68,13 @@ public: virtual bool file_exists(const String &p_name) override; ///< return true if a file exists virtual uint64_t _get_modified_time(const String &p_file) override { return 0; } - virtual uint32_t _get_unix_permissions(const String &p_file) override { return 0; } - virtual Error _set_unix_permissions(const String &p_file, uint32_t p_permissions) override { return FAILED; } + virtual BitField _get_unix_permissions(const String &p_file) override { return 0; } + virtual Error _set_unix_permissions(const String &p_file, BitField p_permissions) override { return FAILED; } + + virtual bool _get_hidden_attribute(const String &p_file) override { return false; } + virtual Error _set_hidden_attribute(const String &p_file, bool p_hidden) override { return ERR_UNAVAILABLE; } + virtual bool _get_read_only_attribute(const String &p_file) override { return false; } + virtual Error _set_read_only_attribute(const String &p_file, bool p_ro) override { return ERR_UNAVAILABLE; } virtual void close() override {} diff --git a/core/io/file_access_pack.h b/core/io/file_access_pack.h index 1538b302c29..97391a56110 100644 --- a/core/io/file_access_pack.h +++ b/core/io/file_access_pack.h @@ -150,8 +150,13 @@ class FileAccessPack : public FileAccess { Ref f; virtual Error open_internal(const String &p_path, int p_mode_flags) override; virtual uint64_t _get_modified_time(const String &p_file) override { return 0; } - virtual uint32_t _get_unix_permissions(const String &p_file) override { return 0; } - virtual Error _set_unix_permissions(const String &p_file, uint32_t p_permissions) override { return FAILED; } + virtual BitField _get_unix_permissions(const String &p_file) override { return 0; } + virtual Error _set_unix_permissions(const String &p_file, BitField p_permissions) override { return FAILED; } + + virtual bool _get_hidden_attribute(const String &p_file) override { return false; } + virtual Error _set_hidden_attribute(const String &p_file, bool p_hidden) override { return ERR_UNAVAILABLE; } + virtual bool _get_read_only_attribute(const String &p_file) override { return false; } + virtual Error _set_read_only_attribute(const String &p_file, bool p_ro) override { return ERR_UNAVAILABLE; } public: virtual bool is_open() const override; diff --git a/core/io/file_access_zip.h b/core/io/file_access_zip.h index f8b640946c2..1062a062380 100644 --- a/core/io/file_access_zip.h +++ b/core/io/file_access_zip.h @@ -106,8 +106,13 @@ public: virtual bool file_exists(const String &p_name) override; ///< return true if a file exists virtual uint64_t _get_modified_time(const String &p_file) override { return 0; } // todo - virtual uint32_t _get_unix_permissions(const String &p_file) override { return 0; } - virtual Error _set_unix_permissions(const String &p_file, uint32_t p_permissions) override { return FAILED; } + virtual BitField _get_unix_permissions(const String &p_file) override { return 0; } + virtual Error _set_unix_permissions(const String &p_file, BitField p_permissions) override { return FAILED; } + + virtual bool _get_hidden_attribute(const String &p_file) override { return false; } + virtual Error _set_hidden_attribute(const String &p_file, bool p_hidden) override { return ERR_UNAVAILABLE; } + virtual bool _get_read_only_attribute(const String &p_file) override { return false; } + virtual Error _set_read_only_attribute(const String &p_file, bool p_ro) override { return ERR_UNAVAILABLE; } virtual void close() override; diff --git a/doc/classes/FileAccess.xml b/doc/classes/FileAccess.xml index 5c1f6775a1d..85fbff79326 100644 --- a/doc/classes/FileAccess.xml +++ b/doc/classes/FileAccess.xml @@ -170,6 +170,14 @@ Returns the next 32 bits from the file as a floating-point number. + + + + + Returns [code]true[/code], if file [code]hidden[/code] attribute is set. + [b]Note:[/b] This method is implemented on iOS, BSD, macOS, and Windows. + + @@ -228,6 +236,14 @@ Returns the file cursor's position. + + + + + Returns [code]true[/code], if file [code]read only[/code] attribute is set. + [b]Note:[/b] This method is implemented on iOS, BSD, macOS, and Windows. + + @@ -241,6 +257,14 @@ Returns a SHA-256 [String] representing the file at the given path or an empty [String] on failure. + + + + + Returns file UNIX permissions. + [b]Note:[/b] This method is implemented on iOS, Linux/BSD, and macOS. + + @@ -312,6 +336,33 @@ [b]Note:[/b] This is an offset, so you should use negative numbers or the cursor will be at the end of the file. + + + + + + Sets file [code]hidden[/code] attribute. + [b]Note:[/b] This method is implemented on iOS, BSD, macOS, and Windows. + + + + + + + + Sets file [code]read only[/code] attribute. + [b]Note:[/b] This method is implemented on iOS, BSD, macOS, and Windows. + + + + + + + + Sets file UNIX permissions. + [b]Note:[/b] This method is implemented on iOS, Linux/BSD, and macOS. + + @@ -485,5 +536,41 @@ Uses the [url=https://github.com/google/brotli]brotli[/url] compression method (only decompression is supported). + + Read for owner bit. + + + Write for owner bit. + + + Execute for owner bit. + + + Read for group bit. + + + Write for group bit. + + + Execute for group bit. + + + Read for other bit. + + + Write for other bit. + + + Execute for other bit. + + + Set user id on execution bit. + + + Set group id on execution bit. + + + Restricted deletion (sticky) bit. + diff --git a/drivers/unix/file_access_unix.cpp b/drivers/unix/file_access_unix.cpp index a80b7d449e6..3b15cf60f76 100644 --- a/drivers/unix/file_access_unix.cpp +++ b/drivers/unix/file_access_unix.cpp @@ -313,19 +313,19 @@ uint64_t FileAccessUnix::_get_modified_time(const String &p_file) { } } -uint32_t FileAccessUnix::_get_unix_permissions(const String &p_file) { +BitField FileAccessUnix::_get_unix_permissions(const String &p_file) { String file = fix_path(p_file); struct stat status = {}; int err = stat(file.utf8().get_data(), &status); if (!err) { - return status.st_mode & 0x7FF; //only permissions + return status.st_mode & 0xFFF; //only permissions } else { ERR_FAIL_V_MSG(0, "Failed to get unix permissions for: " + p_file + "."); } } -Error FileAccessUnix::_set_unix_permissions(const String &p_file, uint32_t p_permissions) { +Error FileAccessUnix::_set_unix_permissions(const String &p_file, BitField p_permissions) { String file = fix_path(p_file); int err = chmod(file.utf8().get_data(), p_permissions); @@ -336,6 +336,74 @@ Error FileAccessUnix::_set_unix_permissions(const String &p_file, uint32_t p_per return FAILED; } +bool FileAccessUnix::_get_hidden_attribute(const String &p_file) { +#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) || defined(__APPLE__) + String file = fix_path(p_file); + + struct stat st = {}; + int err = stat(file.utf8().get_data(), &st); + ERR_FAIL_COND_V_MSG(err, false, "Failed to get attributes for: " + p_file); + + return (st.st_flags & UF_HIDDEN); +#else + return false; +#endif +} + +Error FileAccessUnix::_set_hidden_attribute(const String &p_file, bool p_hidden) { +#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) || defined(__APPLE__) + String file = fix_path(p_file); + + struct stat st = {}; + int err = stat(file.utf8().get_data(), &st); + ERR_FAIL_COND_V_MSG(err, FAILED, "Failed to get attributes for: " + p_file); + + if (p_hidden) { + err = chflags(file.utf8().get_data(), st.st_flags | UF_HIDDEN); + } else { + err = chflags(file.utf8().get_data(), st.st_flags & ~UF_HIDDEN); + } + ERR_FAIL_COND_V_MSG(err, FAILED, "Failed to set attributes for: " + p_file); + return OK; +#else + return ERR_UNAVAILABLE; +#endif +} + +bool FileAccessUnix::_get_read_only_attribute(const String &p_file) { +#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) || defined(__APPLE__) + String file = fix_path(p_file); + + struct stat st = {}; + int err = stat(file.utf8().get_data(), &st); + ERR_FAIL_COND_V_MSG(err, false, "Failed to get attributes for: " + p_file); + + return st.st_flags & UF_IMMUTABLE; +#else + return false; +#endif +} + +Error FileAccessUnix::_set_read_only_attribute(const String &p_file, bool p_ro) { +#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) || defined(__APPLE__) + String file = fix_path(p_file); + + struct stat st = {}; + int err = stat(file.utf8().get_data(), &st); + ERR_FAIL_COND_V_MSG(err, FAILED, "Failed to get attributes for: " + p_file); + + if (p_ro) { + err = chflags(file.utf8().get_data(), st.st_flags | UF_IMMUTABLE); + } else { + err = chflags(file.utf8().get_data(), st.st_flags & ~UF_IMMUTABLE); + } + ERR_FAIL_COND_V_MSG(err, FAILED, "Failed to set attributes for: " + p_file); + return OK; +#else + return ERR_UNAVAILABLE; +#endif +} + void FileAccessUnix::close() { _close(); } diff --git a/drivers/unix/file_access_unix.h b/drivers/unix/file_access_unix.h index 79c4e736369..2bfac27c4f0 100644 --- a/drivers/unix/file_access_unix.h +++ b/drivers/unix/file_access_unix.h @@ -79,8 +79,13 @@ public: virtual bool file_exists(const String &p_path) override; ///< return true if a file exists virtual uint64_t _get_modified_time(const String &p_file) override; - virtual uint32_t _get_unix_permissions(const String &p_file) override; - virtual Error _set_unix_permissions(const String &p_file, uint32_t p_permissions) override; + virtual BitField _get_unix_permissions(const String &p_file) override; + virtual Error _set_unix_permissions(const String &p_file, BitField p_permissions) override; + + virtual bool _get_hidden_attribute(const String &p_file) override; + virtual Error _set_hidden_attribute(const String &p_file, bool p_hidden) override; + virtual bool _get_read_only_attribute(const String &p_file) override; + virtual Error _set_read_only_attribute(const String &p_file, bool p_ro) override; virtual void close() override; diff --git a/drivers/windows/file_access_windows.cpp b/drivers/windows/file_access_windows.cpp index 6e69743d4ef..c1e0c3fb60b 100644 --- a/drivers/windows/file_access_windows.cpp +++ b/drivers/windows/file_access_windows.cpp @@ -381,14 +381,62 @@ uint64_t FileAccessWindows::_get_modified_time(const String &p_file) { } } -uint32_t FileAccessWindows::_get_unix_permissions(const String &p_file) { +BitField FileAccessWindows::_get_unix_permissions(const String &p_file) { return 0; } -Error FileAccessWindows::_set_unix_permissions(const String &p_file, uint32_t p_permissions) { +Error FileAccessWindows::_set_unix_permissions(const String &p_file, BitField p_permissions) { return ERR_UNAVAILABLE; } +bool FileAccessWindows::_get_hidden_attribute(const String &p_file) { + String file = fix_path(p_file); + + DWORD attrib = GetFileAttributesW((LPCWSTR)file.utf16().get_data()); + ERR_FAIL_COND_V_MSG(attrib == INVALID_FILE_ATTRIBUTES, false, "Failed to get attributes for: " + p_file); + return (attrib & FILE_ATTRIBUTE_HIDDEN); +} + +Error FileAccessWindows::_set_hidden_attribute(const String &p_file, bool p_hidden) { + String file = fix_path(p_file); + + DWORD attrib = GetFileAttributesW((LPCWSTR)file.utf16().get_data()); + ERR_FAIL_COND_V_MSG(attrib == INVALID_FILE_ATTRIBUTES, FAILED, "Failed to get attributes for: " + p_file); + BOOL ok; + if (p_hidden) { + ok = SetFileAttributesW((LPCWSTR)file.utf16().get_data(), attrib | FILE_ATTRIBUTE_HIDDEN); + } else { + ok = SetFileAttributesW((LPCWSTR)file.utf16().get_data(), attrib & ~FILE_ATTRIBUTE_HIDDEN); + } + ERR_FAIL_COND_V_MSG(!ok, FAILED, "Failed to set attributes for: " + p_file); + + return OK; +} + +bool FileAccessWindows::_get_read_only_attribute(const String &p_file) { + String file = fix_path(p_file); + + DWORD attrib = GetFileAttributesW((LPCWSTR)file.utf16().get_data()); + ERR_FAIL_COND_V_MSG(attrib == INVALID_FILE_ATTRIBUTES, false, "Failed to get attributes for: " + p_file); + return (attrib & FILE_ATTRIBUTE_READONLY); +} + +Error FileAccessWindows::_set_read_only_attribute(const String &p_file, bool p_ro) { + String file = fix_path(p_file); + + DWORD attrib = GetFileAttributesW((LPCWSTR)file.utf16().get_data()); + ERR_FAIL_COND_V_MSG(attrib == INVALID_FILE_ATTRIBUTES, FAILED, "Failed to get attributes for: " + p_file); + BOOL ok; + if (p_ro) { + ok = SetFileAttributesW((LPCWSTR)file.utf16().get_data(), attrib | FILE_ATTRIBUTE_READONLY); + } else { + ok = SetFileAttributesW((LPCWSTR)file.utf16().get_data(), attrib & ~FILE_ATTRIBUTE_READONLY); + } + ERR_FAIL_COND_V_MSG(!ok, FAILED, "Failed to set attributes for: " + p_file); + + return OK; +} + void FileAccessWindows::close() { _close(); } diff --git a/drivers/windows/file_access_windows.h b/drivers/windows/file_access_windows.h index 13c881e562a..73143009fcf 100644 --- a/drivers/windows/file_access_windows.h +++ b/drivers/windows/file_access_windows.h @@ -80,8 +80,13 @@ public: virtual bool file_exists(const String &p_name) override; ///< return true if a file exists uint64_t _get_modified_time(const String &p_file) override; - virtual uint32_t _get_unix_permissions(const String &p_file) override; - virtual Error _set_unix_permissions(const String &p_file, uint32_t p_permissions) override; + virtual BitField _get_unix_permissions(const String &p_file) override; + virtual Error _set_unix_permissions(const String &p_file, BitField p_permissions) override; + + virtual bool _get_hidden_attribute(const String &p_file) override; + virtual Error _set_hidden_attribute(const String &p_file, bool p_hidden) override; + virtual bool _get_read_only_attribute(const String &p_file) override; + virtual Error _set_read_only_attribute(const String &p_file, bool p_ro) override; virtual void close() override; diff --git a/platform/android/file_access_android.h b/platform/android/file_access_android.h index 7ff5c4d1173..3aa4ca98fcb 100644 --- a/platform/android/file_access_android.h +++ b/platform/android/file_access_android.h @@ -76,8 +76,13 @@ public: virtual bool file_exists(const String &p_path) override; // return true if a file exists virtual uint64_t _get_modified_time(const String &p_file) override { return 0; } - virtual uint32_t _get_unix_permissions(const String &p_file) override { return 0; } - virtual Error _set_unix_permissions(const String &p_file, uint32_t p_permissions) override { return FAILED; } + virtual BitField _get_unix_permissions(const String &p_file) override { return 0; } + virtual Error _set_unix_permissions(const String &p_file, BitField p_permissions) override { return FAILED; } + + virtual bool _get_hidden_attribute(const String &p_file) override { return false; } + virtual Error _set_hidden_attribute(const String &p_file, bool p_hidden) override { return ERR_UNAVAILABLE; } + virtual bool _get_read_only_attribute(const String &p_file) override { return false; } + virtual Error _set_read_only_attribute(const String &p_file, bool p_ro) override { return ERR_UNAVAILABLE; } virtual void close() override; diff --git a/platform/android/file_access_filesystem_jandroid.h b/platform/android/file_access_filesystem_jandroid.h index 739c8a09250..0c3f8d72599 100644 --- a/platform/android/file_access_filesystem_jandroid.h +++ b/platform/android/file_access_filesystem_jandroid.h @@ -91,8 +91,13 @@ public: static void setup(jobject p_file_access_handler); virtual uint64_t _get_modified_time(const String &p_file) override; - virtual uint32_t _get_unix_permissions(const String &p_file) override { return 0; } - virtual Error _set_unix_permissions(const String &p_file, uint32_t p_permissions) override { return FAILED; } + virtual BitField _get_unix_permissions(const String &p_file) override { return 0; } + virtual Error _set_unix_permissions(const String &p_file, BitField p_permissions) override { return FAILED; } + + virtual bool _get_hidden_attribute(const String &p_file) override { return false; } + virtual Error _set_hidden_attribute(const String &p_file, bool p_hidden) override { return ERR_UNAVAILABLE; } + virtual bool _get_read_only_attribute(const String &p_file) override { return false; } + virtual Error _set_read_only_attribute(const String &p_file, bool p_ro) override { return ERR_UNAVAILABLE; } virtual void close() override;