ReactOS  0.4.15-dev-1206-g731eddf
CFSDropTarget.cpp
Go to the documentation of this file.
1 
2 /*
3  * file system folder drop target
4  *
5  * Copyright 1997 Marcus Meissner
6  * Copyright 1998, 1999, 2002 Juergen Schmied
7  *
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.
12  *
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.
17  *
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
21  */
22 
23 #include <precomp.h>
24 
26 
27 /****************************************************************************
28  * BuildPathsList
29  *
30  * Builds a list of paths like the one used in SHFileOperation from a table of
31  * PIDLs relative to the given base folder
32  */
33 static WCHAR* BuildPathsList(LPCWSTR wszBasePath, int cidl, LPCITEMIDLIST *pidls)
34 {
35  WCHAR *pwszPathsList = (WCHAR *)HeapAlloc(GetProcessHeap(), 0, MAX_PATH * sizeof(WCHAR) * cidl + 1);
36  WCHAR *pwszListPos = pwszPathsList;
37 
38  for (int i = 0; i < cidl; i++)
39  {
40  FileStructW* pDataW = _ILGetFileStructW(pidls[i]);
41  if (!pDataW)
42  {
43  ERR("Got garbage pidl\n");
44  continue;
45  }
46 
47  PathCombineW(pwszListPos, wszBasePath, pDataW->wszName);
48  pwszListPos += wcslen(pwszListPos) + 1;
49  }
50  *pwszListPos = 0;
51  return pwszPathsList;
52 }
53 
54 /****************************************************************************
55  * CFSDropTarget::_CopyItems
56  *
57  * copies items to this folder
58  */
60  LPCITEMIDLIST * apidl, BOOL bCopy)
61 {
62  LPWSTR pszSrcList;
63  HRESULT hr;
64  WCHAR wszTargetPath[MAX_PATH + 1];
65 
66  wcscpy(wszTargetPath, m_sPathTarget);
67  //Double NULL terminate.
68  wszTargetPath[wcslen(wszTargetPath) + 1] = '\0';
69 
70  TRACE ("(%p)->(%p,%u,%p)\n", this, pSFFrom, cidl, apidl);
71 
72  STRRET strretFrom;
73  hr = pSFFrom->GetDisplayNameOf(NULL, SHGDN_FORPARSING, &strretFrom);
75  return hr;
76 
77  pszSrcList = BuildPathsList(strretFrom.pOleStr, cidl, apidl);
78  TRACE("Source file (just the first) = %s, target path = %s, bCopy: %d\n", debugstr_w(pszSrcList), debugstr_w(m_sPathTarget), bCopy);
79  CoTaskMemFree(strretFrom.pOleStr);
80  if (!pszSrcList)
81  return E_OUTOFMEMORY;
82 
83  SHFILEOPSTRUCTW op = {0};
84  op.pFrom = pszSrcList;
85  op.pTo = wszTargetPath;
86  op.hwnd = m_hwndSite;
87  op.wFunc = bCopy ? FO_COPY : FO_MOVE;
89 
90  int res = SHFileOperationW(&op);
91 
92  HeapFree(GetProcessHeap(), 0, pszSrcList);
93 
94  if (res)
95  {
96  ERR("SHFileOperationW failed with 0x%x\n", res);
97  return E_FAIL;
98  }
99  return S_OK;
100 }
101 
103  m_cfShellIDList(0),
104  m_fAcceptFmt(FALSE),
105  m_sPathTarget(NULL),
106  m_hwndSite(NULL),
107  m_grfKeyState(0)
108 {
109 }
110 
112 {
113  if (!PathTarget)
114  return E_UNEXPECTED;
115 
117  if (!m_cfShellIDList)
118  return E_FAIL;
119 
120  m_sPathTarget = (WCHAR *)SHAlloc((wcslen(PathTarget) + 1) * sizeof(WCHAR));
121  if (!m_sPathTarget)
122  return E_OUTOFMEMORY;
123 
124  wcscpy(m_sPathTarget, PathTarget);
125 
126  return S_OK;
127 }
128 
130 {
132 }
133 
134 BOOL
135 CFSDropTarget::_GetUniqueFileName(LPWSTR pwszBasePath, LPCWSTR pwszExt, LPWSTR pwszTarget, BOOL bShortcut)
136 {
137  WCHAR wszLink[40];
138 
139  if (!bShortcut)
140  {
141  if (!LoadStringW(shell32_hInstance, IDS_LNK_FILE, wszLink, _countof(wszLink)))
142  wszLink[0] = L'\0';
143  }
144 
145  if (!bShortcut)
146  swprintf(pwszTarget, L"%s%s%s", wszLink, pwszBasePath, pwszExt);
147  else
148  swprintf(pwszTarget, L"%s%s", pwszBasePath, pwszExt);
149 
150  for (UINT i = 2; PathFileExistsW(pwszTarget); ++i)
151  {
152  if (!bShortcut)
153  swprintf(pwszTarget, L"%s%s (%u)%s", wszLink, pwszBasePath, i, pwszExt);
154  else
155  swprintf(pwszTarget, L"%s (%u)%s", pwszBasePath, i, pwszExt);
156  }
157 
158  return TRUE;
159 }
160 
161 /****************************************************************************
162  * IDropTarget implementation
163  */
165 {
166  /* TODO Windows does different drop effects if dragging across drives.
167  i.e., it will copy instead of move if the directories are on different disks. */
168 
169  DWORD dwEffect = m_dwDefaultEffect;
170 
171  *pdwEffect = DROPEFFECT_NONE;
172 
173  if (m_fAcceptFmt) { /* Does our interpretation of the keystate ... */
174  *pdwEffect = KeyStateToDropEffect (dwKeyState);
175 
176  if (*pdwEffect == DROPEFFECT_NONE)
177  *pdwEffect = dwEffect;
178 
179  /* ... matches the desired effect ? */
180  if (dwEffect & *pdwEffect) {
181  return TRUE;
182  }
183  }
184  return FALSE;
185 }
186 
187 HRESULT CFSDropTarget::_GetEffectFromMenu(IDataObject *pDataObject, POINTL pt, DWORD *pdwEffect, DWORD dwAvailableEffects)
188 {
190  if (!hmenu)
191  return E_OUTOFMEMORY;
192 
194 
195  if ((dwAvailableEffects & DROPEFFECT_COPY) == 0)
197  else if ((dwAvailableEffects & DROPEFFECT_MOVE) == 0)
199  else if ((dwAvailableEffects & DROPEFFECT_LINK) == 0)
201 
202  if ((*pdwEffect & DROPEFFECT_COPY))
204  else if ((*pdwEffect & DROPEFFECT_MOVE))
206  else if ((*pdwEffect & DROPEFFECT_LINK))
208 
209  /* FIXME: We need to support shell extensions here */
210 
211  /* We shouldn't use the site window here because the menu should work even when we don't have a site */
212  HWND hwndDummy = CreateWindowEx(0,
213  WC_STATIC,
214  NULL,
216  pt.x,
217  pt.y,
218  1,
219  1,
220  NULL,
221  NULL,
222  NULL,
223  NULL);
224 
225  UINT uCommand = TrackPopupMenu(hpopupmenu,
227  pt.x, pt.y, 0, hwndDummy, NULL);
228 
229  DestroyWindow(hwndDummy);
230 
231  if (uCommand == 0)
232  return S_FALSE;
233  else if (uCommand == IDM_COPYHERE)
234  *pdwEffect = DROPEFFECT_COPY;
235  else if (uCommand == IDM_MOVEHERE)
236  *pdwEffect = DROPEFFECT_MOVE;
237  else if (uCommand == IDM_LINKHERE)
238  *pdwEffect = DROPEFFECT_LINK;
239 
240  return S_OK;
241 }
242 
244 {
245  CComPtr<IFolderView> pfv;
246  POINT ptDrag;
247  HRESULT hr = psfv->QueryInterface(IID_PPV_ARG(IFolderView, &pfv));
248  if (FAILED_UNEXPECTEDLY(hr))
249  return hr;
250 
251  hr = psfv->GetDragPoint(&ptDrag);
252  if (FAILED_UNEXPECTEDLY(hr))
253  return hr;
254 
255  PIDLIST_ABSOLUTE pidlFolder;
256  PUITEMID_CHILD *apidl;
257  UINT cidl;
258  hr = SH_GetApidlFromDataObject(pdtobj, &pidlFolder, &apidl, &cidl);
259  if (FAILED_UNEXPECTEDLY(hr))
260  return hr;
261 
262  CComHeapPtr<POINT> apt;
263  if (!apt.Allocate(cidl))
264  {
265  SHFree(pidlFolder);
266  _ILFreeaPidl(apidl, cidl);
267  return E_OUTOFMEMORY;
268  }
269 
270  for (UINT i = 0; i<cidl; i++)
271  {
272  pfv->GetItemPosition(apidl[i], &apt[i]);
273  apt[i].x += pt.x - ptDrag.x;
274  apt[i].y += pt.y - ptDrag.y;
275  }
276 
277  pfv->SelectAndPositionItems(cidl, apidl, apt, SVSI_SELECT);
278 
279  SHFree(pidlFolder);
280  _ILFreeaPidl(apidl, cidl);
281  return S_OK;
282 }
283 
285  DWORD dwKeyState, POINTL pt, DWORD *pdwEffect)
286 {
287  TRACE("(%p)->(DataObject=%p)\n", this, pDataObject);
288 
289  if (*pdwEffect == DROPEFFECT_NONE)
290  return S_OK;
291 
292  FORMATETC fmt;
293  FORMATETC fmt2;
295 
296  InitFormatEtc (fmt, m_cfShellIDList, TYMED_HGLOBAL);
297  InitFormatEtc (fmt2, CF_HDROP, TYMED_HGLOBAL);
298 
299  if (SUCCEEDED(pDataObject->QueryGetData(&fmt)))
300  m_fAcceptFmt = TRUE;
301  else if (SUCCEEDED(pDataObject->QueryGetData(&fmt2)))
302  m_fAcceptFmt = TRUE;
303 
304  m_grfKeyState = dwKeyState;
305 
306 #define D_NONE DROPEFFECT_NONE
307 #define D_COPY DROPEFFECT_COPY
308 #define D_MOVE DROPEFFECT_MOVE
309 #define D_LINK DROPEFFECT_LINK
310  m_dwDefaultEffect = *pdwEffect;
311  switch (*pdwEffect & (D_COPY | D_MOVE | D_LINK))
312  {
313  case D_COPY | D_MOVE:
314  if (dwKeyState & MK_CONTROL)
316  else
318  break;
319  case D_COPY | D_MOVE | D_LINK:
320  if ((dwKeyState & (MK_SHIFT | MK_CONTROL)) == (MK_SHIFT | MK_CONTROL))
322  else if ((dwKeyState & (MK_SHIFT | MK_CONTROL)) == MK_CONTROL)
324  else
326  break;
327  case D_COPY | D_LINK:
328  if ((dwKeyState & (MK_SHIFT | MK_CONTROL)) == (MK_SHIFT | MK_CONTROL))
330  else
332  break;
333  case D_MOVE | D_LINK:
334  if ((dwKeyState & (MK_SHIFT | MK_CONTROL)) == (MK_SHIFT | MK_CONTROL))
336  else
338  break;
339  }
340 
341  STGMEDIUM medium;
342  if (SUCCEEDED(pDataObject->GetData(&fmt2, &medium)))
343  {
344  WCHAR wstrFirstFile[MAX_PATH];
345  if (DragQueryFileW((HDROP)medium.hGlobal, 0, wstrFirstFile, _countof(wstrFirstFile)))
346  {
347  /* Check if the drive letter is different */
348  if (wstrFirstFile[0] != m_sPathTarget[0])
349  {
351  }
352  }
353  ReleaseStgMedium(&medium);
354  }
355 
356  if (!m_fAcceptFmt)
357  *pdwEffect = DROPEFFECT_NONE;
358  else
359  *pdwEffect = m_dwDefaultEffect;
360 
361  return S_OK;
362 }
363 
365  DWORD *pdwEffect)
366 {
367  TRACE("(%p)\n", this);
368 
369  if (!pdwEffect)
370  return E_INVALIDARG;
371 
372  m_grfKeyState = dwKeyState;
373 
374  _QueryDrop(dwKeyState, pdwEffect);
375 
376  return S_OK;
377 }
378 
380 {
381  TRACE("(%p)\n", this);
382 
384 
385  return S_OK;
386 }
387 
389  DWORD dwKeyState, POINTL pt, DWORD *pdwEffect)
390 {
391  TRACE("(%p) object dropped, effect %u\n", this, *pdwEffect);
392 
393  if (!pdwEffect)
394  return E_INVALIDARG;
395 
397 
398  DWORD dwAvailableEffects = *pdwEffect;
399 
400  _QueryDrop(dwKeyState, pdwEffect);
401 
402  TRACE("pdwEffect: 0x%x, m_dwDefaultEffect: 0x%x, dwAvailableEffects: 0x%x\n", *pdwEffect, m_dwDefaultEffect, dwAvailableEffects);
403 
405  {
406  HRESULT hr = _GetEffectFromMenu(pDataObject, pt, pdwEffect, dwAvailableEffects);
407  if (FAILED_UNEXPECTEDLY(hr) || hr == S_FALSE)
408  return hr;
409  }
410 
411  if (*pdwEffect == DROPEFFECT_MOVE && m_site)
412  {
413  CComPtr<IShellFolderView> psfv;
414  HRESULT hr = IUnknown_QueryService(m_site, SID_IFolderView, IID_PPV_ARG(IShellFolderView, &psfv));
415  if (SUCCEEDED(hr) && psfv->IsDropOnSource(this) == S_OK)
416  {
417  _RepositionItems(psfv, pDataObject, pt);
418  return S_OK;
419  }
420  }
421 
422  BOOL fIsOpAsync = FALSE;
423  CComPtr<IAsyncOperation> pAsyncOperation;
424 
425  if (SUCCEEDED(pDataObject->QueryInterface(IID_PPV_ARG(IAsyncOperation, &pAsyncOperation))))
426  {
427  if (SUCCEEDED(pAsyncOperation->GetAsyncMode(&fIsOpAsync)) && fIsOpAsync)
428  {
429  _DoDropData *data = static_cast<_DoDropData*>(HeapAlloc(GetProcessHeap(), 0, sizeof(_DoDropData)));
430  data->This = this;
431  // Need to maintain this class in case the window is closed or the class exists temporarily (when dropping onto a folder).
432  pDataObject->AddRef();
433  pAsyncOperation->StartOperation(NULL);
435  this->AddRef();
436  data->dwKeyState = dwKeyState;
437  data->pt = pt;
438  // Need to dereference as pdweffect gets freed.
439  data->pdwEffect = *pdwEffect;
441  return S_OK;
442  }
443  }
444  return this->_DoDrop(pDataObject, dwKeyState, pt, pdwEffect);
445 }
446 
447 HRESULT
448 WINAPI
450 {
451  m_site = pUnkSite;
452  return S_OK;
453 }
454 
455 HRESULT
456 WINAPI
458 {
459  if (!m_site)
460  return E_FAIL;
461 
462  return m_site->QueryInterface(riid, ppvSite);
463 }
464 
466  DWORD dwKeyState, POINTL pt, DWORD *pdwEffect)
467 {
468  TRACE("(%p) performing drop, effect %u\n", this, *pdwEffect);
469  FORMATETC fmt;
470  FORMATETC fmt2;
471  STGMEDIUM medium;
472 
473  InitFormatEtc (fmt, m_cfShellIDList, TYMED_HGLOBAL);
474  InitFormatEtc (fmt2, CF_HDROP, TYMED_HGLOBAL);
475 
476  HRESULT hr;
477  bool bCopy = TRUE;
478  bool bLinking = FALSE;
479 
480  /* Figure out what drop operation we're doing */
481  if (pdwEffect)
482  {
483  TRACE("Current drop effect flag %i\n", *pdwEffect);
484  if ((*pdwEffect & DROPEFFECT_MOVE) == DROPEFFECT_MOVE)
485  bCopy = FALSE;
486  if ((*pdwEffect & DROPEFFECT_LINK) == DROPEFFECT_LINK)
487  bLinking = TRUE;
488  }
489 
490  if (SUCCEEDED(pDataObject->QueryGetData(&fmt)))
491  {
492  hr = pDataObject->GetData(&fmt, &medium);
493  TRACE("CFSTR_SHELLIDLIST.\n");
494  if (FAILED(hr))
495  {
496  ERR("CFSTR_SHELLIDLIST failed\n");
497  }
498  /* lock the handle */
499  LPIDA lpcida = (LPIDA)GlobalLock(medium.hGlobal);
500  if (!lpcida)
501  {
502  ReleaseStgMedium(&medium);
503  return E_FAIL;
504  }
505 
506  /* convert the data into pidl */
507  LPITEMIDLIST pidl;
508  LPITEMIDLIST *apidl = _ILCopyCidaToaPidl(&pidl, lpcida);
509  if (!apidl)
510  {
511  ReleaseStgMedium(&medium);
512  return E_FAIL;
513  }
514 
515  CComPtr<IShellFolder> psfDesktop;
516  CComPtr<IShellFolder> psfFrom = NULL;
517 
518  /* Grab the desktop shell folder */
519  hr = SHGetDesktopFolder(&psfDesktop);
520  if (FAILED(hr))
521  {
522  ERR("SHGetDesktopFolder failed\n");
523  SHFree(pidl);
524  _ILFreeaPidl(apidl, lpcida->cidl);
525  ReleaseStgMedium(&medium);
526  return E_FAIL;
527  }
528 
529  /* Find source folder, this is where the clipboard data was copied from */
530  if (_ILIsDesktop(pidl))
531  {
532  /* use desktop shell folder */
533  psfFrom = psfDesktop;
534  }
535  else
536  {
537  hr = psfDesktop->BindToObject(pidl, NULL, IID_PPV_ARG(IShellFolder, &psfFrom));
538  if (FAILED(hr))
539  {
540  ERR("no IShellFolder\n");
541  SHFree(pidl);
542  _ILFreeaPidl(apidl, lpcida->cidl);
543  ReleaseStgMedium(&medium);
544  return E_FAIL;
545  }
546  }
547 
548  if (bLinking)
549  {
550  WCHAR wszTargetPath[MAX_PATH];
551  WCHAR wszPath[MAX_PATH];
552  WCHAR wszTarget[MAX_PATH];
553 
554  wcscpy(wszTargetPath, m_sPathTarget);
555 
556  TRACE("target path = %s", debugstr_w(wszTargetPath));
557 
558  /* We need to create a link for each pidl in the copied items, so step through the pidls from the clipboard */
559  for (UINT i = 0; i < lpcida->cidl; i++)
560  {
561  //Find out which file we're copying
562  STRRET strFile;
563  hr = psfFrom->GetDisplayNameOf(apidl[i], SHGDN_FORPARSING, &strFile);
564  if (FAILED(hr))
565  {
566  ERR("Error source obtaining path");
567  break;
568  }
569 
570  hr = StrRetToBufW(&strFile, apidl[i], wszPath, _countof(wszPath));
571  if (FAILED(hr))
572  {
573  ERR("Error putting source path into buffer");
574  break;
575  }
576  TRACE("source path = %s", debugstr_w(wszPath));
577 
578  // Creating a buffer to hold the combined path
579  WCHAR buffer_1[MAX_PATH] = L"";
580  WCHAR *lpStr1;
581  lpStr1 = buffer_1;
582 
583  LPWSTR pwszFileName = PathFindFileNameW(wszPath);
584  LPWSTR pwszExt = PathFindExtensionW(wszPath);
585  LPWSTR placementPath = PathCombineW(lpStr1, m_sPathTarget, pwszFileName);
586  CComPtr<IPersistFile> ppf;
587 
588  //Check to see if it's already a link.
589  if (!wcsicmp(pwszExt, L".lnk"))
590  {
591  //It's a link so, we create a new one which copies the old.
592  if(!_GetUniqueFileName(placementPath, pwszExt, wszTarget, TRUE))
593  {
594  ERR("Error getting unique file name");
595  hr = E_FAIL;
596  break;
597  }
599  if (FAILED(hr)) {
600  ERR("Error constructing link from file");
601  break;
602  }
603 
604  hr = ppf->Save(wszTarget, FALSE);
605  if (FAILED(hr))
606  break;
608  }
609  else
610  {
611  //It's not a link, so build a new link using the creator class and fill it in.
612  //Create a file name for the link
613  if (!_GetUniqueFileName(placementPath, L".lnk", wszTarget, TRUE))
614  {
615  ERR("Error creating unique file name");
616  hr = E_FAIL;
617  break;
618  }
619 
620  CComPtr<IShellLinkW> pLink;
621  hr = CShellLink::_CreatorClass::CreateInstance(NULL, IID_PPV_ARG(IShellLinkW, &pLink));
622  if (FAILED(hr)) {
623  ERR("Error instantiating IShellLinkW");
624  break;
625  }
626 
627  WCHAR szDirPath[MAX_PATH], *pwszFile;
628  GetFullPathName(wszPath, MAX_PATH, szDirPath, &pwszFile);
629  if (pwszFile) pwszFile[0] = 0;
630 
631  hr = pLink->SetPath(wszPath);
632  if(FAILED(hr))
633  break;
634 
635  hr = pLink->SetWorkingDirectory(szDirPath);
636  if(FAILED(hr))
637  break;
638 
639  hr = pLink->QueryInterface(IID_PPV_ARG(IPersistFile, &ppf));
640  if(FAILED(hr))
641  break;
642 
643  hr = ppf->Save(wszTarget, TRUE);
644  if (FAILED(hr))
645  break;
647  }
648  }
649  }
650  else
651  {
652  hr = _CopyItems(psfFrom, lpcida->cidl, (LPCITEMIDLIST*)apidl, bCopy);
653  }
654 
655  SHFree(pidl);
656  _ILFreeaPidl(apidl, lpcida->cidl);
657  ReleaseStgMedium(&medium);
658  }
659  else if (SUCCEEDED(pDataObject->QueryGetData(&fmt2)))
660  {
661  FORMATETC fmt2;
662  InitFormatEtc (fmt2, CF_HDROP, TYMED_HGLOBAL);
663  if (SUCCEEDED(pDataObject->GetData(&fmt2, &medium)) /* && SUCCEEDED(pDataObject->GetData(&fmt2, &medium))*/)
664  {
665  WCHAR wszTargetPath[MAX_PATH + 1];
666  LPWSTR pszSrcList;
667 
668  wcscpy(wszTargetPath, m_sPathTarget);
669  //Double NULL terminate.
670  wszTargetPath[wcslen(wszTargetPath) + 1] = '\0';
671 
672  LPDROPFILES lpdf = (LPDROPFILES) GlobalLock(medium.hGlobal);
673  if (!lpdf)
674  {
675  ERR("Error locking global\n");
676  return E_FAIL;
677  }
678  pszSrcList = (LPWSTR) (((byte*) lpdf) + lpdf->pFiles);
679  ERR("Source file (just the first) = %s, target path = %s, bCopy: %d\n", debugstr_w(pszSrcList), debugstr_w(wszTargetPath), bCopy);
680 
682  ZeroMemory(&op, sizeof(op));
683  op.pFrom = pszSrcList;
684  op.pTo = wszTargetPath;
685  op.hwnd = m_hwndSite;
686  op.wFunc = bCopy ? FO_COPY : FO_MOVE;
688  int res = SHFileOperationW(&op);
689  if (res)
690  {
691  ERR("SHFileOperationW failed with 0x%x\n", res);
692  hr = E_FAIL;
693  }
694 
695  return hr;
696  }
697  ERR("Error calling GetData\n");
698  hr = E_FAIL;
699  }
700  else
701  {
702  ERR("No viable drop format.\n");
703  hr = E_FAIL;
704  }
705  return hr;
706 }
707 
709 {
711  _DoDropData *data = static_cast<_DoDropData*>(lpParameter);
712  CComPtr<IDataObject> pDataObject;
714 
715  if (SUCCEEDED(hr))
716  {
717  CComPtr<IAsyncOperation> pAsyncOperation;
718  hr = data->This->_DoDrop(pDataObject, data->dwKeyState, data->pt, &data->pdwEffect);
719  if (SUCCEEDED(pDataObject->QueryInterface(IID_PPV_ARG(IAsyncOperation, &pAsyncOperation))))
720  {
721  pAsyncOperation->EndOperation(hr, NULL, data->pdwEffect);
722  }
723  }
724  //Release the CFSFolder and data object holds in the copying thread.
725  data->This->Release();
726  //Release the parameter from the heap.
728  CoUninitialize();
729  return 0;
730 }
731 
733 {
734  return ShellObjectCreatorInit<CFSDropTarget>(sPathTarget, riid, ppvOut);
735 }
virtual HRESULT WINAPI Drop(IDataObject *pDataObject, DWORD dwKeyState, POINTL pt, DWORD *pdwEffect)
#define WS_CLIPSIBLINGS
Definition: pedump.c:618
LPWSTR m_sPathTarget
Definition: CFSDropTarget.h:34
#define WS_DISABLED
Definition: pedump.c:621
struct _DROPFILES * LPDROPFILES
#define REFIID
Definition: guiddef.h:118
#define MK_SHIFT
Definition: winuser.h:2344
#define D_LINK
#define MF_BYCOMMAND
Definition: winuser.h:202
VOID WINAPI CoTaskMemFree(LPVOID ptr)
Definition: ifs.c:442
#define IDM_LINKHERE
Definition: shresdef.h:816
long y
Definition: polytest.cpp:48
HRESULT CFSDropTarget_CreateInstance(LPWSTR sPathTarget, REFIID riid, LPVOID *ppvOut)
virtual HRESULT STDMETHODCALLTYPE GetSite(REFIID riid, void **ppvSite)
#define CFSTR_SHELLIDLIST
Definition: shlobj.h:477
CComPtr< IUnknown > m_site
Definition: CFSDropTarget.h:38
HRESULT hr
Definition: shlfolder.c:183
static HMENU hmenu
Definition: win.c:66
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
long x
Definition: polytest.cpp:48
#define InitFormatEtc(fe, cf, med)
Definition: editor.h:32
void WINAPI ReleaseStgMedium(STGMEDIUM *pmedium)
Definition: ole2.c:2033
#define TRUE
Definition: types.h:120
#define pt(x, y)
Definition: drawing.c:79
#define TPM_LEFTALIGN
Definition: winuser.h:2352
WINE_DEFAULT_DEBUG_CHANNEL(shell)
REFIID riid
Definition: precomp.h:44
UINT WINAPI RegisterClipboardFormatW(_In_ LPCWSTR)
#define FO_COPY
Definition: shellapi.h:134
#define TPM_RETURNCMD
Definition: winuser.h:2362
HRESULT WINAPI StrRetToBufW(LPSTRRET src, const ITEMIDLIST *pidl, LPWSTR dest, UINT len)
Definition: string.c:1522
WCHAR wszName[1]
Definition: shlfolder.c:1555
ITEMID_CHILD UNALIGNED * PUITEMID_CHILD
Definition: shtypes.idl:68
const ITEMIDLIST UNALIGNED * LPCITEMIDLIST
Definition: shtypes.idl:42
const char * fmt
Definition: wsprintf.c:30
HRESULT WINAPI CoGetInterfaceAndReleaseStream(LPSTREAM pStm, REFIID riid, LPVOID *ppv)
Definition: marshal.c:2144
HRESULT _CopyItems(IShellFolder *pSFFrom, UINT cidl, LPCITEMIDLIST *apidl, BOOL bCopy)
LPWSTR pOleStr
Definition: shtypes.idl:96
#define FOF_ALLOWUNDO
Definition: shellapi.h:144
HRESULT GetData([in, unique] FORMATETC *pformatetcIn, [out] STGMEDIUM *pmedium)
#define ZeroMemory
Definition: winbase.h:1648
const GUID IID_IDataObject
#define SID_IFolderView
#define IID_PPV_ARG(Itype, ppType)
#define E_FAIL
Definition: ddrawi.h:102
HRESULT WINAPI IUnknown_GetWindow(IUnknown *lpUnknown, HWND *lphWnd)
Definition: ordinal.c:1329
virtual HRESULT WINAPI DragOver(DWORD dwKeyState, POINTL pt, DWORD *pdwEffect)
BOOL WINAPI DestroyWindow(_In_ HWND)
int WINAPI LoadStringW(_In_opt_ HINSTANCE hInstance, _In_ UINT uID, _Out_writes_to_(cchBufferMax, return+1) LPWSTR lpBuffer, _In_ int cchBufferMax)
int WINAPI SHFileOperationW(LPSHFILEOPSTRUCTW lpFileOp)
Definition: shlfileop.cpp:1918
HRESULT WINAPI IUnknown_QueryService(IUnknown *, REFGUID, REFIID, LPVOID *)
Definition: ordinal.c:1494
LPITEMIDLIST * _ILCopyCidaToaPidl(LPITEMIDLIST *pidl, const CIDA *cida)
Definition: pidl.c:2673
static DWORD WINAPI _DoDropThreadProc(LPVOID lpParameter)
const DWORD DROPEFFECT_COPY
Definition: oleidl.idl:930
#define FO_MOVE
Definition: shellapi.h:133
HRESULT GetDisplayNameOf([in] PCUITEMID_CHILD pidl, [in] SHGDNF uFlags, [out] STRRET *lpName)
#define IDM_DRAGFILE
Definition: shresdef.h:813
const DWORD DROPEFFECT_NONE
Definition: oleidl.idl:929
#define TPM_RIGHTBUTTON
Definition: winuser.h:2355
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
#define FALSE
Definition: types.h:117
#define WC_STATIC
Definition: commctrl.h:4678
unsigned int BOOL
Definition: ntddk_ex.h:94
virtual HRESULT STDMETHODCALLTYPE SetSite(IUnknown *pUnkSite)
#define debugstr_w
Definition: kernel32.h:32
#define SS_LEFT
Definition: pedump.c:692
#define CreateWindowEx
Definition: winuser.h:5730
#define S_FALSE
Definition: winerror.h:2357
#define E_INVALIDARG
Definition: ddrawi.h:101
HRESULT SH_GetApidlFromDataObject(IDataObject *pDataObject, PIDLIST_ABSOLUTE *ppidlfolder, PUITEMID_CHILD **apidlItems, UINT *pcidl)
Definition: shlfolder.cpp:327
smooth NULL
Definition: ftsmooth.c:416
#define KeyStateToDropEffect(kst)
Definition: shell32_main.h:95
#define CF_HDROP
Definition: constants.h:410
LPWSTR WINAPI PathFindFileNameW(LPCWSTR lpszPath)
Definition: path.c:389
HRESULT _GetEffectFromMenu(IDataObject *pDataObject, POINTL pt, DWORD *pdwEffect, DWORD dwAvailableEffects)
BOOL WINAPI PathFileExistsW(LPCWSTR lpszPath)
Definition: path.c:1756
static HMENU hpopupmenu
Definition: msg.c:17314
LPWSTR WINAPI PathFindExtensionW(LPCWSTR lpszPath)
Definition: path.c:442
#define MK_RBUTTON
Definition: winuser.h:2343
BOOL _ILIsDesktop(LPCITEMIDLIST pidl)
Definition: CBandSite.h:24
UINT m_cfShellIDList
Definition: CFSDropTarget.h:32
#define D_COPY
#define TRACE(s)
Definition: solgame.cpp:4
HRESULT WINAPI SHGetDesktopFolder(IShellFolder **psf)
#define WS_OVERLAPPED
Definition: pedump.c:615
#define GetProcessHeap()
Definition: compat.h:595
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
#define D_MOVE
__wchar_t WCHAR
Definition: xmlstorage.h:180
LONG HRESULT
Definition: typedefs.h:79
BOOL _QueryDrop(DWORD dwKeyState, LPDWORD pdwEffect)
BOOL WINAPI DeleteMenu(_In_ HMENU, _In_ UINT, _In_ UINT)
#define _countof(array)
Definition: sndvol32.h:68
#define FAILED_UNEXPECTEDLY(hr)
Definition: shellutils.h:71
#define MAX_PATH
Definition: compat.h:34
#define swprintf(buf, format,...)
Definition: sprintf.c:56
virtual HRESULT WINAPI DragLeave()
#define WINAPI
Definition: msvc.h:6
const DWORD DROPEFFECT_LINK
Definition: oleidl.idl:932
struct CIDA * LPIDA
UINT cidl
Definition: shlobj.h:499
unsigned long DWORD
Definition: ntddk_ex.h:95
UINT op
Definition: effect.c:224
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
#define TPM_NONOTIFY
Definition: winuser.h:2361
ULONG AddRef()
#define IDM_COPYHERE
Definition: shresdef.h:814
HRESULT _RepositionItems(IShellFolderView *psfv, IDataObject *pDataObject, POINTL pt)
#define wcsicmp
Definition: compat.h:15
HRESULT _DoDrop(IDataObject *pDataObject, DWORD dwKeyState, POINTL pt, DWORD *pdwEffect)
EXTERN_C void WINAPI SHChangeNotify(LONG wEventId, UINT uFlags, LPCVOID dwItem1, LPCVOID dwItem2)
_CRTIMP wchar_t *__cdecl wcscpy(_Out_writes_z_(_String_length_(_Source)+1) wchar_t *_Dest, _In_z_ const wchar_t *_Source)
static const WCHAR L[]
Definition: oid.c:1250
LPVOID NTAPI GlobalLock(HGLOBAL hMem)
Definition: heapmem.c:755
DWORD m_dwDefaultEffect
Definition: CFSDropTarget.h:37
LPVOID lpParameter
Definition: kernel32.h:241
#define GetFullPathName
Definition: winbase.h:3661
HMENU WINAPI GetSubMenu(_In_ HMENU, _In_ int)
BOOL _GetUniqueFileName(LPWSTR pwszBasePath, LPCWSTR pwszExt, LPWSTR pwszTarget, BOOL bShortcut)
#define IDS_LNK_FILE
Definition: shresdef.h:166
DWORD dwKeyState
Definition: CFSDropTarget.h:77
void _ILFreeaPidl(LPITEMIDLIST *apidl, UINT cidl)
Definition: pidl.c:2635
#define SHCNF_PATHW
Definition: shlobj.h:1764
HRESULT Initialize(LPWSTR PathTarget)
#define IDM_MOVEHERE
Definition: shresdef.h:815
#define ERR(fmt,...)
Definition: debug.h:110
HRESULT WINAPI CoMarshalInterThreadInterfaceInStream(REFIID riid, LPUNKNOWN pUnk, LPSTREAM *ppStm)
Definition: marshal.c:2100
#define S_OK
Definition: intsafe.h:51
#define shell32_hInstance
#define WS_BORDER
Definition: pedump.c:625
static WCHAR * BuildPathsList(LPCWSTR wszBasePath, int cidl, LPCITEMIDLIST *pidls)
FileStructW * _ILGetFileStructW(LPCITEMIDLIST pidl)
Definition: pidl.c:2350
const DWORD DROPEFFECT_MOVE
Definition: oleidl.idl:931
void shell(int argc, const char *argv[])
Definition: cmds.c:1231
void WINAPI DECLSPEC_HOTPATCH CoUninitialize(void)
Definition: compobj.c:2067
HRESULT QueryGetData([in, unique] FORMATETC *pformatetc)
virtual HRESULT WINAPI DragEnter(IDataObject *pDataObject, DWORD dwKeyState, POINTL pt, DWORD *pdwEffect)
unsigned int UINT
Definition: ndis.h:50
#define MK_CONTROL
Definition: winuser.h:2345
BOOL WINAPI SetMenuDefaultItem(_In_ HMENU, _In_ UINT, _In_ UINT)
#define E_UNEXPECTED
Definition: winerror.h:2456
HRESULT QueryInterface([in] REFIID riid, [out, iid_is(riid)] void **ppvObject)
void WINAPI SHFree(LPVOID pv)
Definition: shellole.c:331
HRESULT WINAPI CoInitialize(LPVOID lpReserved)
Definition: compobj.c:1964
GLuint res
Definition: glext.h:9613
#define TPM_LEFTBUTTON
Definition: winuser.h:2354
uint32_t * LPDWORD
Definition: typedefs.h:59
HMENU WINAPI LoadMenuW(_In_opt_ HINSTANCE, _In_ LPCWSTR)
DWORD m_grfKeyState
Definition: CFSDropTarget.h:36
#define MAKEINTRESOURCEW(i)
Definition: winuser.h:582
#define SHCNE_CREATE
Definition: shlobj.h:1730
WCHAR * LPWSTR
Definition: xmlstorage.h:184
LPWSTR WINAPI PathCombineW(LPWSTR lpszDest, LPCWSTR lpszDir, LPCWSTR lpszFile)
Definition: path.c:189
BOOL WINAPI SHCreateThread(LPTHREAD_START_ROUTINE pfnThreadProc, VOID *pData, DWORD dwFlags, LPTHREAD_START_ROUTINE pfnCallback)
Definition: thread.c:356
ITEMIDLIST UNALIGNED * LPITEMIDLIST
Definition: shtypes.idl:41
UINT WINAPI DragQueryFileW(HDROP hDrop, UINT lFile, LPWSTR lpszwFile, UINT lLength)
Definition: shellole.c:627
static const CLSID *static CLSID *static const GUID VARIANT VARIANT *static IServiceProvider DWORD *static HMENU
Definition: ordinal.c:60
#define FOF_NOCONFIRMMKDIR
Definition: shellapi.h:147
BOOL WINAPI TrackPopupMenu(_In_ HMENU, _In_ UINT, _In_ int, _In_ int, _Reserved_ int, _In_ HWND, _Reserved_ LPCRECT)
Definition: dsound.c:943
LPVOID WINAPI SHAlloc(SIZE_T len)
Definition: shellole.c:309
size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
#define HeapFree(x, y, z)
Definition: compat.h:594
#define SUCCEEDED(hr)
Definition: intsafe.h:49
Definition: shlobj.h:498