From f9a19f57e1cc696e660ad4f847516aeb768a293b Mon Sep 17 00:00:00 2001 From: Nikolay Sivov Date: Sat, 28 Jun 2014 15:43:06 +0400 Subject: [PATCH] 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 2dfed750402..158b1d121fe 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 7486fac4df9..efdfbbd5893 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(); } } -- 2.11.4.GIT