ChangeLog: Fix side-effect of converting slashes to backslashes in splitpath function. Support case where a colon is present in the filename or the extension. Description: Same fixes for _splitpath function in dlls/ntdll/string.c and _wsplitpath in dlls/msvcrt/dir.c. If at least a slash has been converted to a backslash in the input path, use slashes in the directory output parameter. Change the way we look for the drive in the input path by only looking at the first and second characters for the occurence of a colon instead of doing a string search (strchr) since on most Unix systems, the colon is a valid filename character. Warren Baird : Warren_Baird@cimmetry.com Dave Belanger diff -ur clean/wine/dlls/ntdll/string.c wine/dlls/ntdll/string.c --- clean/wine/dlls/ntdll/string.c Wed Jan 29 15:30:36 2003 +++ wine/dlls/ntdll/string.c Tue Dec 17 17:08:37 2002 @@ -118,31 +118,38 @@ /* Modified PD code from 'snippets' collection. */ char ch, *ptr, *p; char pathbuff[MAX_PATH], *path=pathbuff; + int swapSlashes = 0; strcpy(pathbuff, inpath); /* convert slashes to backslashes for searching */ - for (ptr = (char*)path; *ptr; ++ptr) - if ('/' == *ptr) - *ptr = '\\'; + for (ptr = (char*)path; *ptr; ++ptr) { + if ('/' == *ptr) { + *ptr = '\\'; + swapSlashes = 1; + } + } /* look for drive spec */ - if ('\0' != (ptr = strchr(path, ':'))) + ptr = path; + if (path[0] == ':') { - ++ptr; - if (drv) - { - strncpy(drv, path, ptr - path); - drv[ptr - path] = '\0'; - } - path = ptr; + ptr = path+1; } - else if (drv) - *drv = '\0'; + else if (path[1] == ':') + { + ptr = path+2; + } + + if (drv) + { + strncpy(drv, path, ptr - path); + drv[ptr - path] = '\0'; + } + path = ptr; - /* find rightmost backslash or leftmost colon */ - if (NULL == (ptr = strrchr(path, '\\'))) - ptr = (strchr(path, ':')); + /* find rightmost backslash */ + ptr = strrchr(path, '\\'); if (!ptr) { @@ -193,4 +200,15 @@ strcpy(dir,pathbuff); } } + + if (swapSlashes && dir) { + /* convert backslashes back to slashes */ + for (ptr = (char*)dir; *ptr; ++ptr) { + if ('\\' == *ptr) { + *ptr = '/'; + } + } + + } + } diff -ur clean/wine/dlls/msvcrt/dir.c wine/dlls/msvcrt/dir.c --- clean/wine/dlls/msvcrt/dir.c Wed Jan 29 15:30:35 2003 +++ wine/dlls/msvcrt/dir.c Mon Feb 3 11:55:13 2003 @@ -432,6 +432,7 @@ /* Modified PD code from 'snippets' collection. */ MSVCRT_wchar_t ch, *ptr, *p; MSVCRT_wchar_t pathbuff[MAX_PATH],*path=pathbuff; + int swapSlashes = 0; TRACE(":splitting path %s\n",debugstr_w(path)); /* FIXME: Should be an strncpyW or something */ @@ -440,25 +441,31 @@ /* convert slashes to backslashes for searching */ for (ptr = (MSVCRT_wchar_t*)path; *ptr; ++ptr) if (*ptr == '/') + { *ptr = '\\'; + swapSlashes = 1; + } /* look for drive spec */ - if ((ptr = strchrW(path, ':')) != 0) + ptr = path; + if (path[0] == ':') { - ++ptr; - if (drv) - { - strncpyW(drv, path, ptr - path); - drv[ptr - path] = 0; - } - path = ptr; + ptr = path+1; + } + else if (path[1] == ':') + { + ptr = path+2; } - else if (drv) - *drv = 0; - /* find rightmost backslash or leftmost colon */ - if ((ptr = strrchrW(path, '\\')) == NULL) - ptr = (strchrW(path, ':')); + if (drv) + { + strncpyW(drv, path, ptr - path); + drv[ptr - path] = 0; + } + path = ptr; + + /* find rightmost backslash */ + ptr = strrchrW(path, '\\'); if (!ptr) { @@ -508,6 +515,16 @@ strcatW(pathbuff,dir); strcpyW(dir, pathbuff); } + } + + if (swapSlashes && dir) { + /* convert backslashes back to slashes */ + for (ptr = (WCHAR*)dir; *ptr; ++ptr) { + if ((WCHAR)L'\\' == *ptr) { + *ptr = (WCHAR)L'/'; + } + } + } }