浏览代码

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
Samuele Panzeri 2 年之前
父节点
当前提交
59f04e16b8

+ 1 - 1
core/io/dir_access.h

@@ -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() {

+ 1 - 1
core/io/file_access.h

@@ -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);

+ 9 - 6
drivers/windows/dir_access_windows.cpp

@@ -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();
 

+ 3 - 0
drivers/windows/dir_access_windows.h

@@ -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;

+ 8 - 0
drivers/windows/file_access_windows.cpp

@@ -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

+ 1 - 0
drivers/windows/file_access_windows.h

@@ -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