From 7c2b22c4de31933a30d411bbbc25e7f29fb77e5d Mon Sep 17 00:00:00 2001 From: Thamatip Chitpong Date: Sun, 4 Dec 2022 00:06:45 +0700 Subject: [PATCH] [SENDMAIL] Fix Send To -> Desktop (create shortcut) behavior (#4913) Several fixes and improvements to the CDeskLinkDropHandler: - Set default working directory for shortcuts (except folders and zip files) - Copy existing shortcut to the desktop if the source file is a shortcut - Prevent destination file name collision Verified on Windows XP SP3 and Windows 7 SP1. --- .../sendmail/CDeskLinkDropHandler.cpp | 47 ++++++++++++++++--- 1 file changed, 41 insertions(+), 6 deletions(-) diff --git a/dll/shellext/sendmail/CDeskLinkDropHandler.cpp b/dll/shellext/sendmail/CDeskLinkDropHandler.cpp index 8edc76dda2b..cf35e55d151 100644 --- a/dll/shellext/sendmail/CDeskLinkDropHandler.cpp +++ b/dll/shellext/sendmail/CDeskLinkDropHandler.cpp @@ -86,14 +86,49 @@ CDeskLinkDropHandler::Drop(IDataObject *pDataObject, DWORD dwKeyState, StringCbCopyW(szDest, sizeof(szDest), szDir); if (SHGetPathFromIDListW(pidl, szSrc)) { - CStringW strTitle; - strTitle.Format(IDS_SHORTCUT, PathFindFileNameW(szSrc)); + LPCWSTR pszSourceExt; + BOOL bIsLink; - PathAppendW(szDest, strTitle); - PathRemoveExtensionW(szDest); - StringCbCatW(szDest, sizeof(szDest), L".lnk"); + pszSourceExt = PathFindExtensionW(szSrc); + bIsLink = ((_wcsicmp(pszSourceExt, L".lnk") == 0) || + (_wcsicmp(pszSourceExt, L".url") == 0)); - hr = CreateShellLink(szDest, szSrc, NULL, NULL, NULL, NULL, -1, NULL); + if (bIsLink) + { + PathAppendW(szDest, PathFindFileNameW(szSrc)); + } + else + { + CStringW strTitle; + strTitle.Format(IDS_SHORTCUT, PathFindFileNameW(szSrc)); + + PathAppendW(szDest, strTitle); + PathRemoveExtensionW(szDest); + StringCbCatW(szDest, sizeof(szDest), L".lnk"); + } + + if (PathFileExistsW(szDest)) + { + CStringW strName(PathFindFileNameW(szDest)); + PathYetAnotherMakeUniqueName(szDest, szDir, NULL, strName); + } + + if (bIsLink) + { + hr = (CopyFileW(szSrc, szDest, TRUE) ? S_OK : E_FAIL); + } + else if (PathIsDirectoryW(szSrc) || (_wcsicmp(pszSourceExt, L".zip") == 0)) + { + hr = CreateShellLink(szDest, szSrc, NULL, NULL, NULL, NULL, -1, NULL); + } + else + { + /* Set default working directory for the shortcut */ + CStringW strWorkingDir(szSrc); + PathRemoveFileSpecW(strWorkingDir.GetBuffer()); + + hr = CreateShellLink(szDest, szSrc, NULL, NULL, strWorkingDir, NULL, -1, NULL); + } } else {