Nikolay Sivov : shell32: Implement PathYetAnotherMakeUniqueName().

Alexandre Julliard julliard at wine.codeweavers.com
Mon Jun 30 15:30:20 CDT 2014


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

Author: Nikolay Sivov <nsivov at codeweavers.com>
Date:   Sat Jun 28 15:43:06 2014 +0400

shell32: Implement PathYetAnotherMakeUniqueName().

---

 dlls/shell32/shellpath.c       | 37 +++++++++++++------
 dlls/shell32/tests/shellpath.c | 82 ++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 108 insertions(+), 11 deletions(-)

diff --git a/dlls/shell32/shellpath.c b/dlls/shell32/shellpath.c
index 2dfed75..158b1d1 100644
--- a/dlls/shell32/shellpath.c
+++ b/dlls/shell32/shellpath.c
@@ -537,22 +537,37 @@ BOOL WINAPI PathMakeUniqueNameAW(
 
 /*************************************************************************
  * PathYetAnotherMakeUniqueName [SHELL32.75]
- *
- * NOTES
- *     exported by ordinal
  */
-BOOL WINAPI PathYetAnotherMakeUniqueName(
-	LPWSTR lpszBuffer,
-	LPCWSTR lpszPathName,
-	LPCWSTR lpszShortName,
-	LPCWSTR lpszLongName)
+BOOL WINAPI PathYetAnotherMakeUniqueName(LPWSTR buffer, LPCWSTR path, LPCWSTR shortname, LPCWSTR longname)
 {
-    FIXME("(%p, %s, %s ,%s):stub.\n",
-          lpszBuffer, debugstr_w(lpszPathName), debugstr_w(lpszShortName), debugstr_w(lpszLongName));
+    WCHAR pathW[MAX_PATH], retW[MAX_PATH];
+    const WCHAR *file, *ext;
+    int i = 2;
+
+    TRACE("(%p, %s, %s, %s)\n", buffer, debugstr_w(path), debugstr_w(shortname), debugstr_w(longname));
+
+    file = longname ? longname : shortname;
+    PathCombineW(pathW, path, file);
+    strcpyW(retW, pathW);
+    PathRemoveExtensionW(pathW);
+
+    ext = PathFindExtensionW(file);
+
+    /* now try to make it unique */
+    while (PathFileExistsW(retW))
+    {
+        static const WCHAR fmtW[] = {'%','s',' ','(','%','d',')','%','s',0};
+
+        sprintfW(retW, fmtW, pathW, i, ext);
+        i++;
+    }
+
+    strcpyW(buffer, retW);
+    TRACE("ret - %s\n", debugstr_w(buffer));
+
     return TRUE;
 }
 
-
 /*
 	########## cleaning and resolving paths ##########
  */
diff --git a/dlls/shell32/tests/shellpath.c b/dlls/shell32/tests/shellpath.c
index 7486fac..efdfbbd 100644
--- a/dlls/shell32/tests/shellpath.c
+++ b/dlls/shell32/tests/shellpath.c
@@ -101,6 +101,7 @@ static UINT (WINAPI *pGetSystemWow64DirectoryA)(LPSTR,UINT);
 static HRESULT (WINAPI *pSHGetKnownFolderPath)(REFKNOWNFOLDERID, DWORD, HANDLE, PWSTR *);
 static HRESULT (WINAPI *pSHSetKnownFolderPath)(REFKNOWNFOLDERID, DWORD, HANDLE, PWSTR);
 static HRESULT (WINAPI *pSHGetFolderPathEx)(REFKNOWNFOLDERID, DWORD, HANDLE, LPWSTR, DWORD);
+static BOOL (WINAPI *pPathYetAnotherMakeUniqueName)(PWSTR, PCWSTR, PCWSTR, PCWSTR);
 
 static DLLVERSIONINFO shellVersion = { 0 };
 static LPMALLOC pMalloc;
@@ -207,6 +208,7 @@ static void loadShell32(void)
         pILFindLastID = (void *)GetProcAddress(hShell32, (LPCSTR)16);
     GET_PROC(SHFileOperationA)
     GET_PROC(SHGetMalloc)
+    GET_PROC(PathYetAnotherMakeUniqueName)
 
     ok(pSHGetMalloc != NULL, "shell32 is missing SHGetMalloc\n");
     if (pSHGetMalloc)
@@ -2631,6 +2633,85 @@ static void test_DoEnvironmentSubst(void)
     }
 }
 
+static void test_PathYetAnotherMakeUniqueName(void)
+{
+    static const WCHAR shortW[] = {'f','i','l','e','.','t','s','t',0};
+    static const WCHAR short2W[] = {'f','i','l','e',' ','(','2',')','.','t','s','t',0};
+    static const WCHAR tmpW[] = {'t','m','p',0};
+    static const WCHAR longW[] = {'n','a','m','e',0};
+    static const WCHAR long2W[] = {'n','a','m','e',' ','(','2',')',0};
+    WCHAR nameW[MAX_PATH], buffW[MAX_PATH], pathW[MAX_PATH];
+    HANDLE file;
+    BOOL ret;
+
+    if (!pPathYetAnotherMakeUniqueName)
+    {
+        win_skip("PathYetAnotherMakeUniqueName() is not available.\n");
+        return;
+    }
+
+if (0)
+{
+    /* crashes on Windows */
+    ret = pPathYetAnotherMakeUniqueName(NULL, NULL, NULL, NULL);
+    ok(!ret, "got %d\n", ret);
+
+    ret = pPathYetAnotherMakeUniqueName(nameW, NULL, NULL, NULL);
+    ok(!ret, "got %d\n", ret);
+}
+
+    GetTempPathW(sizeof(pathW)/sizeof(WCHAR), pathW);
+
+    /* Using short name only first */
+    nameW[0] = 0;
+    ret = pPathYetAnotherMakeUniqueName(nameW, pathW, shortW, NULL);
+    ok(ret, "got %d\n", ret);
+    lstrcpyW(buffW, pathW);
+    lstrcatW(buffW, shortW);
+    ok(!lstrcmpW(nameW, buffW), "got %s, expected %s\n", wine_dbgstr_w(nameW), wine_dbgstr_w(buffW));
+
+    /* now create a file with this name and get next name */
+    file = CreateFileW(nameW, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_FLAG_DELETE_ON_CLOSE, NULL);
+    ok(file != NULL, "got %p\n", file);
+
+    nameW[0] = 0;
+    ret = pPathYetAnotherMakeUniqueName(nameW, pathW, shortW, NULL);
+    ok(ret, "got %d\n", ret);
+    lstrcpyW(buffW, pathW);
+    lstrcatW(buffW, short2W);
+    ok(!lstrcmpW(nameW, buffW), "got %s, expected %s\n", wine_dbgstr_w(nameW), wine_dbgstr_w(buffW));
+
+    CloseHandle(file);
+
+    /* Using short and long */
+    nameW[0] = 0;
+    ret = pPathYetAnotherMakeUniqueName(nameW, pathW, tmpW, longW);
+    ok(ret, "got %d\n", ret);
+    lstrcpyW(buffW, pathW);
+    lstrcatW(buffW, longW);
+    ok(!lstrcmpW(nameW, buffW), "got %s, expected %s\n", wine_dbgstr_w(nameW), wine_dbgstr_w(buffW));
+
+    file = CreateFileW(nameW, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_FLAG_DELETE_ON_CLOSE, NULL);
+    ok(file != NULL, "got %p\n", file);
+
+    nameW[0] = 0;
+    ret = pPathYetAnotherMakeUniqueName(nameW, pathW, tmpW, longW);
+    ok(ret, "got %d\n", ret);
+    lstrcpyW(buffW, pathW);
+    lstrcatW(buffW, long2W);
+    ok(!lstrcmpW(nameW, buffW), "got %s, expected %s\n", wine_dbgstr_w(nameW), wine_dbgstr_w(buffW));
+
+    CloseHandle(file);
+
+    /* Using long only */
+    nameW[0] = 0;
+    ret = pPathYetAnotherMakeUniqueName(nameW, pathW, NULL, longW);
+    ok(ret, "got %d\n", ret);
+    lstrcpyW(buffW, pathW);
+    lstrcatW(buffW, longW);
+    ok(!lstrcmpW(nameW, buffW), "got %s, expected %s\n", wine_dbgstr_w(nameW), wine_dbgstr_w(buffW));
+}
+
 START_TEST(shellpath)
 {
     if (!init()) return;
@@ -2659,5 +2740,6 @@ START_TEST(shellpath)
         test_SHGetFolderPathEx();
         test_knownFolders();
         test_DoEnvironmentSubst();
+        test_PathYetAnotherMakeUniqueName();
     }
 }




More information about the wine-cvs mailing list