Presently the wine file explorer has a create shortcut entry that does nothing. This implements the FCIDM_SHVIEW_CREATELINK command.
This is a patch that was first submitted in 2017 and I unfortunately let the revision request fall unimplemented.
-- v7: shell32: Implement FCIDM_SHVIEW_CREATELINK
From: Aric Stewart aric@codeweavers.com
--- dlls/shell32/shlview_cmenu.c | 109 +++++++++++++++++++++++++++++++++++ 1 file changed, 109 insertions(+)
diff --git a/dlls/shell32/shlview_cmenu.c b/dlls/shell32/shlview_cmenu.c index cac33c39af7..ae3b5be3bdb 100644 --- a/dlls/shell32/shlview_cmenu.c +++ b/dlls/shell32/shlview_cmenu.c @@ -946,6 +946,111 @@ static void DoOpenProperties(ContextMenu *This, HWND hwnd) FIXME("No property pages found.\n"); }
+ +static void do_create_link(ContextMenu *This) +{ + IShellLinkW* shelllink; + IPersistFile* persistfile; + WCHAR filename[MAX_PATH]; + WCHAR root[MAX_PATH]; + WCHAR lnkfile[MAX_PATH]; + ITEMIDLIST *full_pidl; + HRESULT hr; + int length; + int counter = 1; + + static const WCHAR *shortcutW = L"Shortcut"; + + if (FAILED(IShellLink_Constructor(NULL, &IID_IShellLinkW, (LPVOID*)&shelllink))) + { + ERR("couldn't create ShellLink object\n"); + return; + } + full_pidl = ILCombine(This->pidl, This->apidl[0]); + if (!full_pidl) + { + ERR("Out of Memory\n"); + return; + } + + hr = IShellLinkW_SetIDList(shelllink, full_pidl); + ILFree(full_pidl); + if (FAILED(hr)) + { + ERR("SetIDList failed\n"); + return; + } + _ILSimpleGetTextW(This->apidl[0], (LPVOID)filename, MAX_PATH); + length = wcslen(filename) + wcslen(shortcutW); + if (length > MAX_PATH) + { + ERR("Path maximum length exceeded (%i>%i)\n", length, MAX_PATH); + IShellLinkW_Release(shelllink); + return; + } + + SHGetPathFromIDListW(This->pidl, root); + + if (!SUCCEEDED(IShellLinkW_QueryInterface(shelllink, &IID_IPersistFile, (LPVOID*)&persistfile))) + { + ERR("couldn't get IPersistFile interface\n"); + IShellLinkW_Release(shelllink); + return; + } + + do { + WCHAR *link_filename; + + if (counter == 1) + { + static const WCHAR *fmt = L"%s - %s.lnk"; + int length = wcslen(filename) + wcslen(shortcutW) + 7; /* length of the format*/ + link_filename = malloc((length + 1) * sizeof(WCHAR)); + wsprintfW(link_filename, fmt, filename, shortcutW); + } + else + { + static const WCHAR *fmt = L"%s - %s (%s).lnk"; + int length = wcslen(filename) + wcslen(shortcutW) + 10; /* length of the format*/ + WCHAR counter_string[34]; + wsprintfW(counter_string, L"%i", counter); + length += wcslen(counter_string); + link_filename = malloc((length + 1) * sizeof(WCHAR)); + wsprintfW(link_filename, fmt, filename, shortcutW, counter_string); + } + + length = wcslen(root) + wcslen(link_filename) + 2; /* the path seperator and NULL */ + if (length > MAX_PATH) + { + ERR("Path maximum length exceeded (%i>%i)\n", length, MAX_PATH); + IShellLinkW_Release(shelllink); + free(link_filename); + return; + } + + PathCombineW(lnkfile, root, link_filename); + free(link_filename); + counter++; + + if (PathFileExistsW(lnkfile)) + { + hr = HRESULT_FROM_WIN32(ERROR_FILE_EXISTS); + } + else + { + ERR("attempting to write link to %s\n", wine_dbgstr_w(lnkfile)); + hr = IPersistFile_Save(persistfile, lnkfile, FALSE); + ERR("ARIC %#lx\n",hr); + } + } while (hr == HRESULT_FROM_WIN32(ERROR_FILE_EXISTS)); + + if (!SUCCEEDED(hr)) + ERR("couldn't write link to %s : %#lx\n", wine_dbgstr_w(lnkfile), hr); + + IPersistFile_Release(persistfile); + IShellLinkW_Release(shelllink); +} + static HRESULT WINAPI ItemMenu_InvokeCommand( IContextMenu3 *iface, LPCMINVOKECOMMANDINFO lpcmi) @@ -1014,6 +1119,10 @@ static HRESULT WINAPI ItemMenu_InvokeCommand( TRACE("Verb FCIDM_SHVIEW_PROPERTIES\n"); DoOpenProperties(This, lpcmi->hwnd); break; + case FCIDM_SHVIEW_CREATELINK: + TRACE("Verb FCIDM_SHVIEW_CREATELINK\n"); + do_create_link(This); + break; default: FIXME("Unhandled verb %#x.\n", id); return E_INVALIDARG;
Hi,
It looks like your patch introduced the new failures shown below. Please investigate and fix them before resubmitting your patch. If they are not new, fixing them anyway would help a lot. Otherwise please ask for the known failures list to be updated.
The tests also ran into some preexisting test failures. If you know how to fix them that would be helpful. See the TestBot job for the details:
The full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=145947
Your paranoid android.
=== debian11 (32 bit report) ===
Report validation errors: shell32:shelllink crashed (c0000005)
Ok I believe I have addressed these.