Skip to content

Commit 59f04e1

Browse files
committed
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
1 parent d023e51 commit 59f04e1

6 files changed

+23
-8
lines changed

core/io/dir_access.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ class DirAccess : public RefCounted {
6868
virtual String _get_root_string() const;
6969

7070
AccessType get_access_type() const;
71-
String fix_path(String p_path) const;
71+
virtual String fix_path(String p_path) const;
7272

7373
template <class T>
7474
static Ref<DirAccess> _create_builtin() {

core/io/file_access.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ class FileAccess : public RefCounted {
8181
static void _bind_methods();
8282

8383
AccessType get_access_type() const;
84-
String fix_path(const String &p_path) const;
84+
virtual String fix_path(const String &p_path) const;
8585
virtual Error open_internal(const String &p_path, int p_mode_flags) = 0; ///< open a file
8686
virtual uint64_t _get_modified_time(const String &p_file) = 0;
8787
virtual void _set_access_type(AccessType p_access);

drivers/windows/dir_access_windows.cpp

+9-6
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,14 @@ struct DirAccessWindowsPrivate {
5959
WIN32_FIND_DATAW fu; //unicode version
6060
};
6161

62+
String DirAccessWindows::fix_path(String p_path) const {
63+
String r_path = DirAccess::fix_path(p_path);
64+
if (r_path.is_absolute_path() && !r_path.is_network_share_path() && r_path.length() > MAX_PATH) {
65+
r_path = "\\\\?\\" + r_path.replace("/", "\\");
66+
}
67+
return r_path;
68+
}
69+
6270
// CreateFolderAsync
6371

6472
Error DirAccessWindows::list_dir_begin() {
@@ -158,19 +166,14 @@ Error DirAccessWindows::make_dir(String p_dir) {
158166
p_dir = fix_path(p_dir);
159167
if (p_dir.is_relative_path()) {
160168
p_dir = current_dir.path_join(p_dir);
169+
p_dir = fix_path(p_dir);
161170
}
162171

163172
p_dir = p_dir.simplify_path().replace("/", "\\");
164173

165174
bool success;
166175
int err;
167176

168-
if (!p_dir.is_network_share_path()) {
169-
p_dir = "\\\\?\\" + p_dir;
170-
// Add "\\?\" to the path to extend max. path length past 248, if it's not a network share UNC path.
171-
// See https://msdn.microsoft.com/en-us/library/windows/desktop/aa363855(v=vs.85).aspx
172-
}
173-
174177
success = CreateDirectoryW((LPCWSTR)(p_dir.utf16().get_data()), nullptr);
175178
err = GetLastError();
176179

drivers/windows/dir_access_windows.h

+3
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,9 @@ class DirAccessWindows : public DirAccess {
5353
bool _cisdir = false;
5454
bool _cishidden = false;
5555

56+
protected:
57+
virtual String fix_path(String p_path) const override;
58+
5659
public:
5760
virtual Error list_dir_begin() override; ///< This starts dir listing
5861
virtual String get_next() override;

drivers/windows/file_access_windows.cpp

+8
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,14 @@ bool FileAccessWindows::is_path_invalid(const String &p_path) {
6868
return invalid_files.has(fname);
6969
}
7070

71+
String FileAccessWindows::fix_path(const String &p_path) const {
72+
String r_path = FileAccess::fix_path(p_path);
73+
if (r_path.is_absolute_path() && !r_path.is_network_share_path() && r_path.length() > MAX_PATH) {
74+
r_path = "\\\\?\\" + r_path.replace("/", "\\");
75+
}
76+
return r_path;
77+
}
78+
7179
Error FileAccessWindows::open_internal(const String &p_path, int p_mode_flags) {
7280
if (is_path_invalid(p_path)) {
7381
#ifdef DEBUG_ENABLED

drivers/windows/file_access_windows.h

+1
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ class FileAccessWindows : public FileAccess {
5454
static HashSet<String> invalid_files;
5555

5656
public:
57+
virtual String fix_path(const String &p_path) const override;
5758
virtual Error open_internal(const String &p_path, int p_mode_flags) override; ///< open a file
5859
virtual bool is_open() const override; ///< true when file is open
5960

0 commit comments

Comments
 (0)