From fcde02f9ffc166a0c39a5ff2ae65bdef813b331f Mon Sep 17 00:00:00 2001 From: Vincent Povirk Date: Thu, 16 Apr 2009 22:51:40 -0500 Subject: [PATCH] shell32: Implement SHGetNewLinkInfo[AW]. --- dlls/shell32/shellord.c | 61 ++++++++++++++++++++++++++++++++++++++---- dlls/shell32/tests/shlfileop.c | 52 +++++++++++++++++++++++++++++++++++ 2 files changed, 108 insertions(+), 5 deletions(-) diff --git a/dlls/shell32/shellord.c b/dlls/shell32/shellord.c index eaf285977ba..5eb45074019 100644 --- a/dlls/shell32/shellord.c +++ b/dlls/shell32/shellord.c @@ -1914,19 +1914,70 @@ BOOL WINAPI SHObjectProperties(HWND hwnd, DWORD dwType, LPCWSTR szObject, LPCWST BOOL WINAPI SHGetNewLinkInfoA(LPCSTR pszLinkTo, LPCSTR pszDir, LPSTR pszName, BOOL *pfMustCopy, UINT uFlags) { - FIXME("%s, %s, %p, %p, 0x%08x - stub\n", debugstr_a(pszLinkTo), debugstr_a(pszDir), - pszName, pfMustCopy, uFlags); + WCHAR wszLinkTo[MAX_PATH]; + WCHAR wszDir[MAX_PATH]; + WCHAR wszName[MAX_PATH]; + BOOL res; - return FALSE; + MultiByteToWideChar(CP_ACP, 0, pszLinkTo, -1, wszLinkTo, MAX_PATH); + MultiByteToWideChar(CP_ACP, 0, pszDir, -1, wszDir, MAX_PATH); + + res = SHGetNewLinkInfoW(wszLinkTo, wszDir, wszName, pfMustCopy, uFlags); + + if (res) + WideCharToMultiByte(CP_ACP, 0, wszName, -1, pszName, MAX_PATH, NULL, NULL); + + return res; } BOOL WINAPI SHGetNewLinkInfoW(LPCWSTR pszLinkTo, LPCWSTR pszDir, LPWSTR pszName, BOOL *pfMustCopy, UINT uFlags) { - FIXME("%s, %s, %p, %p, 0x%08x - stub\n", debugstr_w(pszLinkTo), debugstr_w(pszDir), + const WCHAR *basename; + WCHAR *dst_basename; + int i=2; + static const WCHAR lnkformat[] = {'%','s','.','l','n','k',0}; + static const WCHAR lnkformatnum[] = {'%','s',' ','(','%','d',')','.','l','n','k',0}; + + TRACE("(%s, %s, %p, %p, 0x%08x)\n", debugstr_w(pszLinkTo), debugstr_w(pszDir), pszName, pfMustCopy, uFlags); - return FALSE; + *pfMustCopy = FALSE; + + if (uFlags & SHGNLI_PIDL) + { + FIXME("SHGNLI_PIDL flag unsupported\n"); + return FALSE; + } + + if (uFlags) + FIXME("ignoring flags: 0x%08x\n", uFlags); + + /* FIXME: should test if the file is a shortcut or DOS program */ + if (GetFileAttributesW(pszLinkTo) == INVALID_FILE_ATTRIBUTES) + return FALSE; + + basename = strrchrW(pszLinkTo, '\\'); + if (basename) + basename = basename+1; + else + basename = pszLinkTo; + + lstrcpynW(pszName, pszDir, MAX_PATH); + if (!PathAddBackslashW(pszName)) + return FALSE; + + dst_basename = pszName + strlenW(pszName); + + snprintfW(dst_basename, pszName + MAX_PATH - dst_basename, lnkformat, basename); + + while (GetFileAttributesW(pszName) != INVALID_FILE_ATTRIBUTES) + { + snprintfW(dst_basename, pszName + MAX_PATH - dst_basename, lnkformatnum, basename, i); + i++; + } + + return TRUE; } HRESULT WINAPI SHStartNetConnectionDialog(HWND hwnd, LPCSTR pszRemoteName, DWORD dwType) diff --git a/dlls/shell32/tests/shlfileop.c b/dlls/shell32/tests/shlfileop.c index 433a1318888..ff060baec62 100644 --- a/dlls/shell32/tests/shlfileop.c +++ b/dlls/shell32/tests/shlfileop.c @@ -2051,6 +2051,54 @@ static void test_sh_path_prepare(void) RemoveDirectoryW(UNICODE_PATH); } +static void test_sh_new_link_info(void) +{ + BOOL ret, mustcopy=TRUE; + CHAR linkto[MAX_PATH]; + CHAR destdir[MAX_PATH]; + CHAR result[MAX_PATH]; + CHAR result2[MAX_PATH]; + + /* source file does not exist */ + set_curr_dir_path(linkto, "nosuchfile.txt\0"); + set_curr_dir_path(destdir, "testdir2\0"); + ret = SHGetNewLinkInfoA(linkto, destdir, result, &mustcopy, 0); + ok(ret == FALSE, "SHGetNewLinkInfoA succeeded\n"); + ok(mustcopy == FALSE, "mustcopy should be FALSE\n"); + + /* dest dir does not exist */ + set_curr_dir_path(linkto, "test1.txt\0"); + set_curr_dir_path(destdir, "nosuchdir\0"); + ret = SHGetNewLinkInfoA(linkto, destdir, result, &mustcopy, 0); + ok(ret == TRUE, "SHGetNewLinkInfoA failed, err=%i\n", GetLastError()); + ok(mustcopy == FALSE, "mustcopy should be FALSE\n"); + + /* source file exists */ + set_curr_dir_path(linkto, "test1.txt\0"); + set_curr_dir_path(destdir, "testdir2\0"); + ret = SHGetNewLinkInfoA(linkto, destdir, result, &mustcopy, 0); + ok(ret == TRUE, "SHGetNewLinkInfoA failed, err=%i\n", GetLastError()); + ok(mustcopy == FALSE, "mustcopy should be FALSE\n"); + ok(CompareStringA(LOCALE_SYSTEM_DEFAULT, NORM_IGNORECASE, destdir, + lstrlenA(destdir), result, lstrlenA(destdir)) == CSTR_EQUAL, + "%s does not start with %s\n", result, destdir); + ok(lstrlenA(result) > 4 && lstrcmpiA(result+lstrlenA(result)-4, ".lnk") == 0, + "%s does not end with .lnk\n", result); + + /* preferred target name already exists */ + createTestFile(result); + ret = SHGetNewLinkInfoA(linkto, destdir, result2, &mustcopy, 0); + ok(ret == TRUE, "SHGetNewLinkInfoA failed, err=%i\n", GetLastError()); + ok(mustcopy == FALSE, "mustcopy should be FALSE\n"); + ok(CompareStringA(LOCALE_SYSTEM_DEFAULT, NORM_IGNORECASE, destdir, + lstrlenA(destdir), result2, lstrlenA(destdir)) == CSTR_EQUAL, + "%s does not start with %s\n", result2, destdir); + ok(lstrlenA(result2) > 4 && lstrcmpiA(result2+lstrlenA(result2)-4, ".lnk") == 0, + "%s does not end with .lnk\n", result2); + ok(lstrcmpiA(result, result2) != 0, "%s and %s are the same\n", result, result2); + DeleteFileA(result); +} + static void test_unicode(void) { SHFILEOPSTRUCTW shfoW; @@ -2158,5 +2206,9 @@ START_TEST(shlfileop) test_sh_path_prepare(); clean_after_shfo_tests(); + init_shfo_tests(); + test_sh_new_link_info(); + clean_after_shfo_tests(); + test_unicode(); } -- 2.11.4.GIT