Support long path in file access on windows
Changed windows file access file to check for path length and use the \\?\ long format when needed
This commit is contained in:
parent
d023e51363
commit
59f04e16b8
|
@ -68,7 +68,7 @@ protected:
|
||||||
virtual String _get_root_string() const;
|
virtual String _get_root_string() const;
|
||||||
|
|
||||||
AccessType get_access_type() const;
|
AccessType get_access_type() const;
|
||||||
String fix_path(String p_path) const;
|
virtual String fix_path(String p_path) const;
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
static Ref<DirAccess> _create_builtin() {
|
static Ref<DirAccess> _create_builtin() {
|
||||||
|
|
|
@ -81,7 +81,7 @@ protected:
|
||||||
static void _bind_methods();
|
static void _bind_methods();
|
||||||
|
|
||||||
AccessType get_access_type() const;
|
AccessType get_access_type() const;
|
||||||
String fix_path(const String &p_path) const;
|
virtual String fix_path(const String &p_path) const;
|
||||||
virtual Error open_internal(const String &p_path, int p_mode_flags) = 0; ///< open a file
|
virtual Error open_internal(const String &p_path, int p_mode_flags) = 0; ///< open a file
|
||||||
virtual uint64_t _get_modified_time(const String &p_file) = 0;
|
virtual uint64_t _get_modified_time(const String &p_file) = 0;
|
||||||
virtual void _set_access_type(AccessType p_access);
|
virtual void _set_access_type(AccessType p_access);
|
||||||
|
|
|
@ -59,6 +59,14 @@ struct DirAccessWindowsPrivate {
|
||||||
WIN32_FIND_DATAW fu; //unicode version
|
WIN32_FIND_DATAW fu; //unicode version
|
||||||
};
|
};
|
||||||
|
|
||||||
|
String DirAccessWindows::fix_path(String p_path) const {
|
||||||
|
String r_path = DirAccess::fix_path(p_path);
|
||||||
|
if (r_path.is_absolute_path() && !r_path.is_network_share_path() && r_path.length() > MAX_PATH) {
|
||||||
|
r_path = "\\\\?\\" + r_path.replace("/", "\\");
|
||||||
|
}
|
||||||
|
return r_path;
|
||||||
|
}
|
||||||
|
|
||||||
// CreateFolderAsync
|
// CreateFolderAsync
|
||||||
|
|
||||||
Error DirAccessWindows::list_dir_begin() {
|
Error DirAccessWindows::list_dir_begin() {
|
||||||
|
@ -158,6 +166,7 @@ Error DirAccessWindows::make_dir(String p_dir) {
|
||||||
p_dir = fix_path(p_dir);
|
p_dir = fix_path(p_dir);
|
||||||
if (p_dir.is_relative_path()) {
|
if (p_dir.is_relative_path()) {
|
||||||
p_dir = current_dir.path_join(p_dir);
|
p_dir = current_dir.path_join(p_dir);
|
||||||
|
p_dir = fix_path(p_dir);
|
||||||
}
|
}
|
||||||
|
|
||||||
p_dir = p_dir.simplify_path().replace("/", "\\");
|
p_dir = p_dir.simplify_path().replace("/", "\\");
|
||||||
|
@ -165,12 +174,6 @@ Error DirAccessWindows::make_dir(String p_dir) {
|
||||||
bool success;
|
bool success;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
if (!p_dir.is_network_share_path()) {
|
|
||||||
p_dir = "\\\\?\\" + p_dir;
|
|
||||||
// Add "\\?\" to the path to extend max. path length past 248, if it's not a network share UNC path.
|
|
||||||
// See https://msdn.microsoft.com/en-us/library/windows/desktop/aa363855(v=vs.85).aspx
|
|
||||||
}
|
|
||||||
|
|
||||||
success = CreateDirectoryW((LPCWSTR)(p_dir.utf16().get_data()), nullptr);
|
success = CreateDirectoryW((LPCWSTR)(p_dir.utf16().get_data()), nullptr);
|
||||||
err = GetLastError();
|
err = GetLastError();
|
||||||
|
|
||||||
|
|
|
@ -53,6 +53,9 @@ class DirAccessWindows : public DirAccess {
|
||||||
bool _cisdir = false;
|
bool _cisdir = false;
|
||||||
bool _cishidden = false;
|
bool _cishidden = false;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual String fix_path(String p_path) const override;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
virtual Error list_dir_begin() override; ///< This starts dir listing
|
virtual Error list_dir_begin() override; ///< This starts dir listing
|
||||||
virtual String get_next() override;
|
virtual String get_next() override;
|
||||||
|
|
|
@ -68,6 +68,14 @@ bool FileAccessWindows::is_path_invalid(const String &p_path) {
|
||||||
return invalid_files.has(fname);
|
return invalid_files.has(fname);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String FileAccessWindows::fix_path(const String &p_path) const {
|
||||||
|
String r_path = FileAccess::fix_path(p_path);
|
||||||
|
if (r_path.is_absolute_path() && !r_path.is_network_share_path() && r_path.length() > MAX_PATH) {
|
||||||
|
r_path = "\\\\?\\" + r_path.replace("/", "\\");
|
||||||
|
}
|
||||||
|
return r_path;
|
||||||
|
}
|
||||||
|
|
||||||
Error FileAccessWindows::open_internal(const String &p_path, int p_mode_flags) {
|
Error FileAccessWindows::open_internal(const String &p_path, int p_mode_flags) {
|
||||||
if (is_path_invalid(p_path)) {
|
if (is_path_invalid(p_path)) {
|
||||||
#ifdef DEBUG_ENABLED
|
#ifdef DEBUG_ENABLED
|
||||||
|
|
|
@ -54,6 +54,7 @@ class FileAccessWindows : public FileAccess {
|
||||||
static HashSet<String> invalid_files;
|
static HashSet<String> invalid_files;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
virtual String fix_path(const String &p_path) const override;
|
||||||
virtual Error open_internal(const String &p_path, int p_mode_flags) override; ///< open a file
|
virtual Error open_internal(const String &p_path, int p_mode_flags) override; ///< open a file
|
||||||
virtual bool is_open() const override; ///< true when file is open
|
virtual bool is_open() const override; ///< true when file is open
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue