mirror of
https://github.com/reactos/reactos.git
synced 2025-02-22 16:36:33 +00:00
[SHELL32] Improve and fix SendTo (#2122)
Because of timing of SendTo folder initialization, SendTo My Documents didn't work well. Now My Documents item is working well. CORE-12562
This commit is contained in:
parent
92c3c814bb
commit
b582d6ff45
3 changed files with 162 additions and 128 deletions
|
@ -156,10 +156,169 @@ void CSendToMenu::UnloadAllItems()
|
|||
}
|
||||
}
|
||||
|
||||
BOOL CSendToMenu::FolderHasAnyItems() const
|
||||
{
|
||||
WCHAR szPath[MAX_PATH];
|
||||
SHGetSpecialFolderPathW(NULL, szPath, CSIDL_SENDTO, FALSE);
|
||||
|
||||
PathAppendW(szPath, L"*");
|
||||
|
||||
WIN32_FIND_DATAW find;
|
||||
HANDLE hFind = FindFirstFileW(szPath, &find);
|
||||
if (hFind == INVALID_HANDLE_VALUE)
|
||||
return FALSE;
|
||||
|
||||
BOOL bFound = FALSE;
|
||||
do
|
||||
{
|
||||
if (wcscmp(find.cFileName, L".") == 0 ||
|
||||
wcscmp(find.cFileName, L"..") == 0 ||
|
||||
_wcsicmp(find.cFileName, L"desktop.ini") == 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
bFound = TRUE;
|
||||
break;
|
||||
} while (FindNextFileW(hFind, &find));
|
||||
|
||||
FindClose(hFind);
|
||||
return bFound;
|
||||
}
|
||||
|
||||
static BOOL CreateEmptyFile(LPCWSTR pszFile)
|
||||
{
|
||||
HANDLE hFile;
|
||||
hFile = CreateFileW(pszFile, GENERIC_WRITE, FILE_SHARE_READ, NULL,
|
||||
CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
CloseHandle(hFile);
|
||||
return hFile != INVALID_HANDLE_VALUE;
|
||||
}
|
||||
|
||||
static HRESULT
|
||||
CreateShellLink(
|
||||
LPCWSTR pszLinkPath,
|
||||
LPCWSTR pszTargetPath OPTIONAL,
|
||||
LPCITEMIDLIST pidlTarget OPTIONAL,
|
||||
LPCWSTR pszArg OPTIONAL,
|
||||
LPCWSTR pszDir OPTIONAL,
|
||||
LPCWSTR pszIconPath OPTIONAL,
|
||||
INT iIconNr OPTIONAL,
|
||||
LPCWSTR pszComment OPTIONAL)
|
||||
{
|
||||
CComPtr<IShellLinkW> psl;
|
||||
HRESULT hr = CoCreateInstance(CLSID_ShellLink, NULL,
|
||||
CLSCTX_INPROC_SERVER,
|
||||
IID_PPV_ARG(IShellLinkW, &psl));
|
||||
if (FAILED_UNEXPECTEDLY(hr))
|
||||
return hr;
|
||||
|
||||
if (pszTargetPath)
|
||||
{
|
||||
hr = psl->SetPath(pszTargetPath);
|
||||
if (FAILED_UNEXPECTEDLY(hr))
|
||||
return hr;
|
||||
}
|
||||
else if (pidlTarget)
|
||||
{
|
||||
hr = psl->SetIDList(pidlTarget);
|
||||
if (FAILED_UNEXPECTEDLY(hr))
|
||||
return hr;
|
||||
}
|
||||
else
|
||||
{
|
||||
ERR("invalid argument\n");
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
|
||||
if (pszArg)
|
||||
hr = psl->SetArguments(pszArg);
|
||||
|
||||
if (pszDir)
|
||||
hr = psl->SetWorkingDirectory(pszDir);
|
||||
|
||||
if (pszIconPath)
|
||||
hr = psl->SetIconLocation(pszIconPath, iIconNr);
|
||||
|
||||
if (pszComment)
|
||||
hr = psl->SetDescription(pszComment);
|
||||
|
||||
CComPtr<IPersistFile> ppf;
|
||||
hr = psl->QueryInterface(IID_PPV_ARG(IPersistFile, &ppf));
|
||||
if (FAILED_UNEXPECTEDLY(hr))
|
||||
return hr;
|
||||
|
||||
hr = ppf->Save(pszLinkPath, TRUE);
|
||||
if (FAILED_UNEXPECTEDLY(hr))
|
||||
return hr;
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
HRESULT CSendToMenu::CreateSendToFiles(LPCWSTR pszSendTo)
|
||||
{
|
||||
WCHAR szTarget[MAX_PATH];
|
||||
WCHAR szSendToFile[MAX_PATH];
|
||||
WCHAR szShell32[MAX_PATH];
|
||||
HRESULT hr;
|
||||
|
||||
/* create my documents */
|
||||
SHGetSpecialFolderPathW(NULL, szTarget, CSIDL_MYDOCUMENTS, FALSE);
|
||||
|
||||
StringCbCopyW(szSendToFile, sizeof(szSendToFile), pszSendTo);
|
||||
PathAppendW(szSendToFile, PathFindFileNameW(szTarget));
|
||||
StringCbCatW(szSendToFile, sizeof(szSendToFile), L".lnk");
|
||||
|
||||
GetSystemDirectoryW(szShell32, ARRAY_SIZE(szShell32));
|
||||
PathAppendW(szShell32, L"shell32.dll");
|
||||
hr = CreateShellLink(szSendToFile, szTarget, NULL, NULL, NULL,
|
||||
szShell32, -IDI_SHELL_MY_DOCUMENTS, NULL);
|
||||
if (FAILED_UNEXPECTEDLY(hr))
|
||||
;
|
||||
|
||||
/* create desklink */
|
||||
StringCbCopyW(szSendToFile, sizeof(szSendToFile), pszSendTo);
|
||||
LoadStringW(shell32_hInstance, IDS_DESKLINK, szTarget, _countof(szTarget));
|
||||
StringCbCatW(szTarget, sizeof(szTarget), L".DeskLink");
|
||||
PathAppendW(szSendToFile, szTarget);
|
||||
if (!CreateEmptyFile(szSendToFile))
|
||||
{
|
||||
ERR("CreateEmptyFile\n");
|
||||
}
|
||||
|
||||
/* create zipped compressed folder */
|
||||
HINSTANCE hZipFldr =
|
||||
LoadLibraryExW(L"zipfldr.dll", NULL, LOAD_LIBRARY_AS_DATAFILE);
|
||||
if (hZipFldr)
|
||||
{
|
||||
#define IDS_FRIENDLYNAME 10195
|
||||
LoadStringW(hZipFldr, IDS_FRIENDLYNAME, szTarget, _countof(szTarget));
|
||||
#undef IDS_FRIENDLYNAME
|
||||
FreeLibrary(hZipFldr);
|
||||
|
||||
StringCbCopyW(szSendToFile, sizeof(szSendToFile), pszSendTo);
|
||||
PathAppendW(szSendToFile, szTarget);
|
||||
StringCbCatW(szSendToFile, sizeof(szSendToFile), L".ZFSendToTarget");
|
||||
if (!CreateEmptyFile(szSendToFile))
|
||||
{
|
||||
ERR("CreateEmptyFile\n");
|
||||
}
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT CSendToMenu::LoadAllItems(HWND hwnd)
|
||||
{
|
||||
UnloadAllItems();
|
||||
|
||||
if (!FolderHasAnyItems())
|
||||
{
|
||||
WCHAR szPath[MAX_PATH];
|
||||
SHGetSpecialFolderPathW(NULL, szPath, CSIDL_SENDTO, FALSE);
|
||||
CreateSendToFiles(szPath);
|
||||
}
|
||||
|
||||
CComHeapPtr<ITEMIDLIST_ABSOLUTE> pidlSendTo;
|
||||
|
||||
m_pSendTo.Release();
|
||||
|
|
|
@ -69,6 +69,9 @@ private:
|
|||
HRESULT LoadAllItems(HWND hwnd);
|
||||
void UnloadAllItems();
|
||||
|
||||
BOOL FolderHasAnyItems() const;
|
||||
HRESULT CreateSendToFiles(LPCWSTR pszSendTo);
|
||||
|
||||
UINT InsertSendToItems(HMENU hMenu, UINT idFirst, UINT idMenu);
|
||||
|
||||
SENDTO_ITEM *FindItemFromIdOffset(UINT IdOffset);
|
||||
|
|
|
@ -2146,129 +2146,6 @@ cleanup:
|
|||
return hr;
|
||||
}
|
||||
|
||||
static HRESULT
|
||||
CreateShellLink(
|
||||
LPCWSTR pszLinkPath,
|
||||
LPCWSTR pszCmd,
|
||||
LPCWSTR pszArg OPTIONAL,
|
||||
LPCWSTR pszDir OPTIONAL,
|
||||
LPCWSTR pszIconPath OPTIONAL,
|
||||
INT iIconNr OPTIONAL,
|
||||
LPCWSTR pszComment OPTIONAL)
|
||||
{
|
||||
IShellLinkW *psl;
|
||||
IPersistFile *ppf;
|
||||
|
||||
HRESULT hr = CoCreateInstance(&CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, &IID_IShellLink, (LPVOID*)&psl);
|
||||
if (FAILED_UNEXPECTEDLY(hr))
|
||||
return hr;
|
||||
|
||||
hr = IShellLinkW_SetPath(psl, pszCmd);
|
||||
if (FAILED_UNEXPECTEDLY(hr))
|
||||
{
|
||||
IShellLinkW_Release(psl);
|
||||
return hr;
|
||||
}
|
||||
|
||||
if (pszArg)
|
||||
hr = IShellLinkW_SetArguments(psl, pszArg);
|
||||
|
||||
if (pszDir)
|
||||
hr = IShellLinkW_SetWorkingDirectory(psl, pszDir);
|
||||
|
||||
if (pszIconPath)
|
||||
hr = IShellLinkW_SetIconLocation(psl, pszIconPath, iIconNr);
|
||||
|
||||
if (pszComment)
|
||||
hr = IShellLinkW_SetDescription(psl, pszComment);
|
||||
|
||||
hr = IShellLinkW_QueryInterface(psl, &IID_IPersistFile, (LPVOID*)&ppf);
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
hr = IPersistFile_Save(ppf, pszLinkPath, TRUE);
|
||||
IPersistFile_Release(ppf);
|
||||
}
|
||||
|
||||
IShellLinkW_Release(psl);
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
static HRESULT
|
||||
CreateShellLinkCoInit(
|
||||
LPCWSTR pszLinkPath,
|
||||
LPCWSTR pszCmd,
|
||||
LPCWSTR pszArg OPTIONAL,
|
||||
LPCWSTR pszDir OPTIONAL,
|
||||
LPCWSTR pszIconPath OPTIONAL,
|
||||
INT iIconNr OPTIONAL,
|
||||
LPCWSTR pszComment OPTIONAL)
|
||||
{
|
||||
HRESULT hr = CoInitializeEx(NULL, COINIT_MULTITHREADED);
|
||||
BOOL bCoInit = (hr == S_OK);
|
||||
|
||||
hr = CreateShellLink(pszLinkPath, pszCmd, pszArg, pszDir,
|
||||
pszIconPath, iIconNr, pszComment);
|
||||
|
||||
if (bCoInit)
|
||||
CoUninitialize();
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
HRESULT DoCreateSendToFiles(LPCWSTR pszSendTo)
|
||||
{
|
||||
WCHAR szTarget[MAX_PATH];
|
||||
WCHAR szSendToFile[MAX_PATH];
|
||||
WCHAR szShell32[MAX_PATH];
|
||||
HRESULT hr;
|
||||
HANDLE hFile;
|
||||
HINSTANCE hZipFldr;
|
||||
|
||||
/* create my documents */
|
||||
SHGetSpecialFolderPathW(NULL, szTarget, CSIDL_MYDOCUMENTS, TRUE);
|
||||
|
||||
StringCbCopyW(szSendToFile, sizeof(szSendToFile), pszSendTo);
|
||||
PathAppendW(szSendToFile, PathFindFileNameW(szTarget));
|
||||
StringCbCatW(szSendToFile, sizeof(szSendToFile), L".lnk");
|
||||
|
||||
GetSystemDirectoryW(szShell32, ARRAY_SIZE(szShell32));
|
||||
PathAppendW(szShell32, L"shell32.dll");
|
||||
hr = CreateShellLinkCoInit(szSendToFile, szTarget, NULL, NULL,
|
||||
szShell32, -IDI_SHELL_MY_DOCUMENTS, NULL);
|
||||
if (FAILED_UNEXPECTEDLY(hr))
|
||||
return hr;
|
||||
|
||||
/* create desklink */
|
||||
StringCbCopyW(szSendToFile, sizeof(szSendToFile), pszSendTo);
|
||||
LoadStringW(shell32_hInstance, IDS_DESKLINK, szTarget, _countof(szTarget));
|
||||
StringCbCatW(szTarget, sizeof(szTarget), L".DeskLink");
|
||||
PathAppendW(szSendToFile, szTarget);
|
||||
hFile = CreateFileW(szSendToFile, GENERIC_WRITE, FILE_SHARE_READ, NULL,
|
||||
CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
CloseHandle(hFile);
|
||||
|
||||
/* create zipped compressed folder */
|
||||
hZipFldr = LoadLibraryW(L"zipfldr.dll");
|
||||
if (hZipFldr)
|
||||
{
|
||||
#define IDS_FRIENDLYNAME 10195
|
||||
LoadStringW(hZipFldr, IDS_FRIENDLYNAME, szTarget, _countof(szTarget));
|
||||
#undef IDS_FRIENDLYNAME
|
||||
FreeLibrary(hZipFldr);
|
||||
|
||||
StringCbCopyW(szSendToFile, sizeof(szSendToFile), pszSendTo);
|
||||
PathAppendW(szSendToFile, szTarget);
|
||||
StringCbCatW(szSendToFile, sizeof(szSendToFile), L".ZFSendToTarget");
|
||||
hFile = CreateFileW(szSendToFile, GENERIC_WRITE, FILE_SHARE_READ, NULL,
|
||||
CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
CloseHandle(hFile);
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
/*************************************************************************
|
||||
* SHGetFolderPathAndSubDirW [SHELL32.@]
|
||||
*/
|
||||
|
@ -2408,11 +2285,6 @@ HRESULT WINAPI SHGetFolderPathAndSubDirW(
|
|||
TRACE("Created missing system directory %s\n", debugstr_w(szBuildPath));
|
||||
|
||||
end:
|
||||
if ((nFolder & CSIDL_FLAG_CREATE) && folder == CSIDL_SENDTO)
|
||||
{
|
||||
DoCreateSendToFiles(szBuildPath);
|
||||
}
|
||||
|
||||
/* create desktop.ini for custom icon */
|
||||
if ((nFolder & CSIDL_FLAG_CREATE) &&
|
||||
CSIDL_Data[folder].nShell32IconIndex)
|
||||
|
|
Loading…
Reference in a new issue