2 * Trash virtual folder support. The trashing engine is implemented in trash.c
4 * Copyright (C) 2006 Mikolaj Zalewski
5 * Copyright (C) 2009 Andrew Hill
6 * Copyright (C) 2017 Giannis Adamopoulos
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
25 WINE_DEFAULT_DEBUG_CHANNEL (shell
);
27 class CRecyclerDropTarget
:
28 public CComObjectRootEx
<CComMultiThreadModelNoCS
>,
32 BOOL fAcceptFmt
; /* flag for pending Drop */
35 static HRESULT
_DoDeleteDataObject(IDataObject
*pda
, DWORD fMask
)
40 InitFormatEtc (formatetc
, CF_HDROP
, TYMED_HGLOBAL
);
41 hr
= pda
->GetData(&formatetc
, &medium
);
42 if (FAILED_UNEXPECTEDLY(hr
))
45 LPDROPFILES lpdf
= (LPDROPFILES
) GlobalLock(medium
.hGlobal
);
48 ERR("Error locking global\n");
53 SHFILEOPSTRUCTW FileOp
;
54 ZeroMemory(&FileOp
, sizeof(FileOp
));
55 FileOp
.wFunc
= FO_DELETE
;
56 FileOp
.pFrom
= (LPWSTR
) (((byte
*) lpdf
) + lpdf
->pFiles
);;
57 if ((fMask
& CMIC_MASK_SHIFT_DOWN
) == 0)
58 FileOp
.fFlags
= FOF_ALLOWUNDO
;
59 ERR("Deleting file (just the first) = %s, allowundo: %d\n", debugstr_w(FileOp
.pFrom
), (FileOp
.fFlags
== FOF_ALLOWUNDO
));
61 if (SHFileOperationW(&FileOp
) != 0)
63 ERR("SHFileOperation failed with 0x%x\n", GetLastError());
67 ReleaseStgMedium(&medium
);
72 struct DeleteThreadData
{
77 static DWORD WINAPI
_DoDeleteThreadProc(LPVOID lpParameter
)
79 DeleteThreadData
*data
= static_cast<DeleteThreadData
*>(lpParameter
);
81 IDataObject
*pDataObject
;
82 HRESULT hr
= CoGetInterfaceAndReleaseStream (data
->s
, IID_PPV_ARG(IDataObject
, &pDataObject
));
85 _DoDeleteDataObject(pDataObject
, data
->fMask
);
87 pDataObject
->Release();
89 HeapFree(GetProcessHeap(), 0, data
);
93 static void _DoDeleteAsync(IDataObject
*pda
, DWORD fMask
)
95 DeleteThreadData
*data
= static_cast<DeleteThreadData
*>(HeapAlloc(GetProcessHeap(), 0, sizeof(DeleteThreadData
)));
97 CoMarshalInterThreadInterfaceInStream(IID_IDataObject
, pda
, &data
->s
);
98 SHCreateThread(_DoDeleteThreadProc
, data
, NULL
, NULL
);
103 CRecyclerDropTarget()
106 cfShellIDList
= RegisterClipboardFormatW(CFSTR_SHELLIDLIST
);
109 HRESULT WINAPI
DragEnter(IDataObject
*pDataObject
,
110 DWORD dwKeyState
, POINTL pt
, DWORD
*pdwEffect
)
112 TRACE("Recycle bin drag over (%p)\n", this);
113 /* The recycle bin accepts pretty much everything, and sets a CSIDL flag. */
116 *pdwEffect
= DROPEFFECT_MOVE
;
120 HRESULT WINAPI
DragOver(DWORD dwKeyState
, POINTL pt
, DWORD
*pdwEffect
)
122 TRACE("(%p)\n", this);
127 *pdwEffect
= DROPEFFECT_MOVE
;
132 HRESULT WINAPI
DragLeave()
134 TRACE("(%p)\n", this);
141 HRESULT WINAPI
Drop(IDataObject
*pDataObject
,
142 DWORD dwKeyState
, POINTL pt
, DWORD
*pdwEffect
)
144 TRACE("(%p) object dropped on recycle bin, effect %u\n", this, *pdwEffect
);
146 /* TODO: pdwEffect should be read and make the drop object be permanently deleted in the move case (shift held) */
149 TRACE("(%p)->(DataObject=%p)\n", this, pDataObject
);
150 InitFormatEtc (fmt
, cfShellIDList
, TYMED_HGLOBAL
);
152 /* Handle cfShellIDList Drop objects here, otherwise send the approriate message to other software */
153 if (SUCCEEDED(pDataObject
->QueryGetData(&fmt
)))
157 if ((dwKeyState
& MK_SHIFT
) == MK_SHIFT
)
158 fMask
|= CMIC_MASK_SHIFT_DOWN
;
160 _DoDeleteAsync(pDataObject
, fMask
);
165 * TODO call SetData on the data object with format CFSTR_TARGETCLSID
166 * set to the Recycle Bin's class identifier CLSID_RecycleBin.
172 DECLARE_NOT_AGGREGATABLE(CRecyclerDropTarget
)
174 DECLARE_PROTECT_FINAL_CONSTRUCT()
176 BEGIN_COM_MAP(CRecyclerDropTarget
)
177 COM_INTERFACE_ENTRY_IID(IID_IDropTarget
, IDropTarget
)
181 HRESULT
CRecyclerDropTarget_CreateInstance(REFIID riid
, LPVOID
* ppvOut
)
183 return ShellObjectCreator
<CRecyclerDropTarget
>(riid
, ppvOut
);