kernel32: make wine_get_dos_file_name independent from drive mappings

Damjan Jovanovic damjan.jov at gmail.com
Wed Jul 21 04:21:18 CDT 2010


Changelog:
* kernel32: make wine_get_dos_file_name independent from drive mappings

... by returning \\?\unix/home/user/path/to/file.txt style paths.

Damjan Jovanovic
-------------- next part --------------
diff --git a/dlls/kernel32/path.c b/dlls/kernel32/path.c
index 0e69f91..4074b79 100644
--- a/dlls/kernel32/path.c
+++ b/dlls/kernel32/path.c
@@ -1776,22 +1776,67 @@ char * CDECL wine_get_unix_file_name( LPCWSTR dosW )
  */
 WCHAR * CDECL wine_get_dos_file_name( LPCSTR str )
 {
-    UNICODE_STRING nt_name;
-    ANSI_STRING unix_name;
-    NTSTATUS status;
-    DWORD len;
+    static const WCHAR unixW[] = {'\\','\\','?','\\','u','n','i','x',0};
+    char *unix_dir;
+    BOOL needs_free = FALSE;
+    INT len;
+    WCHAR *ret = NULL;
+
+    if (str[0] == '/')
+        unix_dir = (char*)str;
+    else
+    {
+        char *cwd;
+        int err = 0;
+        for (len = 4096; ; len *= 2)
+        {
+            cwd = HeapAlloc(GetProcessHeap(), 0, len);
+            if (cwd == NULL)
+            {
+                SetLastError(ERROR_OUTOFMEMORY);
+                return NULL;
+            }
+            if (getcwd(cwd, len))
+            {
+                break;
+            }
+            else
+            {
+                if (errno != ERANGE)
+                    err = errno;
+            }
+            HeapFree(GetProcessHeap(), 0, cwd);
+            if (err != 0)
+            {
+                SetLastError(ERROR_GEN_FAILURE);
+                return NULL;
+            }
+        }
+        len = strlen(cwd) + 1 + strlen(str) + 1;
+        unix_dir = HeapAlloc(GetProcessHeap(), 0, len);
+        if (unix_dir)
+        {
+            snprintf(unix_dir, len, "%s/%s", cwd, str);
+            needs_free = TRUE;
+        }
+        HeapFree(GetProcessHeap(), 0, cwd);
+        if (unix_dir == NULL)
+        {
+            SetLastError(ERROR_OUTOFMEMORY);
+            return NULL;
+        }
+    }
 
-    RtlInitAnsiString( &unix_name, str );
-    status = wine_unix_to_nt_file_name( &unix_name, &nt_name );
-    if (status)
+    len = MultiByteToWideChar(CP_UNIXCP, 0, unix_dir, -1, NULL, 0);
+    ret = HeapAlloc(GetProcessHeap(), 0, (8 + len + 1) * sizeof(WCHAR));
+    if (ret)
     {
-        SetLastError( RtlNtStatusToDosError( status ) );
-        return NULL;
+        strcpyW(ret, unixW);
+        MultiByteToWideChar(CP_UNIXCP, 0, unix_dir, -1, &ret[8], len);
     }
-    /* get rid of the \??\ prefix */
-    /* FIXME: should implement RtlNtPathNameToDosPathName and use that instead */
-    len = nt_name.Length - 4 * sizeof(WCHAR);
-    memmove( nt_name.Buffer, nt_name.Buffer + 4, len );
-    nt_name.Buffer[len / sizeof(WCHAR)] = 0;
-    return nt_name.Buffer;
+    else
+        SetLastError(ERROR_OUTOFMEMORY);
+    if (needs_free)
+        HeapFree(GetProcessHeap(), 0, unix_dir);
+    return ret;
 }


More information about the wine-patches mailing list