1 /*
2  * executable drop target handler
3  *
4  * Copyright 2014              Huw Campbell
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19  */
20 
21 #include <precomp.h>
22 
23 WINE_DEFAULT_DEBUG_CHANNEL (shell);
24 
25 CExeDropHandler::CExeDropHandler()
26 {
27     pclsid = (CLSID *)&CLSID_ExeDropHandler;
28 }
29 
30 CExeDropHandler::~CExeDropHandler()
31 {
32 
33 }
34 
35 // IDropTarget
36 HRESULT WINAPI CExeDropHandler::DragEnter(IDataObject *pDataObject, DWORD dwKeyState, POINTL pt, DWORD *pdwEffect)
37 {
38     TRACE ("(%p)\n", this);
39     *pdwEffect = DROPEFFECT_COPY;
40     return S_OK;
41 }
42 
43 HRESULT WINAPI CExeDropHandler::DragOver(DWORD dwKeyState, POINTL pt, DWORD *pdwEffect)
44 {
45     TRACE ("(%p)\n", this);
46     *pdwEffect = DROPEFFECT_COPY;
47     return S_OK;
48 }
49 
50 HRESULT WINAPI CExeDropHandler::DragLeave()
51 {
52     TRACE ("(%p)\n", this);
53     return S_OK;
54 }
55 
56 HRESULT WINAPI CExeDropHandler::Drop(IDataObject *pDataObject, DWORD dwKeyState, POINTL pt, DWORD *pdwEffect)
57 {
58     TRACE ("(%p)\n", this);
59     FORMATETC fmt;
60     STGMEDIUM medium;
61     LPWSTR pszSrcList;
62     InitFormatEtc (fmt, CF_HDROP, TYMED_HGLOBAL);
63     WCHAR wszBuf[MAX_PATH * 2 + 8], *pszEnd = wszBuf;
64     size_t cchRemaining = _countof(wszBuf);
65 
66     if (SUCCEEDED(pDataObject->GetData(&fmt, &medium)) /* && SUCCEEDED(pDataObject->GetData(&fmt2, &medium))*/)
67     {
68         LPDROPFILES lpdf = (LPDROPFILES) GlobalLock(medium.hGlobal);
69         if (!lpdf)
70         {
71             ERR("Error locking global\n");
72             return E_FAIL;
73         }
74         pszSrcList = (LPWSTR) (((byte*) lpdf) + lpdf->pFiles);
75         while (*pszSrcList)
76         {
77             if (StrChrW(pszSrcList, L' ') && cchRemaining > 3)
78                 StringCchPrintfExW(pszEnd, cchRemaining, &pszEnd, &cchRemaining, 0, L"\"%ls\" ", pszSrcList);
79             else
80                 StringCchPrintfExW(pszEnd, cchRemaining, &pszEnd, &cchRemaining, 0, L"%ls ", pszSrcList);
81 
82             pszSrcList += wcslen(pszSrcList) + 1;
83         }
84     }
85 
86     ShellExecuteW(NULL, L"open", sPathTarget, wszBuf, NULL,SW_SHOWNORMAL);
87 
88     return S_OK;
89 }
90 
91 
92 // IPersistFile
93 HRESULT WINAPI CExeDropHandler::GetCurFile(LPOLESTR *ppszFileName)
94 {
95     FIXME ("(%p)\n", this);
96     return E_NOTIMPL;
97 }
98 
99 HRESULT WINAPI CExeDropHandler::IsDirty()
100 {
101     FIXME ("(%p)\n", this);
102     return E_NOTIMPL;
103 }
104 
105 HRESULT WINAPI CExeDropHandler::Load(LPCOLESTR pszFileName, DWORD dwMode)
106 {
107     UINT len = strlenW(pszFileName);
108     sPathTarget = (WCHAR *)SHAlloc((len + 1) * sizeof(WCHAR));
109     memcpy(sPathTarget, pszFileName, (len + 1) * sizeof(WCHAR));
110     return S_OK;
111 }
112 
113 HRESULT WINAPI CExeDropHandler::Save(LPCOLESTR pszFileName, BOOL fRemember)
114 {
115     FIXME ("(%p)\n", this);
116     return E_NOTIMPL;
117 }
118 
119 HRESULT WINAPI CExeDropHandler::SaveCompleted(LPCOLESTR pszFileName)
120 {
121     FIXME ("(%p)\n", this);
122     return E_NOTIMPL;
123 }
124 
125 /************************************************************************
126  * CFSFolder::GetClassID
127  */
128 HRESULT WINAPI CExeDropHandler::GetClassID(CLSID * lpClassId)
129 {
130     TRACE ("(%p)\n", this);
131 
132     if (!lpClassId)
133         return E_POINTER;
134 
135     *lpClassId = *pclsid;
136 
137     return S_OK;
138 }