Andrew Eikum : kernel32: Support extended pathnames in GetShortPathName.

Alexandre Julliard julliard at wine.codeweavers.com
Wed May 6 09:29:03 CDT 2015


Module: wine
Branch: master
Commit: 65f2690203089d55339cd2feca6e09b35dbc574a
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=65f2690203089d55339cd2feca6e09b35dbc574a

Author: Andrew Eikum <aeikum at codeweavers.com>
Date:   Tue May  5 13:17:17 2015 -0500

kernel32: Support extended pathnames in GetShortPathName.

---

 dlls/kernel32/path.c       | 28 +++++++++++++++++++++++-----
 dlls/kernel32/tests/path.c | 25 ++++++++++++++++++++-----
 2 files changed, 43 insertions(+), 10 deletions(-)

diff --git a/dlls/kernel32/path.c b/dlls/kernel32/path.c
index c2833b1..179c8e0 100644
--- a/dlls/kernel32/path.c
+++ b/dlls/kernel32/path.c
@@ -440,7 +440,7 @@ DWORD WINAPI GetLongPathNameA( LPCSTR shortpath, LPSTR longpath, DWORD longlen )
  */
 DWORD WINAPI GetShortPathNameW( LPCWSTR longpath, LPWSTR shortpath, DWORD shortlen )
 {
-    WCHAR               tmpshortpath[MAX_PATHNAME_LEN];
+    WCHAR               *tmpshortpath;
     LPCWSTR             p;
     DWORD               sp = 0, lp = 0;
     DWORD               tmplen;
@@ -460,12 +460,28 @@ DWORD WINAPI GetShortPathNameW( LPCWSTR longpath, LPWSTR shortpath, DWORD shortl
         return 0;
     }
 
+    /* code below only removes characters from string, never adds, so this is
+     * the largest buffer that tmpshortpath will need to have */
+    tmpshortpath = HeapAlloc(GetProcessHeap(), 0, (strlenW(longpath) + 1) * sizeof(WCHAR));
+    if (!tmpshortpath)
+    {
+        SetLastError(ERROR_OUTOFMEMORY);
+        return 0;
+    }
+
+    if (longpath[0] == '\\' && longpath[1] == '\\' && longpath[2] == '?' && longpath[3] == '\\')
+    {
+        memcpy(tmpshortpath, longpath, 4 * sizeof(WCHAR));
+        sp = lp = 4;
+    }
+
     /* check for drive letter */
-    if (longpath[0] != '/' && longpath[1] == ':' )
+    if (longpath[lp] != '/' && longpath[lp + 1] == ':' )
     {
-        tmpshortpath[0] = longpath[0];
-        tmpshortpath[1] = ':';
-        sp = lp = 2;
+        tmpshortpath[sp] = longpath[lp];
+        tmpshortpath[sp + 1] = ':';
+        sp += 2;
+        lp += 2;
     }
 
     while (longpath[lp])
@@ -522,9 +538,11 @@ DWORD WINAPI GetShortPathNameW( LPCWSTR longpath, LPWSTR shortpath, DWORD shortl
         tmplen--; /* length without 0 */
     }
 
+    HeapFree(GetProcessHeap(), 0, tmpshortpath);
     return tmplen;
 
  notfound:
+    HeapFree(GetProcessHeap(), 0, tmpshortpath);
     TRACE("not found!\n" );
     SetLastError ( ERROR_FILE_NOT_FOUND );
     return 0;
diff --git a/dlls/kernel32/tests/path.c b/dlls/kernel32/tests/path.c
index cdb565a..de6d92a 100644
--- a/dlls/kernel32/tests/path.c
+++ b/dlls/kernel32/tests/path.c
@@ -1343,29 +1343,44 @@ static void test_GetLongPathNameW(void)
 
 static void test_GetShortPathNameW(void)
 {
-    WCHAR test_path[] = { 'L', 'o', 'n', 'g', 'D', 'i', 'r', 'e', 'c', 't', 'o', 'r', 'y', 'N', 'a', 'm', 'e',  0 };
-    WCHAR path[MAX_PATH];
+    static const WCHAR extended_prefix[] = {'\\','\\','?','\\',0};
+    static const WCHAR test_path[] = { 'L', 'o', 'n', 'g', 'D', 'i', 'r', 'e', 'c', 't', 'o', 'r', 'y', 'N', 'a', 'm', 'e',  0 };
+    static const WCHAR name[] = { 't', 'e', 's', 't', 0 };
+    static const WCHAR backSlash[] = { '\\', 0 };
+    WCHAR path[MAX_PATH], tmppath[MAX_PATH];
     WCHAR short_path[MAX_PATH];
     DWORD length;
     HANDLE file;
     int ret;
-    WCHAR name[] = { 't', 'e', 's', 't', 0 };
-    WCHAR backSlash[] = { '\\', 0 };
 
     SetLastError(0xdeadbeef);
-    GetTempPathW( MAX_PATH, path );
+    GetTempPathW( MAX_PATH, tmppath );
     if (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
     {
         win_skip("GetTempPathW is not implemented\n");
         return;
     }
 
+    lstrcpyW( path, tmppath );
     lstrcatW( path, test_path );
     lstrcatW( path, backSlash );
     ret = CreateDirectoryW( path, NULL );
     ok( ret, "Directory was not created. LastError = %d\n", GetLastError() );
 
     /* Starting a main part of test */
+
+    /* extended path \\?\C:\path\ */
+    lstrcpyW( path, extended_prefix );
+    lstrcatW( path, tmppath );
+    lstrcatW( path, test_path );
+    lstrcatW( path, backSlash );
+    short_path[0] = 0;
+    length = GetShortPathNameW( path, short_path, sizeof(short_path) / sizeof(*short_path) );
+    ok( length, "GetShortPathNameW returned 0.\n" );
+
+    lstrcpyW( path, tmppath );
+    lstrcatW( path, test_path );
+    lstrcatW( path, backSlash );
     length = GetShortPathNameW( path, short_path, 0 );
     ok( length, "GetShortPathNameW returned 0.\n" );
     ret = GetShortPathNameW( path, short_path, length );




More information about the wine-cvs mailing list