Skip to content

Commit

Permalink
Merge pull request #61985 from bruvzg/win_net_share3
Browse files Browse the repository at this point in the history
[Windows, 3.x] Add support for handling network share paths.
  • Loading branch information
akien-mga authored Jun 13, 2022
2 parents 8c53dd2 + 11a7997 commit 606ec57
Show file tree
Hide file tree
Showing 8 changed files with 69 additions and 15 deletions.
8 changes: 6 additions & 2 deletions core/os/dir_access.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -148,14 +148,18 @@ Error DirAccess::make_dir_recursive(String p_dir) {

full_dir = full_dir.replace("\\", "/");

//int slices = full_dir.get_slice_count("/");

String base;

if (full_dir.begins_with("res://")) {
base = "res://";
} else if (full_dir.begins_with("user://")) {
base = "user://";
} else if (full_dir.is_network_share_path()) {
int pos = full_dir.find("/", 2);
ERR_FAIL_COND_V(pos < 0, ERR_INVALID_PARAMETER);
pos = full_dir.find("/", pos + 1);
ERR_FAIL_COND_V(pos < 0, ERR_INVALID_PARAMETER);
base = full_dir.substr(0, pos + 1);
} else if (full_dir.begins_with("/")) {
base = "/";
} else if (full_dir.find(":/") != -1) {
Expand Down
30 changes: 27 additions & 3 deletions core/ustring.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3268,6 +3268,10 @@ String String::rstrip(const String &p_chars) const {
return substr(0, end + 1);
}

bool String::is_network_share_path() const {
return begins_with("//") || begins_with("\\\\");
}

String String::simplify_path() const {
String s = *this;
String drive;
Expand All @@ -3280,6 +3284,9 @@ String String::simplify_path() const {
} else if (s.begins_with("user://")) {
drive = "user://";
s = s.substr(7, s.length());
} else if (is_network_share_path()) {
drive = s.substr(0, 2);
s = s.substr(2, s.length() - 2);
} else if (s.begins_with("/") || s.begins_with("\\")) {
drive = s.substr(0, 1);
s = s.substr(1, s.length() - 1);
Expand Down Expand Up @@ -4017,13 +4024,13 @@ bool String::is_rel_path() const {
String String::get_base_dir() const {
int end = 0;

// url scheme style base
// URL scheme style base.
int basepos = find("://");
if (basepos != -1) {
end = basepos + 3;
}

// windows top level directory base
// Windows top level directory base.
if (end == 0) {
basepos = find(":/");
if (basepos == -1) {
Expand All @@ -4034,7 +4041,24 @@ String String::get_base_dir() const {
}
}

// unix root directory base
// Windows UNC network share path.
if (end == 0) {
if (is_network_share_path()) {
basepos = find("/", 2);
if (basepos == -1) {
basepos = find("\\", 2);
}
int servpos = find("/", basepos + 1);
if (servpos == -1) {
servpos = find("\\", basepos + 1);
}
if (servpos != -1) {
end = servpos + 1;
}
}
}

// Unix root directory base.
if (end == 0) {
if (begins_with("/")) {
end = 1;
Expand Down
1 change: 1 addition & 0 deletions core/ustring.h
Original file line number Diff line number Diff line change
Expand Up @@ -329,6 +329,7 @@ class String {
String get_file() const;
static String humanize_size(uint64_t p_size);
String simplify_path() const;
bool is_network_share_path() const;

String xml_escape(bool p_escape_quotes = false) const;
String xml_unescape() const;
Expand Down
11 changes: 9 additions & 2 deletions drivers/windows/dir_access_windows.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -159,8 +159,11 @@ Error DirAccessWindows::make_dir(String p_dir) {
bool success;
int err;

p_dir = "\\\\?\\" + p_dir; //done according to
// https://msdn.microsoft.com/en-us/library/windows/desktop/aa363855(v=vs.85).aspx
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(p_dir.c_str(), NULL);
err = GetLastError();
Expand Down Expand Up @@ -344,6 +347,10 @@ uint64_t DirAccessWindows::get_space_left() {
String DirAccessWindows::get_filesystem_type() const {
String path = fix_path(const_cast<DirAccessWindows *>(this)->get_current_dir());

if (path.is_network_share_path()) {
return "Network Share";
}

int unit_end = path.find(":");
ERR_FAIL_COND_V(unit_end == -1, String());
String unit = path.substr(0, unit_end + 1) + "\\";
Expand Down
15 changes: 12 additions & 3 deletions editor/editor_file_dialog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,14 @@ Vector<String> EditorFileDialog::get_selected_files() const {

void EditorFileDialog::update_dir() {
if (drives->is_visible()) {
drives->select(dir_access->get_current_drive());
if (dir_access->get_current_dir().is_network_share_path()) {
_update_drives(false);
drives->add_item(RTR("Network"));
drives->set_item_disabled(drives->get_item_count() - 1, true);
drives->select(drives->get_item_count() - 1);
} else {
drives->select(dir_access->get_current_drive());
}
}
dir->set_text(dir_access->get_current_dir_without_drive());

Expand Down Expand Up @@ -1125,7 +1132,7 @@ void EditorFileDialog::_select_drive(int p_idx) {
_push_history();
}

void EditorFileDialog::_update_drives() {
void EditorFileDialog::_update_drives(bool p_select) {
int dc = dir_access->get_drive_count();
if (dc == 0 || access != ACCESS_FILESYSTEM) {
drives->hide();
Expand All @@ -1144,7 +1151,9 @@ void EditorFileDialog::_update_drives() {
drives->add_item(dir_access->get_drive(i));
}

drives->select(dir_access->get_current_drive());
if (p_select) {
drives->select(dir_access->get_current_drive());
}
}
}

Expand Down
2 changes: 1 addition & 1 deletion editor/editor_file_dialog.h
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@ class EditorFileDialog : public ConfirmationDialog {

void _delete_items();

void _update_drives();
void _update_drives(bool p_select = true);

void _go_up();
void _go_back();
Expand Down
15 changes: 12 additions & 3 deletions scene/gui/file_dialog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,14 @@ void FileDialog::update_dir() {
dir->set_text(dir_access->get_current_dir_without_drive());

if (drives->is_visible()) {
drives->select(dir_access->get_current_drive());
if (dir_access->get_current_dir().is_network_share_path()) {
_update_drives(false);
drives->add_item(RTR("Network"));
drives->set_item_disabled(drives->get_item_count() - 1, true);
drives->select(drives->get_item_count() - 1);
} else {
drives->select(dir_access->get_current_drive());
}
}

// Deselect any item, to make "Select Current Folder" button text by default.
Expand Down Expand Up @@ -749,7 +756,7 @@ void FileDialog::_select_drive(int p_idx) {
update_dir();
}

void FileDialog::_update_drives() {
void FileDialog::_update_drives(bool p_select) {
int dc = dir_access->get_drive_count();
if (dc == 0 || access != ACCESS_FILESYSTEM) {
drives->hide();
Expand All @@ -767,7 +774,9 @@ void FileDialog::_update_drives() {
drives->add_item(dir_access->get_drive(i));
}

drives->select(dir_access->get_current_drive());
if (p_select) {
drives->select(dir_access->get_current_drive());
}
}
}

Expand Down
2 changes: 1 addition & 1 deletion scene/gui/file_dialog.h
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ class FileDialog : public ConfirmationDialog {
void _make_dir_confirm();
void _go_up();

void _update_drives();
void _update_drives(bool p_select = true);

void _unhandled_input(const Ref<InputEvent> &p_event);

Expand Down

0 comments on commit 606ec57

Please sign in to comment.