Page MenuHome

uncpaths_elubie.diff

File Metadata

Author
Andrea Weikert (elubie)
Created
Feb 8 2014, 5:39 PM

uncpaths_elubie.diff

diff --git a/source/blender/blenlib/BLI_path_util.h b/source/blender/blenlib/BLI_path_util.h
index efc5731..506d622 100644
--- a/source/blender/blenlib/BLI_path_util.h
+++ b/source/blender/blenlib/BLI_path_util.h
@@ -166,6 +166,11 @@ void BLI_path_rel(char *file, const char *relfile) ATTR_NONNULL();
bool BLI_path_is_rel(const char *path) ATTR_NONNULL() ATTR_WARN_UNUSED_RESULT;
+#if defined(WIN32)
+ bool BLI_path_is_abs(const char *path);
+ bool BLI_path_is_unc(const char *path);
+#endif
+
/* path string comparisons: case-insensitive for Windows, case-sensitive otherwise */
#if defined(WIN32)
# define BLI_path_cmp BLI_strcasecmp
diff --git a/source/blender/blenlib/intern/path_util.c b/source/blender/blenlib/intern/path_util.c
index e56ac6f..afcec57 100644
--- a/source/blender/blenlib/intern/path_util.c
+++ b/source/blender/blenlib/intern/path_util.c
@@ -394,7 +394,7 @@ void BLI_cleanup_path(const char *relabase, char *path)
memmove(start, eind, strlen(eind) + 1);
}
- while ( (start = strstr(path, "\\\\")) ) {
+ while ( (start = strstr(path+2, "\\\\")) ) {
eind = start + strlen("\\\\") - 1;
memmove(start, eind, strlen(eind) + 1);
}
@@ -463,6 +463,24 @@ bool BLI_path_is_rel(const char *path)
return path[0] == '/' && path[1] == '/';
}
+#ifdef WIN32
+/* return true if the path is a UNC share */
+bool BLI_path_is_unc(const char *name)
+{
+ if (name == NULL || strlen(name) < 4)
+ return 0;
+ return name[0] == '\\' && name[1] == '\\';
+}
+
+/* return true if the path is absolute ie starts with a drive specifier (eg A:\) or is a UNC path */
+bool BLI_path_is_abs(const char *name)
+{
+ if (name == NULL || strlen(name) < 3)
+ return 0;
+ return (name[1] == ':' && (name[2] =='\\' || name[2] =='/') ) || BLI_path_is_unc(name);
+}
+#endif
+
/**
* Replaces *file with a relative version (prefixed by "//") such that BLI_path_abs, given
* the same *relfile, will convert it back to its original value.
@@ -484,7 +502,7 @@ void BLI_path_rel(char *file, const char *relfile)
}
#ifdef WIN32
- if (BLI_strnlen(relfile, 3) > 2 && relfile[1] != ':') {
+ if (BLI_strnlen(relfile, 3) > 2 && !BLI_path_is_abs(relfile)) {
char *ptemp;
/* fix missing volume name in relative base,
* can happen with old recent-files.txt files */
@@ -500,8 +518,28 @@ void BLI_path_rel(char *file, const char *relfile)
}
if (BLI_strnlen(file, 3) > 2) {
- if (temp[1] == ':' && file[1] == ':' && temp[0] != file[0])
+ /* Ensure paths are both UNC paths or are both drives */
+ if ((BLI_path_is_unc(temp) && !BLI_path_is_unc(file)) ||
+ (!BLI_path_is_unc(temp) && BLI_path_is_unc(file)))
+ return;
+
+ /* Ensure both UNC paths are on the same share */
+ if (BLI_path_is_unc(temp) && BLI_path_is_unc(file))
+ {
+ int off;
+ int slash = 0;
+ for (off = 0; temp[off] && slash < 4; off++)
+ {
+ if (temp[off] != file[off])
+ return;
+
+ if (temp[off] == '\\')
+ slash++;
+ }
+ }
+ else if (temp[1] == ':' && file[1] == ':' && temp[0] != file[0]) {
return;
+ }
}
#else
BLI_strncpy(temp, relfile, FILE_MAX);
@@ -727,7 +765,7 @@ bool BLI_path_abs(char *path, const char *basepath)
* blend file as a lib main - we are basically checking for the case that a
* UNIX root '/' is passed.
*/
- if (!wasrelative && (vol[1] != ':' && (vol[0] == '\0' || vol[0] == '/' || vol[0] == '\\'))) {
+ if (!wasrelative && !BLI_path_is_abs(path)) {
char *p = path;
get_default_root(tmp);
// get rid of the slashes at the beginning of the path
@@ -757,24 +795,25 @@ bool BLI_path_abs(char *path, const char *basepath)
#endif
- BLI_strncpy(base, basepath, sizeof(base));
-
- /* file component is ignored, so don't bother with the trailing slash */
- BLI_cleanup_path(NULL, base);
-
/* push slashes into unix mode - strings entering this part are
* potentially messed up: having both back- and forward slashes.
* Here we push into one conform direction, and at the end we
* push them into the system specific dir. This ensures uniformity
* of paths and solving some problems (and prevent potential future
* ones) -jesterKing. */
- BLI_char_switch(tmp, '\\', '/');
- BLI_char_switch(base, '\\', '/');
+ BLI_char_switch(tmp+2, '\\', '/');
/* Paths starting with // will get the blend file as their base,
* this isn't standard in any os but is used in blender all over the place */
if (wasrelative) {
- const char * const lslash = BLI_last_slash(base);
+ const char * lslash;
+ BLI_strncpy(base, basepath, sizeof(base));
+
+ /* file component is ignored, so don't bother with the trailing slash */
+ BLI_cleanup_path(NULL, base);
+ lslash = BLI_last_slash(base);
+ BLI_char_switch(base, '\\', '/');
+
if (lslash) {
const int baselen = (int) (lslash - base) + 1; /* length up to and including last "/" */
/* use path for temp storage here, we copy back over it right away */
@@ -823,7 +862,7 @@ bool BLI_path_cwd(char *path)
const int filelen = strlen(path);
#ifdef WIN32
- if (filelen >= 3 && path[1] == ':' && (path[2] == '\\' || path[2] == '/'))
+ if ( (filelen >= 3 && BLI_path_is_abs(path)) || BLI_path_is_unc(path))
wasrelative = false;
#else
if (filelen >= 2 && path[0] == '/')
@@ -1486,8 +1525,11 @@ void BLI_make_file_string(const char *relabase, char *string, const char *dir, c
BLI_strncpy(string, dir, 3);
dir += 2;
}
+ else if (strlen(dir) >= 2 && BLI_path_is_unc(dir)) {
+ string[0]= 0;
+ }
else { /* no drive specified */
- /* first option: get the drive from the relabase if it has one */
+ /* first option: get the drive from the relabase if it has one */
if (relabase && strlen(relabase) >= 2 && relabase[1] == ':') {
BLI_strncpy(string, relabase, 3);
string[2] = '\\';
diff --git a/source/blender/blenlib/intern/storage.c b/source/blender/blenlib/intern/storage.c
index de40cab..b68fea7 100644
--- a/source/blender/blenlib/intern/storage.c
+++ b/source/blender/blenlib/intern/storage.c
@@ -481,13 +481,31 @@ int BLI_exists(const char *name)
/* in Windows stat doesn't recognize dir ending on a slash
* To not break code where the ending slash is expected we
* don't mess with the argument name directly here - elubie */
- wchar_t *tmp_16 = alloc_utf16_from_8(name, 0);
+ wchar_t *tmp_16 = alloc_utf16_from_8(name, 1);
int len, res;
unsigned int old_error_mode;
len = wcslen(tmp_16);
- if (len > 3 && (tmp_16[len - 1] == L'\\' || tmp_16[len - 1] == L'/'))
+ if (len > 3 && (tmp_16[len - 1] == L'\\' || tmp_16[len - 1] == L'/')) {
tmp_16[len - 1] = '\0';
+ }
+ if (len >= 3) {
+ if ( (tmp_16[0] == L'\\') && (tmp_16[1] == L'\\') ) {
+ wchar_t *share = &tmp_16[2];
+ wchar_t *folder;
+ while (*share && *share != L'\\') share++;
+ folder = (*share) ? share : share+1;
+ while (*folder && *folder != L'\\') folder++;
+ if ( (*folder) == L'\0') {
+ (*folder) = L'\\';
+ folder++;
+ (*(folder+1)) = L'\0';
+ }
+ } else if ( (tmp_16[1] == L':') && (tmp_16[2] == L'\0') ) {
+ tmp_16[2] = L'\\';
+ tmp_16[3] = L'\0';
+ }
+ }
/* change error mode so user does not get a "no disk in drive" popup
* when looking for a file on an empty CD/DVD drive */
diff --git a/source/blender/editors/space_file/file_ops.c b/source/blender/editors/space_file/file_ops.c
index 94f6174..6da9e4a 100644
--- a/source/blender/editors/space_file/file_ops.c
+++ b/source/blender/editors/space_file/file_ops.c
@@ -1176,6 +1176,27 @@ static void file_expand_directory(bContext *C)
if (G.relbase_valid && BLI_path_is_rel(sfile->params->dir)) {
BLI_path_abs(sfile->params->dir, G.main->name);
}
+#ifdef WIN32
+ else if (BLI_path_is_unc(sfile->params->dir)) {
+ char unc[4096];
+ const char *path = NULL;
+
+ _fullpath(unc, sfile->params->dir, sizeof(unc));
+
+ path = unc+2; // start of the server name
+ if (*path != '\0') {
+ path = BLI_first_slash(path); // end of the server name, start of share name
+ if (path != NULL) {
+ path = BLI_first_slash(path+1); // end of share, start of path
+ if (path == NULL) { // if no path found add '\' since it is a directory and not a file
+ strcat(unc, "\\");
+ }
+ }
+ }
+
+ BLI_strncpy(sfile->params->dir, unc, sizeof(sfile->params->dir));
+ }
+#endif
else if (sfile->params->dir[0] == '~') {
char tmpstr[sizeof(sfile->params->dir) - 1];
BLI_strncpy(tmpstr, sfile->params->dir + 1, sizeof(tmpstr));

Event Timeline