Fix winepath --unix so it works whether the Windows path refers to an existing file/directory or not.

Francois Gouget fgouget at codeweavers.com
Fri Nov 10 08:40:59 CST 2006


---

Currently the behavior of the --windows and --unix options is 
inconsistent:

$ winepath --windows /foo
z:\foo
$ winepath --unix z:\\foo
/foo
$ winepath --windows /foo/bar
z:\foo\bar
$ winepath --unix z:\\foo\\bar
        <--- empty string here


--windows converts paths to the Windows format no matter whether they 
refer to existing files or not, which is as script writers would expect.

But, as seen in the above example, --unix only converts paths that refer 
to existing files/directories, or to nonexistent files/directories with 
an existing parent directory. This is because that's how the ntdll 
function that does the conversion is supposed to behave. However the 
specific behavior of this ntdll function is irrelevant to the writers of 
bash scripts, it makes the --unix behavior inconsistent with the 
behavior of the --windows option, and does not match the winepath usage.

So this patch modifies the --unix implementation to convert all valid 
Windows paths to the Unix format as per the current winepath usage.


 programs/winepath/winepath.c |   59 ++++++++++++++++++++++++++++++++++++++----
 1 files changed, 53 insertions(+), 6 deletions(-)

diff --git a/programs/winepath/winepath.c b/programs/winepath/winepath.c
index 0fc4623..7179214 100644
--- a/programs/winepath/winepath.c
+++ b/programs/winepath/winepath.c
@@ -189,14 +189,61 @@ int wmain(int argc, const WCHAR *argv[])
             printf("%s\n", path);
         }
         if (outputformats & UNIXFORMAT) {
-            char *unix_name;
-
-            if ((unix_name = wine_get_unix_file_name_ptr(argv[i])))
+            WCHAR *ntpath, *tail;
+            int ntpathlen=lstrlenW(argv[i]);
+            ntpath=HeapAlloc(GetProcessHeap(), 0, sizeof(*ntpath)*(ntpathlen+1));
+            lstrcpyW(ntpath, argv[i]);
+            tail=NULL;
+            while (1)
             {
-                printf("%s\n", unix_name);
-                HeapFree( GetProcessHeap(), 0, unix_name );
+                char *unix_name;
+                WCHAR *slash, *c;
+
+                unix_name = wine_get_unix_file_name_ptr(ntpath);
+                if (unix_name)
+                {
+                    if (tail)
+                    {
+                        WideCharToMultiByte(CP_UNIXCP, 0, tail+1, -1, path, MAX_PATH, NULL, NULL);
+                        printf("%s/%s\n", unix_name, path);
+                    }
+                    else
+                    {
+                        printf("%s\n", unix_name);
+                    }
+                    HeapFree( GetProcessHeap(), 0, unix_name );
+                    break;
+                }
+
+                slash=(tail ? tail : ntpath+ntpathlen);
+                while (slash != ntpath && *slash != '/' && *slash != '\\')
+                    slash--;
+                if (slash == ntpath)
+                {
+                    /* This is a complete path conversion failure.
+                     * It would typically happen if ntpath == "".
+                     */
+                    printf("\n");
+                    break;
+                }
+                c=slash+1;
+                while (*c != '\0' && *c != '*' && *c != '?' &&
+                       *c != '<' && *c != '>' && *c != '|' && *c != '"')
+                    c++;
+                if (*c != '\0')
+                {
+                    /* If this is not a valid NT path to start with,
+                     * then obviously we cannot convert it.
+                     */
+                    printf("\n");
+                    break;
+                }
+                if (tail)
+                    *tail='/';
+                tail=slash;
+                *tail='\0';
             }
-            else printf( "\n" );
+            HeapFree(GetProcessHeap(), 0, ntpath);
         }
         if (outputformats & WINDOWSFORMAT) {
             WCHAR* windows_name;
-- 
1.4.1.1




More information about the wine-patches mailing list