kernel32: GetShortPathName for a non-existent short file name should fail. Resend.

Dmitry Timoshkov dmitry at baikal.ru
Fri Jul 19 00:02:38 CDT 2013


GetLongPathName already handles this case correctly, and appropriate code
was simply copied from GetLongPathName implementation.

This patch fixes several installers which call GetShortPathName before
installing a file and currently don't install anything.
---
 dlls/kernel32/path.c       | 24 ++++++++----------------
 dlls/kernel32/tests/path.c |  2 --
 2 files changed, 8 insertions(+), 18 deletions(-)

diff --git a/dlls/kernel32/path.c b/dlls/kernel32/path.c
index 63d977b..f1a2612 100644
--- a/dlls/kernel32/path.c
+++ b/dlls/kernel32/path.c
@@ -485,29 +485,21 @@ DWORD WINAPI GetShortPathNameW( LPCWSTR longpath, LPWSTR shortpath, DWORD shortl
             continue;
         }
 
-        for (p = longpath + lp; *p && *p != '/' && *p != '\\'; p++);
-        tmplen = p - (longpath + lp);
-        lstrcpynW(tmpshortpath + sp, longpath + lp, tmplen + 1);
-        /* Check, if the current element is a valid dos name */
-        if (tmplen <= 8+1+3)
+        p = longpath + lp;
+        if (lp == 0 && p[0] == '.' && (p[1] == '/' || p[1] == '\\'))
         {
-            BOOLEAN spaces;
-            memcpy(ustr_buf, longpath + lp, tmplen * sizeof(WCHAR));
-            ustr_buf[tmplen] = '\0';
-            ustr.Length = tmplen * sizeof(WCHAR);
-            if (RtlIsNameLegalDOS8Dot3(&ustr, NULL, &spaces) && !spaces)
-            {
-                sp += tmplen;
-                lp += tmplen;
-                continue;
-            }
+            tmpshortpath[sp++] = *p++;
+            tmpshortpath[sp++] = *p++;
         }
+        for (; *p && *p != '/' && *p != '\\'; p++);
+        tmplen = p - (longpath + lp);
+        lstrcpynW(tmpshortpath + sp, longpath + lp, tmplen + 1);
 
         /* Check if the file exists and use the existing short file name */
         goit = FindFirstFileW(tmpshortpath, &wfd);
         if (goit == INVALID_HANDLE_VALUE) goto notfound;
         FindClose(goit);
-        strcpyW(tmpshortpath + sp, wfd.cAlternateFileName);
+        strcpyW(tmpshortpath + sp, wfd.cAlternateFileName[0] ? wfd.cAlternateFileName : wfd.cFileName);
         sp += strlenW(tmpshortpath + sp);
         lp += tmplen;
     }
diff --git a/dlls/kernel32/tests/path.c b/dlls/kernel32/tests/path.c
index d703aa9..c49a76f 100644
--- a/dlls/kernel32/tests/path.c
+++ b/dlls/kernel32/tests/path.c
@@ -1281,9 +1281,7 @@ static void test_GetShortPathNameW(void)
     /* GetShortPathName for a non-existent short file name should fail */
     SetLastError(0xdeadbeef);
     length = GetShortPathNameW( short_path, path, 0 );
-todo_wine
     ok(!length, "GetShortPathNameW should fail\n");
-todo_wine
     ok(GetLastError() == ERROR_FILE_NOT_FOUND, "expected ERROR_FILE_NOT_FOUND, got %d\n", GetLastError());
 
     file = CreateFileW( short_path, GENERIC_READ|GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );
-- 
1.8.3.2




More information about the wine-patches mailing list