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
6 changed files with 23 additions and 8 deletions
|
@ -68,7 +68,7 @@ protected:
|
|||
virtual String _get_root_string() const;
|
||||
|
||||
AccessType get_access_type() const;
|
||||
String fix_path(String p_path) const;
|
||||
virtual String fix_path(String p_path) const;
|
||||
|
||||
template <class T>
|
||||
static Ref<DirAccess> _create_builtin() {
|
||||
|
|
|
@ -81,7 +81,7 @@ protected:
|
|||
static void _bind_methods();
|
||||
|
||||
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 uint64_t _get_modified_time(const String &p_file) = 0;
|
||||
virtual void _set_access_type(AccessType p_access);
|
||||
|
|
|
@ -59,6 +59,14 @@ struct DirAccessWindowsPrivate {
|
|||
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
|
||||
|
||||
Error DirAccessWindows::list_dir_begin() {
|
||||
|
@ -158,6 +166,7 @@ Error DirAccessWindows::make_dir(String p_dir) {
|
|||
p_dir = fix_path(p_dir);
|
||||
if (p_dir.is_relative_path()) {
|
||||
p_dir = current_dir.path_join(p_dir);
|
||||
p_dir = fix_path(p_dir);
|
||||
}
|
||||
|
||||
p_dir = p_dir.simplify_path().replace("/", "\\");
|
||||
|
@ -165,12 +174,6 @@ Error DirAccessWindows::make_dir(String p_dir) {
|
|||
bool success;
|
||||
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);
|
||||
err = GetLastError();
|
||||
|
||||
|
|
|
@ -53,6 +53,9 @@ class DirAccessWindows : public DirAccess {
|
|||
bool _cisdir = false;
|
||||
bool _cishidden = false;
|
||||
|
||||
protected:
|
||||
virtual String fix_path(String p_path) const override;
|
||||
|
||||
public:
|
||||
virtual Error list_dir_begin() override; ///< This starts dir listing
|
||||
virtual String get_next() override;
|
||||
|
|
|
@ -68,6 +68,14 @@ bool FileAccessWindows::is_path_invalid(const String &p_path) {
|
|||
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) {
|
||||
if (is_path_invalid(p_path)) {
|
||||
#ifdef DEBUG_ENABLED
|
||||
|
|
|
@ -54,6 +54,7 @@ class FileAccessWindows : public FileAccess {
|
|||
static HashSet<String> invalid_files;
|
||||
|
||||
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 bool is_open() const override; ///< true when file is open
|
||||
|
||||
|
|
Loading…
Reference in a new issue