Added patches to fix multiple issues in shell32 context menu handling.

This commit is contained in:
Sebastian Lackner 2016-04-02 05:58:59 +02:00
parent bd61bfe45f
commit 1f27eee3ed
10 changed files with 750 additions and 0 deletions

View File

@ -294,6 +294,7 @@ patch_enable_all ()
enable_setupapi_SetupPromptForDisk="$1"
enable_sfc_SfcGetNextProtectedFile="$1"
enable_shdocvw_ParseURLFromOutsideSource_Tests="$1"
enable_shell32_Context_Menu="$1"
enable_shell32_Default_Path="$1"
enable_shell32_File_Property_Dialog="$1"
enable_shell32_FolderItems_Stub_Iface="$1"
@ -1059,6 +1060,9 @@ patch_enable ()
shdocvw-ParseURLFromOutsideSource_Tests)
enable_shdocvw_ParseURLFromOutsideSource_Tests="$2"
;;
shell32-Context_Menu)
enable_shell32_Context_Menu="$2"
;;
shell32-Default_Path)
enable_shell32_Default_Path="$2"
;;
@ -6181,6 +6185,39 @@ if test "$enable_shdocvw_ParseURLFromOutsideSource_Tests" -eq 1; then
) >> "$patchlist"
fi
# Patchset shell32-Context_Menu
# |
# | This patchset fixes the following Wine bugs:
# | * [#34319] Add support for Paste in context menu
# | * [#34322] Fix implementation of Cut file operation
# | * [#34321] Fix Cut/Copy/Paste keyboard shortcuts in Total Commander
# |
# | Modified files:
# | * dlls/shell32/clipboard.c, dlls/shell32/dataobject.c, dlls/shell32/recyclebin.c, dlls/shell32/shell32.rc,
# | dlls/shell32/shell32_main.h, dlls/shell32/shellfolder.h, dlls/shell32/shfldr_fs.c, dlls/shell32/shfldr_unixfs.c,
# | dlls/shell32/shlview.c, dlls/shell32/shlview_cmenu.c
# |
if test "$enable_shell32_Context_Menu" -eq 1; then
patch_apply shell32-Context_Menu/0001-shell32-Fix-copying-of-files-when-using-a-context-me.patch
patch_apply shell32-Context_Menu/0002-shell32-Set-return-value-correctly-in-DoPaste.patch
patch_apply shell32-Context_Menu/0003-shell32-Implement-insert-paste-for-item-context-menu.patch
patch_apply shell32-Context_Menu/0004-shell32-Correctly-interpret-result-of-SHFileOperatio.patch
patch_apply shell32-Context_Menu/0005-shell32-Add-support-for-setting-getting-PREFERREDDRO.patch
patch_apply shell32-Context_Menu/0006-shell32-Add-parameter-to-ISFHelper-DeleteItems-to-al.patch
patch_apply shell32-Context_Menu/0007-shell32-Remove-source-files-when-using-cut-in-the-co.patch
patch_apply shell32-Context_Menu/0008-shell32-Recognize-cut-copy-paste-string-verbs-in-ite.patch
(
echo '+ { "Michael Müller", "shell32: Fix copying of files when using a context menu.", 1 },';
echo '+ { "Michael Müller", "shell32: Set return value correctly in DoPaste.", 1 },';
echo '+ { "Michael Müller", "shell32: Implement insert/paste for item context menus.", 1 },';
echo '+ { "Michael Müller", "shell32: Correctly interpret result of SHFileOperation in UNIXFS copy and delete.", 1 },';
echo '+ { "Michael Müller", "shell32: Add support for setting/getting PREFERREDDROPEFFECT in IDataObject.", 1 },';
echo '+ { "Michael Müller", "shell32: Add parameter to ISFHelper::DeleteItems to allow deleting files without confirmation.", 1 },';
echo '+ { "Michael Müller", "shell32: Remove source files when using cut in the context menu.", 1 },';
echo '+ { "Michael Müller", "shell32: Recognize cut/copy/paste string verbs in item menu context menu.", 1 },';
) >> "$patchlist"
fi
# Patchset shell32-Default_Path
# |
# | This patchset fixes the following Wine bugs:

View File

@ -0,0 +1,30 @@
From 9175a389d86cc231e7e8158360402feb7c5b269e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Michael=20M=C3=BCller?= <michael@fds-team.de>
Date: Sat, 2 Apr 2016 00:22:30 +0200
Subject: shell32: Fix copying of files when using a context menu.
---
dlls/shell32/shlview_cmenu.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/dlls/shell32/shlview_cmenu.c b/dlls/shell32/shlview_cmenu.c
index 099f5bc..552b809 100644
--- a/dlls/shell32/shlview_cmenu.c
+++ b/dlls/shell32/shlview_cmenu.c
@@ -739,6 +739,13 @@ static BOOL DoPaste(ContextMenu *This)
apidl = _ILCopyCidaToaPidl(&pidl, lpcida);
+ /*
+ * In case source is a file we need to remove the last component
+ * to obtain a IShellFolder of the parent.
+ */
+ if (_ILIsValue(pidl))
+ ILRemoveLastID(pidl);
+
/* bind to the source shellfolder */
SHGetDesktopFolder(&psfDesktop);
if(psfDesktop)
--
2.7.1

View File

@ -0,0 +1,26 @@
From 7f13fd37d55efe4cc20c4c3eb1c79d3c8ef0040d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Michael=20M=C3=BCller?= <michael@fds-team.de>
Date: Sat, 2 Apr 2016 01:21:34 +0200
Subject: shell32: Set return value correctly in DoPaste.
---
dlls/shell32/shlview_cmenu.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/dlls/shell32/shlview_cmenu.c b/dlls/shell32/shlview_cmenu.c
index 552b809..7ce6cd9 100644
--- a/dlls/shell32/shlview_cmenu.c
+++ b/dlls/shell32/shlview_cmenu.c
@@ -764,7 +764,8 @@ static BOOL DoPaste(ContextMenu *This)
/* do the copy/move */
if (psfhlpdst && psfhlpsrc)
{
- ISFHelper_CopyItems(psfhlpdst, psfFrom, lpcida->cidl, (LPCITEMIDLIST*)apidl);
+ if (SUCCEEDED(ISFHelper_CopyItems(psfhlpdst, psfFrom, lpcida->cidl, (LPCITEMIDLIST*)apidl)))
+ bSuccess = TRUE;
/* FIXME handle move
ISFHelper_DeleteItems(psfhlpsrc, lpcida->cidl, apidl);
*/
--
2.7.1

View File

@ -0,0 +1,165 @@
From f378913d8cb2e40abb4e24d4bfaf0cbe7ea8134a Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Michael=20M=C3=BCller?= <michael@fds-team.de>
Date: Sat, 2 Apr 2016 01:39:40 +0200
Subject: shell32: Implement insert/paste for item context menus.
---
dlls/shell32/shell32.rc | 1 +
dlls/shell32/shlview_cmenu.c | 68 +++++++++++++++++++++++++++++++++++++++-----
2 files changed, 62 insertions(+), 7 deletions(-)
diff --git a/dlls/shell32/shell32.rc b/dlls/shell32/shell32.rc
index bfba962..4f2015b 100644
--- a/dlls/shell32/shell32.rc
+++ b/dlls/shell32/shell32.rc
@@ -99,6 +99,7 @@ BEGIN
MENUITEM SEPARATOR
MENUITEM "C&ut", FCIDM_SHVIEW_CUT
MENUITEM "&Copy", FCIDM_SHVIEW_COPY
+ MENUITEM "&Paste", FCIDM_SHVIEW_INSERT
MENUITEM SEPARATOR
MENUITEM "Create &Link", FCIDM_SHVIEW_CREATELINK
MENUITEM "&Delete", FCIDM_SHVIEW_DELETE
diff --git a/dlls/shell32/shlview_cmenu.c b/dlls/shell32/shlview_cmenu.c
index 7ce6cd9..d972922 100644
--- a/dlls/shell32/shlview_cmenu.c
+++ b/dlls/shell32/shlview_cmenu.c
@@ -59,6 +59,8 @@ typedef struct
BOOL desktop;
} ContextMenu;
+static BOOL DoPaste(ContextMenu *This);
+
static inline ContextMenu *impl_from_IContextMenu3(IContextMenu3 *iface)
{
return CONTAINING_RECORD(iface, ContextMenu, IContextMenu3_iface);
@@ -123,6 +125,30 @@ static ULONG WINAPI ContextMenu_Release(IContextMenu3 *iface)
return ref;
}
+static BOOL CheckClipboard(void)
+{
+ IDataObject *pda;
+ BOOL ret = FALSE;
+
+ if (SUCCEEDED(OleGetClipboard(&pda)))
+ {
+ STGMEDIUM medium;
+ FORMATETC formatetc;
+
+ /* Set the FORMATETC structure*/
+ InitFormatEtc(formatetc, RegisterClipboardFormatW(CFSTR_SHELLIDLISTW), TYMED_HGLOBAL);
+
+ /* Get the pidls from IDataObject */
+ if (SUCCEEDED(IDataObject_GetData(pda, &formatetc, &medium)))
+ {
+ ReleaseStgMedium(&medium);
+ ret = TRUE;
+ }
+ IDataObject_Release(pda);
+ }
+ return ret;
+}
+
static HRESULT WINAPI ItemMenu_QueryContextMenu(
IContextMenu3 *iface,
HMENU hmenu,
@@ -133,6 +159,7 @@ static HRESULT WINAPI ItemMenu_QueryContextMenu(
{
ContextMenu *This = impl_from_IContextMenu3(iface);
INT uIDMax;
+ DWORD attr = SFGAO_CANRENAME;
TRACE("(%p)->(%p %d 0x%x 0x%x 0x%x )\n", This, hmenu, indexMenu, idCmdFirst, idCmdLast, uFlags);
@@ -169,6 +196,9 @@ static HRESULT WINAPI ItemMenu_QueryContextMenu(
SetMenuDefaultItem(hmenu, 0, MF_BYPOSITION);
+ if (This->apidl && This->cidl == 1)
+ IShellFolder_GetAttributesOf(This->parent, 1, (LPCITEMIDLIST*)This->apidl, &attr);
+
if(uFlags & ~CMF_CANRENAME)
RemoveMenu(hmenu, FCIDM_SHVIEW_RENAME, MF_BYCOMMAND);
else
@@ -179,16 +209,14 @@ static HRESULT WINAPI ItemMenu_QueryContextMenu(
if (!This->apidl || This->cidl > 1)
enable |= MFS_DISABLED;
else
- {
- DWORD attr = SFGAO_CANRENAME;
-
- IShellFolder_GetAttributesOf(This->parent, 1, (LPCITEMIDLIST*)This->apidl, &attr);
enable |= (attr & SFGAO_CANRENAME) ? MFS_ENABLED : MFS_DISABLED;
- }
EnableMenuItem(hmenu, FCIDM_SHVIEW_RENAME, enable);
}
+ if ((attr & (SFGAO_FILESYSTEM|SFGAO_FOLDER)) != (SFGAO_FILESYSTEM|SFGAO_FOLDER) || !CheckClipboard())
+ RemoveMenu(hmenu, FCIDM_SHVIEW_INSERT + idCmdFirst, MF_BYCOMMAND);
+
return MAKE_HRESULT(SEVERITY_SUCCESS, 0, uIDMax-idCmdFirst);
}
return MAKE_HRESULT(SEVERITY_SUCCESS, 0, 0);
@@ -447,6 +475,10 @@ static HRESULT WINAPI ItemMenu_InvokeCommand(
TRACE("Verb FCIDM_SHVIEW_CUT\n");
DoCopyOrCut(This, lpcmi->hwnd, TRUE);
break;
+ case FCIDM_SHVIEW_INSERT:
+ TRACE("Verb FCIDM_SHVIEW_INSERT\n");
+ DoPaste(This);
+ break;
case FCIDM_SHVIEW_PROPERTIES:
TRACE("Verb FCIDM_SHVIEW_PROPERTIES\n");
DoOpenProperties(This, lpcmi->hwnd);
@@ -510,6 +542,10 @@ static HRESULT WINAPI ItemMenu_GetCommandString(
strcpy(lpszName, "copy");
hr = S_OK;
break;
+ case FCIDM_SHVIEW_INSERT:
+ strcpy(lpszName, "paste");
+ hr = S_OK;
+ break;
case FCIDM_SHVIEW_CREATELINK:
strcpy(lpszName, "link");
hr = S_OK;
@@ -550,6 +586,10 @@ static HRESULT WINAPI ItemMenu_GetCommandString(
MultiByteToWideChar(CP_ACP, 0, "copy", -1, (LPWSTR)lpszName, uMaxNameLen);
hr = S_OK;
break;
+ case FCIDM_SHVIEW_INSERT:
+ MultiByteToWideChar(CP_ACP, 0, "paste", -1, (LPWSTR)lpszName, uMaxNameLen);
+ hr = S_OK;
+ break;
case FCIDM_SHVIEW_CREATELINK:
MultiByteToWideChar(CP_ACP, 0, "link", -1, (LPWSTR)lpszName, uMaxNameLen);
hr = S_OK;
@@ -757,8 +797,22 @@ static BOOL DoPaste(ContextMenu *This)
if (psfFrom)
{
/* get source and destination shellfolder */
- ISFHelper *psfhlpdst, *psfhlpsrc;
- IShellFolder_QueryInterface(This->parent, &IID_ISFHelper, (void**)&psfhlpdst);
+ ISFHelper *psfhlpdst = NULL, *psfhlpsrc = NULL;
+
+ /* when using an item context menu we first need to bind to the selected folder */
+ if (This->apidl)
+ {
+ IShellFolder *folder;
+
+ if (SUCCEEDED(IShellFolder_BindToObject(This->parent, This->apidl[0], NULL, &IID_IShellFolder, (LPVOID*)&folder)))
+ {
+ IShellFolder_QueryInterface(folder, &IID_ISFHelper, (void**)&psfhlpdst);
+ IShellFolder_Release(folder);
+ }
+ }
+ else
+ IShellFolder_QueryInterface(This->parent, &IID_ISFHelper, (void**)&psfhlpdst);
+
IShellFolder_QueryInterface(psfFrom, &IID_ISFHelper, (void**)&psfhlpsrc);
/* do the copy/move */
--
2.7.1

View File

@ -0,0 +1,35 @@
From 540ec171b1ad3d84c2087f616151103e4a4593df Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Michael=20M=C3=BCller?= <michael@fds-team.de>
Date: Sat, 2 Apr 2016 03:47:48 +0200
Subject: shell32: Correctly interpret result of SHFileOperation in UNIXFS copy
and delete.
---
dlls/shell32/shfldr_unixfs.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/dlls/shell32/shfldr_unixfs.c b/dlls/shell32/shfldr_unixfs.c
index be1ba81..17998f2 100644
--- a/dlls/shell32/shfldr_unixfs.c
+++ b/dlls/shell32/shfldr_unixfs.c
@@ -847,7 +847,7 @@ static HRESULT UNIXFS_copy(LPCWSTR pwszDosSrc, LPCWSTR pwszDosDst)
op.pFrom = pwszSrc;
op.pTo = pwszDst;
op.fFlags = FOF_ALLOWUNDO;
- if (!SHFileOperationW(&op))
+ if (SHFileOperationW(&op))
{
WARN("SHFileOperationW failed\n");
res = E_FAIL;
@@ -1981,7 +1981,7 @@ static HRESULT UNIXFS_delete_with_shfileop(UnixFolder *This, UINT cidl, const LP
op.wFunc = FO_DELETE;
op.pFrom = wszPathsList;
op.fFlags = FOF_ALLOWUNDO;
- if (!SHFileOperationW(&op))
+ if (SHFileOperationW(&op))
{
WARN("SHFileOperationW failed\n");
ret = E_FAIL;
--
2.7.1

View File

@ -0,0 +1,159 @@
From 9540fdc5b1668e4b575ce00539454b8ac66457a0 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Michael=20M=C3=BCller?= <michael@fds-team.de>
Date: Sat, 2 Apr 2016 04:15:02 +0200
Subject: shell32: Add support for setting/getting PREFERREDDROPEFFECT in
IDataObject.
---
dlls/shell32/clipboard.c | 40 ++++++++++++++++++++++++++++++++++++++++
dlls/shell32/dataobject.c | 24 +++++++++++++++++++++---
dlls/shell32/shell32_main.h | 2 ++
3 files changed, 63 insertions(+), 3 deletions(-)
diff --git a/dlls/shell32/clipboard.c b/dlls/shell32/clipboard.c
index 82df534..9c6f284 100644
--- a/dlls/shell32/clipboard.c
+++ b/dlls/shell32/clipboard.c
@@ -38,6 +38,8 @@
#include <stdarg.h>
#include <string.h>
+#define NONAMELESSUNION
+
#include "windef.h"
#include "winbase.h"
#include "winreg.h"
@@ -214,3 +216,41 @@ HGLOBAL RenderFILENAMEW (LPITEMIDLIST pidlRoot, LPITEMIDLIST * apidl, UINT cidl)
return hGlobal;
}
+
+HGLOBAL RenderPREFERREDDROPEFFECT (DWORD value)
+{
+ DWORD *pEffect;
+ HGLOBAL hGlobal;
+
+ TRACE("(%d)\n", value);
+
+ hGlobal = GlobalAlloc(GHND|GMEM_SHARE, sizeof(DWORD));
+ if(!hGlobal) return hGlobal;
+
+ pEffect = GlobalLock(hGlobal);
+ if (pEffect)
+ {
+ *pEffect = value;
+ GlobalUnlock(hGlobal);
+ }
+
+ return hGlobal;
+}
+
+HRESULT GetPREFERREDDROPEFFECT (STGMEDIUM *pmedium, DWORD *value)
+{
+ DWORD *pEffect;
+ BOOL result = E_OUTOFMEMORY;
+
+ TRACE("(%p, %p)\n", pmedium, value);
+
+ pEffect = GlobalLock(pmedium->u.hGlobal);
+ if (pEffect)
+ {
+ *value = *pEffect;
+ result = S_OK;
+ GlobalUnlock(pmedium->u.hGlobal);
+ }
+
+ return result;
+}
diff --git a/dlls/shell32/dataobject.c b/dlls/shell32/dataobject.c
index cc7b63e..5a18a1a 100644
--- a/dlls/shell32/dataobject.c
+++ b/dlls/shell32/dataobject.c
@@ -197,7 +197,7 @@ LPENUMFORMATETC IEnumFORMATETC_Constructor(UINT cfmt, const FORMATETC afmt[])
*/
/* number of supported formats */
-#define MAX_FORMATS 4
+#define MAX_FORMATS 5
typedef struct
{
@@ -209,12 +209,13 @@ typedef struct
LPITEMIDLIST pidl;
LPITEMIDLIST * apidl;
UINT cidl;
+ DWORD dropEffect;
FORMATETC pFormatEtc[MAX_FORMATS];
UINT cfShellIDList;
UINT cfFileNameA;
UINT cfFileNameW;
-
+ UINT cfDropEffect;
} IDataObjectImpl;
static inline IDataObjectImpl *impl_from_IDataObject(IDataObject *iface)
@@ -314,6 +315,10 @@ static HRESULT WINAPI IDataObject_fnGetData(IDataObject *iface, LPFORMATETC pfor
if (This->cidl < 1) return(E_UNEXPECTED);
pmedium->u.hGlobal = RenderFILENAMEW(This->pidl, This->apidl, This->cidl);
}
+ else if (pformatetcIn->cfFormat == This->cfDropEffect)
+ {
+ pmedium->u.hGlobal = RenderPREFERREDDROPEFFECT(This->dropEffect);
+ }
else
{
FIXME("-- expected clipformat not implemented\n");
@@ -368,7 +373,17 @@ static HRESULT WINAPI IDataObject_fnGetCanonicalFormatEtc(IDataObject *iface, LP
static HRESULT WINAPI IDataObject_fnSetData(IDataObject *iface, LPFORMATETC pformatetc, STGMEDIUM *pmedium, BOOL fRelease)
{
IDataObjectImpl *This = impl_from_IDataObject(iface);
- FIXME("(%p)->()\n", This);
+
+ FIXME("(%p)->(%p, %p, %u): semi-stub\n", This, pformatetc, pmedium, fRelease);
+
+ if (pformatetc->cfFormat == This->cfDropEffect)
+ {
+ if (pmedium->tymed == TYMED_HGLOBAL)
+ return GetPREFERREDDROPEFFECT(pmedium, &This->dropEffect);
+ else
+ return DV_E_TYMED;
+ }
+
return E_NOTIMPL;
}
@@ -441,14 +456,17 @@ IDataObject* IDataObject_Constructor(HWND hwndOwner,
dto->pidl = ILClone(pMyPidl);
dto->apidl = _ILCopyaPidl(apidl, cidl);
dto->cidl = cidl;
+ dto->dropEffect = 0;
dto->cfShellIDList = RegisterClipboardFormatW(CFSTR_SHELLIDLISTW);
dto->cfFileNameA = RegisterClipboardFormatA(CFSTR_FILENAMEA);
dto->cfFileNameW = RegisterClipboardFormatW(CFSTR_FILENAMEW);
+ dto->cfDropEffect = RegisterClipboardFormatW(CFSTR_PREFERREDDROPEFFECTW);
InitFormatEtc(dto->pFormatEtc[0], dto->cfShellIDList, TYMED_HGLOBAL);
InitFormatEtc(dto->pFormatEtc[1], CF_HDROP, TYMED_HGLOBAL);
InitFormatEtc(dto->pFormatEtc[2], dto->cfFileNameA, TYMED_HGLOBAL);
InitFormatEtc(dto->pFormatEtc[3], dto->cfFileNameW, TYMED_HGLOBAL);
+ InitFormatEtc(dto->pFormatEtc[4], dto->cfDropEffect, TYMED_HGLOBAL);
}
TRACE("(%p)->(apidl=%p cidl=%u)\n",dto, apidl, cidl);
diff --git a/dlls/shell32/shell32_main.h b/dlls/shell32/shell32_main.h
index 492f79f..29822b7 100644
--- a/dlls/shell32/shell32_main.h
+++ b/dlls/shell32/shell32_main.h
@@ -130,6 +130,8 @@ HGLOBAL RenderHDROP(LPITEMIDLIST pidlRoot, LPITEMIDLIST * apidl, UINT cidl) DECL
HGLOBAL RenderSHELLIDLIST (LPITEMIDLIST pidlRoot, LPITEMIDLIST * apidl, UINT cidl) DECLSPEC_HIDDEN;
HGLOBAL RenderFILENAMEA (LPITEMIDLIST pidlRoot, LPITEMIDLIST * apidl, UINT cidl) DECLSPEC_HIDDEN;
HGLOBAL RenderFILENAMEW (LPITEMIDLIST pidlRoot, LPITEMIDLIST * apidl, UINT cidl) DECLSPEC_HIDDEN;
+HGLOBAL RenderPREFERREDDROPEFFECT (DWORD value);
+HRESULT GetPREFERREDDROPEFFECT (STGMEDIUM *pmedium, DWORD *value);
/* Change Notification */
void InitChangeNotifications(void) DECLSPEC_HIDDEN;
--
2.7.1

View File

@ -0,0 +1,152 @@
From 60a000e4b5c59b93db1ea24566ad4d7eeea9408b Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Michael=20M=C3=BCller?= <michael@fds-team.de>
Date: Sat, 2 Apr 2016 04:17:19 +0200
Subject: shell32: Add parameter to ISFHelper::DeleteItems to allow deleting
files without confirmation.
---
dlls/shell32/recyclebin.c | 6 +++---
dlls/shell32/shellfolder.h | 4 ++--
dlls/shell32/shfldr_fs.c | 3 ++-
dlls/shell32/shfldr_unixfs.c | 7 ++++---
dlls/shell32/shlview.c | 2 +-
dlls/shell32/shlview_cmenu.c | 2 +-
6 files changed, 13 insertions(+), 11 deletions(-)
diff --git a/dlls/shell32/recyclebin.c b/dlls/shell32/recyclebin.c
index 28098af..f890d97 100644
--- a/dlls/shell32/recyclebin.c
+++ b/dlls/shell32/recyclebin.c
@@ -182,7 +182,7 @@ static void DoErase(RecycleBinMenu *This)
ISFHelper *helper;
IShellFolder2_QueryInterface(This->folder,&IID_ISFHelper,(void**)&helper);
if(helper)
- ISFHelper_DeleteItems(helper,This->cidl,(LPCITEMIDLIST*)This->apidl);
+ ISFHelper_DeleteItems(helper, This->cidl, (LPCITEMIDLIST *)This->apidl, TRUE);
}
static void DoRestore(RecycleBinMenu *This)
@@ -824,10 +824,10 @@ static HRESULT erase_items(HWND parent,const LPCITEMIDLIST * apidl, UINT cidl, B
}
static HRESULT WINAPI RecycleBin_DeleteItems(ISFHelper * iface, UINT cidl,
- LPCITEMIDLIST * apidl)
+ LPCITEMIDLIST * apidl, BOOL confirm)
{
TRACE("(%p,%u,%p)\n",iface,cidl,apidl);
- return erase_items(GetActiveWindow(),apidl,cidl,TRUE);
+ return erase_items(GetActiveWindow(), apidl, cidl, confirm);
}
static HRESULT WINAPI RecycleBin_CopyItems(ISFHelper * iface,
diff --git a/dlls/shell32/shellfolder.h b/dlls/shell32/shellfolder.h
index 942e0e7..b8083a2 100644
--- a/dlls/shell32/shellfolder.h
+++ b/dlls/shell32/shellfolder.h
@@ -48,7 +48,7 @@ DECLARE_INTERFACE_(ISFHelper,IUnknown)
/*** ISFHelper methods ***/
STDMETHOD(GetUniqueName)(THIS_ LPWSTR lpName, UINT uLen) PURE;
STDMETHOD(AddFolder)(THIS_ HWND hwnd, LPCWSTR lpName, LPITEMIDLIST * ppidlOut) PURE;
- STDMETHOD(DeleteItems)(THIS_ UINT cidl, LPCITEMIDLIST * apidl) PURE;
+ STDMETHOD(DeleteItems)(THIS_ UINT cidl, LPCITEMIDLIST *apidl, BOOL confirm) PURE;
STDMETHOD(CopyItems)(THIS_ IShellFolder * pSFFrom, UINT cidl, LPCITEMIDLIST * apidl) PURE;
};
#undef INTERFACE
@@ -61,7 +61,7 @@ DECLARE_INTERFACE_(ISFHelper,IUnknown)
/*** ISFHelper methods ***/
#define ISFHelper_GetUniqueName(p,a,b) (p)->lpVtbl->GetUniqueName(p,a,b)
#define ISFHelper_AddFolder(p,a,b,c) (p)->lpVtbl->AddFolder(p,a,b,c)
-#define ISFHelper_DeleteItems(p,a,b) (p)->lpVtbl->DeleteItems(p,a,b)
+#define ISFHelper_DeleteItems(p,a,b,c) (p)->lpVtbl->DeleteItems(p,a,b,c)
#define ISFHelper_CopyItems(p,a,b,c) (p)->lpVtbl->CopyItems(p,a,b,c)
#endif
diff --git a/dlls/shell32/shfldr_fs.c b/dlls/shell32/shfldr_fs.c
index d8bcb4c..3d88fbd 100644
--- a/dlls/shell32/shfldr_fs.c
+++ b/dlls/shell32/shfldr_fs.c
@@ -1230,7 +1230,7 @@ static WCHAR *build_paths_list(LPCWSTR wszBasePath, int cidl, const LPCITEMIDLIS
* deletes items in folder
*/
static HRESULT WINAPI
-ISFHelper_fnDeleteItems (ISFHelper * iface, UINT cidl, LPCITEMIDLIST * apidl)
+ISFHelper_fnDeleteItems (ISFHelper *iface, UINT cidl, LPCITEMIDLIST *apidl, BOOL confirm)
{
IGenericSFImpl *This = impl_from_ISFHelper(iface);
UINT i;
@@ -1255,6 +1255,7 @@ ISFHelper_fnDeleteItems (ISFHelper * iface, UINT cidl, LPCITEMIDLIST * apidl)
op.wFunc = FO_DELETE;
op.pFrom = wszPathsList;
op.fFlags = FOF_ALLOWUNDO;
+ if (!confirm) op.fFlags |= FOF_NOCONFIRMATION;
if (SHFileOperationW(&op))
{
WARN("SHFileOperation failed\n");
diff --git a/dlls/shell32/shfldr_unixfs.c b/dlls/shell32/shfldr_unixfs.c
index 17998f2..d558efb 100644
--- a/dlls/shell32/shfldr_unixfs.c
+++ b/dlls/shell32/shfldr_unixfs.c
@@ -1939,7 +1939,7 @@ static HRESULT WINAPI SFHelper_AddFolder(ISFHelper* iface, HWND hwnd, LPCWSTR pw
* be converted, S_FALSE is returned. In such situation DeleteItems will try to delete
* the files using syscalls
*/
-static HRESULT UNIXFS_delete_with_shfileop(UnixFolder *This, UINT cidl, const LPCITEMIDLIST *apidl)
+static HRESULT UNIXFS_delete_with_shfileop(UnixFolder *This, UINT cidl, const LPCITEMIDLIST *apidl, BOOL confirm)
{
char szAbsolute[FILENAME_MAX], *pszRelative;
LPWSTR wszPathsList, wszListPos;
@@ -1981,6 +1981,7 @@ static HRESULT UNIXFS_delete_with_shfileop(UnixFolder *This, UINT cidl, const LP
op.wFunc = FO_DELETE;
op.pFrom = wszPathsList;
op.fFlags = FOF_ALLOWUNDO;
+ if (!confirm) op.fFlags |= FOF_NOCONFIRMATION;
if (SHFileOperationW(&op))
{
WARN("SHFileOperationW failed\n");
@@ -2019,7 +2020,7 @@ static HRESULT UNIXFS_delete_with_syscalls(UnixFolder *This, UINT cidl, const LP
return S_OK;
}
-static HRESULT WINAPI SFHelper_DeleteItems(ISFHelper* iface, UINT cidl, LPCITEMIDLIST* apidl)
+static HRESULT WINAPI SFHelper_DeleteItems(ISFHelper *iface, UINT cidl, LPCITEMIDLIST *apidl, BOOL confirm)
{
UnixFolder *This = impl_from_ISFHelper(iface);
char szAbsolute[FILENAME_MAX], *pszRelative;
@@ -2030,7 +2031,7 @@ static HRESULT WINAPI SFHelper_DeleteItems(ISFHelper* iface, UINT cidl, LPCITEMI
TRACE("(%p)->(%d %p)\n", This, cidl, apidl);
- hr = UNIXFS_delete_with_shfileop(This, cidl, apidl);
+ hr = UNIXFS_delete_with_shfileop(This, cidl, apidl, confirm);
if (hr == S_FALSE)
hr = UNIXFS_delete_with_syscalls(This, cidl, apidl);
diff --git a/dlls/shell32/shlview.c b/dlls/shell32/shlview.c
index b763468..1770e6f 100644
--- a/dlls/shell32/shlview.c
+++ b/dlls/shell32/shlview.c
@@ -1579,7 +1579,7 @@ static LRESULT ShellView_OnNotify(IShellViewImpl * This, UINT CtlID, LPNMHDR lpn
}
/* perform the item deletion */
- ISFHelper_DeleteItems(psfhlp, i, (LPCITEMIDLIST*)pItems);
+ ISFHelper_DeleteItems(psfhlp, i, (LPCITEMIDLIST *)pItems, TRUE);
ISFHelper_Release(psfhlp);
/* free pidl array memory */
diff --git a/dlls/shell32/shlview_cmenu.c b/dlls/shell32/shlview_cmenu.c
index d972922..494d95b 100644
--- a/dlls/shell32/shlview_cmenu.c
+++ b/dlls/shell32/shlview_cmenu.c
@@ -275,7 +275,7 @@ static void DoDelete(ContextMenu *This)
IShellFolder_QueryInterface(This->parent, &IID_ISFHelper, (void**)&helper);
if (helper)
{
- ISFHelper_DeleteItems(helper, This->cidl, (LPCITEMIDLIST*)This->apidl);
+ ISFHelper_DeleteItems(helper, This->cidl, (LPCITEMIDLIST *)This->apidl, TRUE);
ISFHelper_Release(helper);
}
}
--
2.7.1

View File

@ -0,0 +1,113 @@
From c6df9e2fd8f92597a728935e67a6ac6c3bc1223c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Michael=20M=C3=BCller?= <michael@fds-team.de>
Date: Sat, 2 Apr 2016 04:22:07 +0200
Subject: shell32: Remove source files when using cut in the context menu.
---
dlls/shell32/shlview_cmenu.c | 75 +++++++++++++++++++++++++++++++++++++++++---
1 file changed, 71 insertions(+), 4 deletions(-)
diff --git a/dlls/shell32/shlview_cmenu.c b/dlls/shell32/shlview_cmenu.c
index 494d95b..c32a4e8 100644
--- a/dlls/shell32/shlview_cmenu.c
+++ b/dlls/shell32/shlview_cmenu.c
@@ -281,6 +281,64 @@ static void DoDelete(ContextMenu *This)
}
/**************************************************************************
+ * SetDropEffect
+ *
+ * Set the drop effect in a IDataObject object
+ */
+static void SetDropEffect(IDataObject *dataobject, DWORD value)
+{
+ FORMATETC formatetc;
+ STGMEDIUM medium;
+ DWORD *effect;
+
+ InitFormatEtc(formatetc, RegisterClipboardFormatW(CFSTR_PREFERREDDROPEFFECTW), TYMED_HGLOBAL);
+
+ medium.tymed = TYMED_HGLOBAL;
+ medium.pUnkForRelease = NULL;
+ medium.u.hGlobal = GlobalAlloc(GHND|GMEM_SHARE, sizeof(DWORD));
+ if (!medium.u.hGlobal) return;
+
+ effect = GlobalLock(medium.u.hGlobal);
+ if (!effect)
+ {
+ ReleaseStgMedium(&medium);
+ return;
+ }
+ *effect = value;
+ GlobalUnlock(effect);
+
+ IDataObject_SetData(dataobject, &formatetc, &medium, FALSE);
+ ReleaseStgMedium(&medium);
+}
+
+/**************************************************************************
+ * GetDropEffect
+ *
+ * Get the drop effect from a IDataObject object
+ */
+static void GetDropEffect(IDataObject *dataobject, DWORD *value)
+{
+ FORMATETC formatetc;
+ STGMEDIUM medium;
+ DWORD *effect;
+
+ *value = DROPEFFECT_NONE;
+
+ InitFormatEtc(formatetc, RegisterClipboardFormatW(CFSTR_PREFERREDDROPEFFECTW), TYMED_HGLOBAL);
+
+ if (SUCCEEDED(IDataObject_GetData(dataobject, &formatetc, &medium)))
+ {
+ effect = GlobalLock(medium.u.hGlobal);
+ if (effect)
+ {
+ *value = *effect;
+ GlobalUnlock(effect);
+ }
+ ReleaseStgMedium(&medium);
+ }
+}
+
+/**************************************************************************
* DoCopyOrCut
*
* copies the currently selected items into the clipboard
@@ -293,6 +351,7 @@ static void DoCopyOrCut(ContextMenu *This, HWND hwnd, BOOL cut)
if (SUCCEEDED(IShellFolder_GetUIObjectOf(This->parent, hwnd, This->cidl, (LPCITEMIDLIST*)This->apidl, &IID_IDataObject, 0, (void**)&dataobject)))
{
+ SetDropEffect(dataobject, cut ? DROPEFFECT_MOVE : DROPEFFECT_COPY);
OleSetClipboard(dataobject);
IDataObject_Release(dataobject);
}
@@ -818,11 +877,19 @@ static BOOL DoPaste(ContextMenu *This)
/* do the copy/move */
if (psfhlpdst && psfhlpsrc)
{
+ DWORD dropEffect;
+ GetDropEffect(pda, &dropEffect);
+
if (SUCCEEDED(ISFHelper_CopyItems(psfhlpdst, psfFrom, lpcida->cidl, (LPCITEMIDLIST*)apidl)))
- bSuccess = TRUE;
- /* FIXME handle move
- ISFHelper_DeleteItems(psfhlpsrc, lpcida->cidl, apidl);
- */
+ {
+ if (dropEffect == DROPEFFECT_MOVE)
+ {
+ if (SUCCEEDED(ISFHelper_DeleteItems(psfhlpsrc, lpcida->cidl, (LPCITEMIDLIST*)apidl, FALSE)))
+ bSuccess = TRUE;
+ }
+ else
+ bSuccess = TRUE;
+ }
}
if(psfhlpdst) ISFHelper_Release(psfhlpdst);
if(psfhlpsrc) ISFHelper_Release(psfhlpsrc);
--
2.7.1

View File

@ -0,0 +1,30 @@
From 47c24300c6530de5dfe32f352ef839e62ebbd520 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Michael=20M=C3=BCller?= <michael@fds-team.de>
Date: Sat, 2 Apr 2016 04:41:56 +0200
Subject: shell32: Recognize cut/copy/paste string verbs in item menu context
menu.
---
dlls/shell32/shlview_cmenu.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/dlls/shell32/shlview_cmenu.c b/dlls/shell32/shlview_cmenu.c
index c32a4e8..cfe88d5 100644
--- a/dlls/shell32/shlview_cmenu.c
+++ b/dlls/shell32/shlview_cmenu.c
@@ -554,6 +554,12 @@ static HRESULT WINAPI ItemMenu_InvokeCommand(
DoDelete(This);
else if (strcmp(lpcmi->lpVerb,"properties")==0)
DoOpenProperties(This, lpcmi->hwnd);
+ else if (strcmp(lpcmi->lpVerb,"cut")==0)
+ DoCopyOrCut(This, lpcmi->hwnd, TRUE);
+ else if (strcmp(lpcmi->lpVerb,"copy")==0)
+ DoCopyOrCut(This, lpcmi->hwnd, FALSE);
+ else if (strcmp(lpcmi->lpVerb,"paste")==0)
+ DoPaste(This);
else {
FIXME("Unhandled string verb %s\n",debugstr_a(lpcmi->lpVerb));
return E_FAIL;
--
2.7.1

View File

@ -0,0 +1,3 @@
Fixes: [34319] Add support for Paste in context menu
Fixes: [34322] Fix implementation of Cut file operation
Fixes: [34321] Fix Cut/Copy/Paste keyboard shortcuts in Total Commander