ReactOS  0.4.15-dev-1200-gc3b3fcd
CDefaultContextMenu.cpp
Go to the documentation of this file.
1 /*
2  * PROJECT: shell32
3  * LICENSE: GPL - See COPYING in the top level directory
4  * FILE: dll/win32/shell32/shv_item_new.c
5  * PURPOSE: provides default context menu implementation
6  * PROGRAMMERS: Johannes Anderwald (johannes.anderwald@reactos.org)
7  */
8 
9 #include "precomp.h"
10 
12 
13 typedef struct _DynamicShellEntry_
14 {
21 
22 typedef struct _StaticShellEntry_
23 {
28 
29 
30 //
31 // verbs for InvokeCommandInfo
32 //
34 {
38 {
39  { "RunAs", 0 }, // Unimplemented
40  { "Print", 0 }, // Unimplemented
41  { "Preview", 0 }, // Unimplemented
42  { "Open", FCIDM_SHVIEW_OPEN },
43  { CMDSTR_NEWFOLDERA, FCIDM_SHVIEW_NEWFOLDER },
44  { "cut", FCIDM_SHVIEW_CUT},
45  { "copy", FCIDM_SHVIEW_COPY},
46  { "paste", FCIDM_SHVIEW_INSERT},
47  { "link", FCIDM_SHVIEW_CREATELINK},
48  { "delete", FCIDM_SHVIEW_DELETE},
49  { "properties", FCIDM_SHVIEW_PROPERTIES},
50  { "rename", FCIDM_SHVIEW_RENAME},
51  { "copyto", FCIDM_SHVIEW_COPYTO },
52  { "moveto", FCIDM_SHVIEW_MOVETO },
53 };
54 
56  public CComObjectRootEx<CComMultiThreadModelNoCS>,
57  public IContextMenu3,
58  public IObjectWithSite
59 {
60  private:
72  PDynamicShellEntry m_pDynamicEntries; /* first dynamic shell extension entry */
73  UINT m_iIdSHEFirst; /* first used id */
74  UINT m_iIdSHELast; /* last used id */
75  PStaticShellEntry m_pStaticEntries; /* first static shell extension entry */
76  UINT m_iIdSCMFirst; /* first static used id */
77  UINT m_iIdSCMLast; /* last static used id */
78  UINT m_iIdCBFirst; /* first callback used id */
79  UINT m_iIdCBLast; /* last callback used id */
80  UINT m_iIdDfltFirst; /* first default part id */
81  UINT m_iIdDfltLast; /* last default part id */
82 
84  void AddStaticEntry(const HKEY hkeyClass, const WCHAR *szVerb);
85  void AddStaticEntriesForKey(HKEY hKey);
87  HRESULT LoadDynamicContextMenuHandler(HKEY hKey, const CLSID *pclsid);
89  UINT AddShellExtensionsToMenu(HMENU hMenu, UINT* pIndexMenu, UINT idCmdFirst, UINT idCmdLast);
90  UINT AddStaticContextMenusToMenu(HMENU hMenu, UINT* IndexMenu, UINT iIdCmdFirst, UINT iIdCmdLast);
107  BOOL MapVerbToCmdId(PVOID Verb, PUINT idCmd, BOOL IsUnicode);
108 
109  public:
113 
114  // IContextMenu
115  virtual HRESULT WINAPI QueryContextMenu(HMENU hMenu, UINT indexMenu, UINT idCmdFirst, UINT idCmdLast, UINT uFlags);
117  virtual HRESULT WINAPI GetCommandString(UINT_PTR idCommand, UINT uFlags, UINT *lpReserved, LPSTR lpszName, UINT uMaxNameLen);
118 
119  // IContextMenu2
121 
122  // IContextMenu3
123  virtual HRESULT WINAPI HandleMenuMsg2(UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT *plResult);
124 
125  // IObjectWithSite
126  virtual HRESULT STDMETHODCALLTYPE SetSite(IUnknown *pUnkSite);
127  virtual HRESULT STDMETHODCALLTYPE GetSite(REFIID riid, void **ppvSite);
128 
130  COM_INTERFACE_ENTRY_IID(IID_IContextMenu, IContextMenu)
131  COM_INTERFACE_ENTRY_IID(IID_IContextMenu2, IContextMenu2)
132  COM_INTERFACE_ENTRY_IID(IID_IContextMenu3, IContextMenu3)
134  END_COM_MAP()
135 };
136 
138  m_psf(NULL),
139  m_pmcb(NULL),
140  m_pfnmcb(NULL),
141  m_cidl(0),
142  m_apidl(NULL),
143  m_pDataObj(NULL),
144  m_aKeys(NULL),
145  m_cKeys(NULL),
146  m_pidlFolder(NULL),
147  m_bGroupPolicyActive(0),
148  m_pDynamicEntries(NULL),
149  m_iIdSHEFirst(0),
150  m_iIdSHELast(0),
151  m_pStaticEntries(NULL),
152  m_iIdSCMFirst(0),
153  m_iIdSCMLast(0),
154  m_iIdCBFirst(0),
155  m_iIdCBLast(0),
156  m_iIdDfltFirst(0),
157  m_iIdDfltLast(0)
158 
159 {
160 }
161 
163 {
164  /* Free dynamic shell extension entries */
165  PDynamicShellEntry pDynamicEntry = m_pDynamicEntries, pNextDynamic;
166  while (pDynamicEntry)
167  {
168  pNextDynamic = pDynamicEntry->pNext;
169  pDynamicEntry->pCM->Release();
170  HeapFree(GetProcessHeap(), 0, pDynamicEntry);
171  pDynamicEntry = pNextDynamic;
172  }
173 
174  /* Free static shell extension entries */
175  PStaticShellEntry pStaticEntry = m_pStaticEntries, pNextStatic;
176  while (pStaticEntry)
177  {
178  pNextStatic = pStaticEntry->pNext;
179  HeapFree(GetProcessHeap(), 0, pStaticEntry->szVerb);
180  HeapFree(GetProcessHeap(), 0, pStaticEntry);
181  pStaticEntry = pNextStatic;
182  }
183 
184  for (UINT i = 0; i < m_cKeys; i++)
187 
188  if (m_pidlFolder)
190  _ILFreeaPidl(const_cast<PITEMID_CHILD *>(m_apidl), m_cidl);
191 }
192 
194 {
195  TRACE("cidl %u\n", pdcm->cidl);
196 
197  if (!pdcm->pcmcb && !lpfn)
198  {
199  ERR("CDefaultContextMenu needs a callback!\n");
200  return E_INVALIDARG;
201  }
202 
203  m_cidl = pdcm->cidl;
204  m_apidl = const_cast<PCUITEMID_CHILD_ARRAY>(_ILCopyaPidl(pdcm->apidl, m_cidl));
205  if (m_cidl && !m_apidl)
206  return E_OUTOFMEMORY;
207  m_psf = pdcm->psf;
208  m_pmcb = pdcm->pcmcb;
209  m_pfnmcb = lpfn;
210 
211  m_cKeys = pdcm->cKeys;
212  if (pdcm->cKeys)
213  {
214  m_aKeys = (HKEY*)HeapAlloc(GetProcessHeap(), 0, sizeof(HKEY) * pdcm->cKeys);
215  if (!m_aKeys)
216  return E_OUTOFMEMORY;
217  memcpy(m_aKeys, pdcm->aKeys, sizeof(HKEY) * pdcm->cKeys);
218  }
219 
220  m_psf->GetUIObjectOf(pdcm->hwnd, m_cidl, m_apidl, IID_NULL_PPV_ARG(IDataObject, &m_pDataObj));
221 
222  if (pdcm->pidlFolder)
223  {
225  }
226  else
227  {
229  if (SUCCEEDED(m_psf->QueryInterface(IID_PPV_ARG(IPersistFolder2, &pf))))
230  {
231  if (FAILED(pf->GetCurFolder(&m_pidlFolder)))
232  ERR("GetCurFolder failed\n");
233  }
234  TRACE("pidlFolder %p\n", m_pidlFolder);
235  }
236 
237  return S_OK;
238 }
239 
241 {
242  if (m_pmcb)
243  {
244  return m_pmcb->CallBack(m_psf, NULL, m_pDataObj, uMsg, wParam, (LPARAM)lParam);
245  }
246  else if(m_pfnmcb)
247  {
248  return m_pfnmcb(m_psf, NULL, m_pDataObj, uMsg, wParam, (LPARAM)lParam);
249  }
250 
251  return E_FAIL;
252 }
253 
254 void CDefaultContextMenu::AddStaticEntry(const HKEY hkeyClass, const WCHAR *szVerb)
255 {
256  PStaticShellEntry pEntry = m_pStaticEntries, pLastEntry = NULL;
257  while(pEntry)
258  {
259  if (!wcsicmp(pEntry->szVerb, szVerb))
260  {
261  /* entry already exists */
262  return;
263  }
264  pLastEntry = pEntry;
265  pEntry = pEntry->pNext;
266  }
267 
268  TRACE("adding verb %s\n", debugstr_w(szVerb));
269 
270  pEntry = (StaticShellEntry *)HeapAlloc(GetProcessHeap(), 0, sizeof(StaticShellEntry));
271  if (pEntry)
272  {
273  pEntry->pNext = NULL;
274  pEntry->szVerb = (LPWSTR)HeapAlloc(GetProcessHeap(), 0, (wcslen(szVerb) + 1) * sizeof(WCHAR));
275  if (pEntry->szVerb)
276  wcscpy(pEntry->szVerb, szVerb);
277  pEntry->hkClass = hkeyClass;
278  }
279 
280  if (!wcsicmp(szVerb, L"open"))
281  {
282  /* open verb is always inserted in front */
283  pEntry->pNext = m_pStaticEntries;
284  m_pStaticEntries = pEntry;
285  }
286  else if (pLastEntry)
287  pLastEntry->pNext = pEntry;
288  else
289  m_pStaticEntries = pEntry;
290 }
291 
293 {
294  WCHAR wszName[40];
295  DWORD cchName, dwIndex = 0;
296  HKEY hShellKey;
297 
298  LRESULT lres = RegOpenKeyExW(hKey, L"shell", 0, KEY_READ, &hShellKey);
299  if (lres != STATUS_SUCCESS)
300  return;
301 
302  while(TRUE)
303  {
304  cchName = _countof(wszName);
305  if (RegEnumKeyExW(hShellKey, dwIndex++, wszName, &cchName, NULL, NULL, NULL, NULL) != ERROR_SUCCESS)
306  break;
307 
308  AddStaticEntry(hKey, wszName);
309  }
310 
311  RegCloseKey(hShellKey);
312 }
313 
314 static
315 BOOL
317 {
318  BOOL bRet = FALSE;
319  CComPtr<IDataObject> pDataObj;
320 
321  if (SUCCEEDED(OleGetClipboard(&pDataObj)))
322  {
323  FORMATETC formatetc;
324 
325  TRACE("pDataObj=%p\n", pDataObj.p);
326 
327  /* Set the FORMATETC structure*/
328  InitFormatEtc(formatetc, RegisterClipboardFormatW(CFSTR_SHELLIDLIST), TYMED_HGLOBAL);
329  bRet = SUCCEEDED(pDataObj->QueryGetData(&formatetc));
330  }
331 
332  return bRet;
333 }
334 
335 BOOL
337 {
339 
340  while (pEntry)
341  {
342  if (!memcmp(&pEntry->ClassID, pclsid, sizeof(CLSID)))
343  return TRUE;
344  pEntry = pEntry->pNext;
345  }
346 
347  return FALSE;
348 }
349 
350 HRESULT
352 {
353  HRESULT hr;
354 
355  TRACE("LoadDynamicContextMenuHandler entered with This %p hKey %p pclsid %s\n", this, hKey, wine_dbgstr_guid(pclsid));
356 
357  if (IsShellExtensionAlreadyLoaded(pclsid))
358  return S_OK;
359 
362  if (FAILED(hr))
363  {
364  ERR("SHCoCreateInstance(IContextMenu) failed.clsid %s hr 0x%x\n", wine_dbgstr_guid(pclsid), hr);
365  return hr;
366  }
367 
368  CComPtr<IShellExtInit> pExtInit;
369  hr = pcm->QueryInterface(IID_PPV_ARG(IShellExtInit, &pExtInit));
370  if (FAILED(hr))
371  {
372  ERR("IContextMenu->QueryInterface(IShellExtInit) failed.clsid %s hr 0x%x\n", wine_dbgstr_guid(pclsid), hr);
373  return hr;
374  }
375 
376  hr = pExtInit->Initialize(m_pidlFolder, m_pDataObj, hKey);
377  if (FAILED(hr))
378  {
379  WARN("IShellExtInit::Initialize failed.clsid %s hr 0x%x\n", wine_dbgstr_guid(pclsid), hr);
380  return hr;
381  }
382 
383  if (m_site)
384  IUnknown_SetSite(pcm, m_site);
385 
387  if (!pEntry)
388  return E_OUTOFMEMORY;
389 
390  pEntry->iIdCmdFirst = 0;
391  pEntry->pNext = NULL;
392  pEntry->NumIds = 0;
393  pEntry->pCM = pcm.Detach();
394  memcpy(&pEntry->ClassID, pclsid, sizeof(CLSID));
395 
396  if (m_pDynamicEntries)
397  {
399 
400  while (pLastEntry->pNext)
401  pLastEntry = pLastEntry->pNext;
402 
403  pLastEntry->pNext = pEntry;
404  }
405  else
406  m_pDynamicEntries = pEntry;
407 
408  return S_OK;
409 }
410 
411 BOOL
413 {
414  WCHAR wszName[MAX_PATH], wszBuf[MAX_PATH], *pwszClsid;
415  DWORD cchName;
416  HRESULT hr;
417  HKEY hKey;
418 
419  if (RegOpenKeyExW(hRootKey, L"shellex\\ContextMenuHandlers", 0, KEY_READ, &hKey) != ERROR_SUCCESS)
420  {
421  TRACE("RegOpenKeyExW failed\n");
422  return FALSE;
423  }
424 
425  DWORD dwIndex = 0;
426  while (TRUE)
427  {
428  cchName = _countof(wszName);
429  if (RegEnumKeyExW(hKey, dwIndex++, wszName, &cchName, NULL, NULL, NULL, NULL) != ERROR_SUCCESS)
430  break;
431 
432  /* Key name or key value is CLSID */
433  CLSID clsid;
434  hr = CLSIDFromString(wszName, &clsid);
435  if (hr == S_OK)
436  pwszClsid = wszName;
437  else
438  {
439  DWORD cchBuf = _countof(wszBuf);
440  if (RegGetValueW(hKey, wszName, NULL, RRF_RT_REG_SZ, NULL, wszBuf, &cchBuf) == ERROR_SUCCESS)
441  hr = CLSIDFromString(wszBuf, &clsid);
442  pwszClsid = wszBuf;
443  }
444 
445  if (FAILED(hr))
446  {
447  ERR("CLSIDFromString failed for clsid %S hr 0x%x\n", pwszClsid, hr);
448  continue;
449  }
450 
452  {
454  L"Software\\Microsoft\\Windows\\CurrentVersion\\Shell Extensions\\Approved",
455  pwszClsid,
457  NULL,
458  NULL,
459  NULL) != ERROR_SUCCESS)
460  {
461  ERR("Shell extension %s not approved!\n", pwszClsid);
462  continue;
463  }
464  }
465 
467  if (FAILED(hr))
468  WARN("Failed to get context menu entires from shell extension! clsid: %S\n", pwszClsid);
469  }
470 
471  RegCloseKey(hKey);
472  return TRUE;
473 }
474 
475 UINT
476 CDefaultContextMenu::AddShellExtensionsToMenu(HMENU hMenu, UINT* pIndexMenu, UINT idCmdFirst, UINT idCmdLast)
477 {
478  UINT cIds = 0;
479 
480  if (!m_pDynamicEntries)
481  return cIds;
482 
484  do
485  {
486  HRESULT hr = pEntry->pCM->QueryContextMenu(hMenu, *pIndexMenu, idCmdFirst + cIds, idCmdLast, CMF_NORMAL);
487  if (SUCCEEDED(hr))
488  {
489  pEntry->iIdCmdFirst = cIds;
490  pEntry->NumIds = LOWORD(hr);
491  (*pIndexMenu) += pEntry->NumIds;
492 
493  cIds += pEntry->NumIds;
494  if(idCmdFirst + cIds >= idCmdLast)
495  break;
496  }
497  TRACE("pEntry %p hr %x contextmenu %p cmdfirst %x num ids %x\n", pEntry, hr, pEntry->pCM, pEntry->iIdCmdFirst, pEntry->NumIds);
498  pEntry = pEntry->pNext;
499  } while (pEntry);
500 
501  return cIds;
502 }
503 
504 UINT
506  HMENU hMenu,
507  UINT* pIndexMenu,
508  UINT iIdCmdFirst,
509  UINT iIdCmdLast)
510 {
511  MENUITEMINFOW mii;
512  UINT idResource;
513  WCHAR wszVerb[40];
514  UINT fState;
515  UINT cIds = 0;
516 
517  mii.cbSize = sizeof(mii);
519  mii.fType = MFT_STRING;
520  mii.dwTypeData = NULL;
521 
523 
524  while (pEntry)
525  {
526  fState = MFS_ENABLED;
527  mii.dwTypeData = NULL;
528 
529  /* set first entry as default */
530  if (pEntry == m_pStaticEntries)
531  fState |= MFS_DEFAULT;
532 
533  if (!wcsicmp(pEntry->szVerb, L"open"))
534  {
535  /* override default when open verb is found */
536  fState |= MFS_DEFAULT;
537  idResource = IDS_OPEN_VERB;
538  }
539  else if (!wcsicmp(pEntry->szVerb, L"explore"))
540  idResource = IDS_EXPLORE_VERB;
541  else if (!wcsicmp(pEntry->szVerb, L"runas"))
542  idResource = IDS_RUNAS_VERB;
543  else if (!wcsicmp(pEntry->szVerb, L"edit"))
544  idResource = IDS_EDIT_VERB;
545  else if (!wcsicmp(pEntry->szVerb, L"find"))
546  idResource = IDS_FIND_VERB;
547  else if (!wcsicmp(pEntry->szVerb, L"print"))
548  idResource = IDS_PRINT_VERB;
549  else if (!wcsicmp(pEntry->szVerb, L"printto"))
550  {
551  pEntry = pEntry->pNext;
552  continue;
553  }
554  else
555  idResource = 0;
556 
557  /* By default use verb for menu item name */
558  mii.dwTypeData = pEntry->szVerb;
559 
560  WCHAR wszKey[256];
561  HRESULT hr;
562  hr = StringCbPrintfW(wszKey, sizeof(wszKey), L"shell\\%s", pEntry->szVerb);
563  if (FAILED_UNEXPECTEDLY(hr))
564  {
565  pEntry = pEntry->pNext;
566  continue;
567  }
568 
569  BOOL Extended = FALSE;
570  HKEY hkVerb;
571  if (idResource > 0)
572  {
573  if (LoadStringW(shell32_hInstance, idResource, wszVerb, _countof(wszVerb)))
574  mii.dwTypeData = wszVerb; /* use translated verb */
575  else
576  ERR("Failed to load string\n");
577 
578  LONG res = RegOpenKeyW(pEntry->hkClass, wszKey, &hkVerb);
579  if (res == ERROR_SUCCESS)
580  {
581  res = RegQueryValueExW(hkVerb, L"Extended", NULL, NULL, NULL, NULL);
582  Extended = (res == ERROR_SUCCESS);
583 
584  RegCloseKey(hkVerb);
585  }
586  }
587  else
588  {
589  LONG res = RegOpenKeyW(pEntry->hkClass, wszKey, &hkVerb);
590  if (res == ERROR_SUCCESS)
591  {
592  DWORD cbVerb = sizeof(wszVerb);
593  res = RegLoadMUIStringW(hkVerb, NULL, wszVerb, cbVerb, NULL, 0, NULL);
594  if (res == ERROR_SUCCESS)
595  {
596  /* use description for the menu entry */
597  mii.dwTypeData = wszVerb;
598  }
599 
600  res = RegQueryValueExW(hkVerb, L"Extended", NULL, NULL, NULL, NULL);
601  Extended = (res == ERROR_SUCCESS);
602 
603  RegCloseKey(hkVerb);
604  }
605  }
606 
607  if (!Extended || GetAsyncKeyState(VK_SHIFT) < 0)
608  {
609  mii.cch = wcslen(mii.dwTypeData);
610  mii.fState = fState;
611  mii.wID = iIdCmdFirst + cIds;
612  InsertMenuItemW(hMenu, *pIndexMenu, TRUE, &mii);
613  (*pIndexMenu)++;
614  cIds++;
615  }
616 
617  pEntry = pEntry->pNext;
618 
619  if (mii.wID >= iIdCmdLast)
620  break;
621  }
622 
623  return cIds;
624 }
625 
627  HMENU hMenu,
628  UINT indexMenu,
629  BOOL fByPosition,
630  UINT wID,
631  UINT fType,
632  LPCWSTR dwTypeData,
633  UINT fState)
634 {
635  MENUITEMINFOW mii;
636  WCHAR wszText[100];
637 
638  ZeroMemory(&mii, sizeof(mii));
639  mii.cbSize = sizeof(mii);
640  if (fType == MFT_SEPARATOR)
641  mii.fMask = MIIM_ID | MIIM_TYPE;
642  else if (fType == MFT_STRING)
643  {
644  mii.fMask = MIIM_ID | MIIM_TYPE | MIIM_STATE;
645  if ((ULONG_PTR)HIWORD((ULONG_PTR)dwTypeData) == 0)
646  {
647  if (LoadStringW(shell32_hInstance, LOWORD((ULONG_PTR)dwTypeData), wszText, _countof(wszText)))
648  mii.dwTypeData = wszText;
649  else
650  {
651  ERR("failed to load string %p\n", dwTypeData);
652  return;
653  }
654  }
655  else
656  mii.dwTypeData = (LPWSTR)dwTypeData;
657  mii.fState = fState;
658  }
659 
660  mii.wID = wID;
661  mii.fType = fType;
662  InsertMenuItemW(hMenu, indexMenu, fByPosition, &mii);
663 }
664 
665 HRESULT
666 WINAPI
668  HMENU hMenu,
669  UINT IndexMenu,
670  UINT idCmdFirst,
671  UINT idCmdLast,
672  UINT uFlags)
673 {
674  HRESULT hr;
675  UINT idCmdNext = idCmdFirst;
676  UINT cIds = 0;
677 
678  TRACE("BuildShellItemContextMenu entered\n");
679 
680  /* Load static verbs and shell extensions from registry */
681  for (UINT i = 0; i < m_cKeys; i++)
682  {
685  }
686 
687  /* Add static context menu handlers */
688  cIds = AddStaticContextMenusToMenu(hMenu, &IndexMenu, idCmdFirst, idCmdLast);
689  m_iIdSCMFirst = 0;
690  m_iIdSCMLast = cIds;
691  idCmdNext = idCmdFirst + cIds;
692 
693  /* Add dynamic context menu handlers */
694  cIds += AddShellExtensionsToMenu(hMenu, &IndexMenu, idCmdNext, idCmdLast);
696  m_iIdSHELast = cIds;
697  idCmdNext = idCmdFirst + cIds;
698  TRACE("SH_LoadContextMenuHandlers first %x last %x\n", m_iIdSHEFirst, m_iIdSHELast);
699 
700  /* Now let the callback add its own items */
701  QCMINFO qcminfo = {hMenu, IndexMenu, idCmdNext, idCmdLast, NULL};
703  {
704  cIds += qcminfo.idCmdFirst;
705  IndexMenu += qcminfo.idCmdFirst;
707  m_iIdCBLast = cIds;
708  idCmdNext = idCmdFirst + cIds;
709  }
710 
711  if (uFlags & CMF_VERBSONLY)
712  return MAKE_HRESULT(SEVERITY_SUCCESS, 0, cIds);
713 
714  /* If this is a background context menu we are done */
715  if (!m_cidl)
716  return MAKE_HRESULT(SEVERITY_SUCCESS, 0, cIds);
717 
718  /* Get the attributes of the items */
719  SFGAOF rfg = SFGAO_BROWSABLE | SFGAO_CANCOPY | SFGAO_CANLINK | SFGAO_CANMOVE | SFGAO_CANDELETE | SFGAO_CANRENAME | SFGAO_HASPROPSHEET | SFGAO_FILESYSTEM | SFGAO_FOLDER;
720  hr = m_psf->GetAttributesOf(m_cidl, m_apidl, &rfg);
721  if (FAILED_UNEXPECTEDLY(hr))
722  return MAKE_HRESULT(SEVERITY_SUCCESS, 0, cIds);
723 
724  /* Add the default part of the menu */
725  HMENU hmenuDefault = LoadMenu(_AtlBaseModule.GetResourceInstance(), L"MENU_SHV_FILE");
726 
727  /* Remove uneeded entries */
728  if (!(rfg & SFGAO_CANMOVE))
729  DeleteMenu(hmenuDefault, IDM_CUT, MF_BYCOMMAND);
730  if (!(rfg & SFGAO_CANCOPY))
731  DeleteMenu(hmenuDefault, IDM_COPY, MF_BYCOMMAND);
732  if (!((rfg & SFGAO_FILESYSTEM) && HasClipboardData()))
733  DeleteMenu(hmenuDefault, IDM_INSERT, MF_BYCOMMAND);
734  if (!(rfg & SFGAO_CANLINK))
735  DeleteMenu(hmenuDefault, IDM_CREATELINK, MF_BYCOMMAND);
736  if (!(rfg & SFGAO_CANDELETE))
737  DeleteMenu(hmenuDefault, IDM_DELETE, MF_BYCOMMAND);
738  if (!(rfg & SFGAO_CANRENAME))
739  DeleteMenu(hmenuDefault, IDM_RENAME, MF_BYCOMMAND);
740  if (!(rfg & SFGAO_HASPROPSHEET))
741  DeleteMenu(hmenuDefault, IDM_PROPERTIES, MF_BYCOMMAND);
742 
743  UINT idMax = Shell_MergeMenus(hMenu, GetSubMenu(hmenuDefault, 0), IndexMenu, idCmdNext, idCmdLast, 0);
744  m_iIdDfltFirst = cIds;
745  cIds += idMax - idCmdNext;
746  m_iIdDfltLast = cIds;
747 
748  DestroyMenu(hmenuDefault);
749 
750  return MAKE_HRESULT(SEVERITY_SUCCESS, 0, cIds);
751 }
752 
754 {
755  HRESULT hr;
756 
758  hr = OleGetClipboard(&pda);
759  if (FAILED_UNEXPECTEDLY(hr))
760  return hr;
761 
762  FORMATETC formatetc2;
763  STGMEDIUM medium2;
765 
766  DWORD dwKey= 0;
767 
768  if (SUCCEEDED(pda->GetData(&formatetc2, &medium2)))
769  {
770  DWORD * pdwFlag = (DWORD*)GlobalLock(medium2.hGlobal);
771  if (pdwFlag)
772  {
773  if (*pdwFlag == DROPEFFECT_COPY)
774  dwKey = MK_CONTROL;
775  else
776  dwKey = MK_SHIFT;
777  }
778  else {
779  ERR("No drop effect obtained");
780  }
781  GlobalUnlock(medium2.hGlobal);
782  }
783 
784  if (bLink)
785  {
786  dwKey = MK_CONTROL|MK_SHIFT;
787  }
788 
789  CComPtr<IDropTarget> pdrop;
790  if (m_cidl)
791  hr = m_psf->GetUIObjectOf(NULL, 1, &m_apidl[0], IID_NULL_PPV_ARG(IDropTarget, &pdrop));
792  else
793  hr = m_psf->CreateViewObject(NULL, IID_PPV_ARG(IDropTarget, &pdrop));
794 
795  if (FAILED_UNEXPECTEDLY(hr))
796  return hr;
797 
798  SHSimulateDrop(pdrop, pda, dwKey, NULL, NULL);
799 
800  TRACE("CP result %x\n", hr);
801  return S_OK;
802 }
803 
804 HRESULT
806 {
808  return E_FAIL;
809 }
810 
812 {
813  if (!m_cidl || !m_pDataObj)
814  return E_FAIL;
815 
817  HRESULT hr = m_psf->CreateViewObject(NULL, IID_PPV_ARG(IDropTarget, &pDT));
818  if (FAILED_UNEXPECTEDLY(hr))
819  return hr;
820 
822 
823  return S_OK;
824 }
825 
827 {
828  if (!m_cidl || !m_pDataObj)
829  return E_FAIL;
830 
833  if (FAILED_UNEXPECTEDLY(hr))
834  return hr;
835 
836  SHSimulateDrop(pDT, m_pDataObj, 0, NULL, NULL);
837 
838  return S_OK;
839 }
840 
842 {
843  if (!m_cidl || !m_pDataObj)
844  return E_FAIL;
845 
846  FORMATETC formatetc;
848  STGMEDIUM medium = {0};
849  medium.tymed = TYMED_HGLOBAL;
850  medium.hGlobal = GlobalAlloc(GHND, sizeof(DWORD));
851  DWORD* pdwFlag = (DWORD*)GlobalLock(medium.hGlobal);
852  if (pdwFlag)
853  *pdwFlag = bCopy ? DROPEFFECT_COPY : DROPEFFECT_MOVE;
854  GlobalUnlock(medium.hGlobal);
855  m_pDataObj->SetData(&formatetc, &medium, TRUE);
856 
858  if (FAILED_UNEXPECTEDLY(hr))
859  return hr;
860 
861  return S_OK;
862 }
863 
865 {
867  HRESULT hr;
868 
869  if (!m_site || !m_cidl)
870  return E_FAIL;
871 
872  /* Get a pointer to the shell browser */
874  if (FAILED_UNEXPECTEDLY(hr))
875  return hr;
876 
877  CComPtr<IShellView> lpSV;
878  hr = psb->QueryActiveShellView(&lpSV);
879  if (FAILED_UNEXPECTEDLY(hr))
880  return hr;
881 
882  SVSIF selFlags = SVSI_DESELECTOTHERS | SVSI_EDIT | SVSI_ENSUREVISIBLE | SVSI_FOCUSED | SVSI_SELECT;
883  hr = lpSV->SelectItem(m_apidl[0], selFlags);
884  if (FAILED_UNEXPECTEDLY(hr))
885  return hr;
886 
887  return S_OK;
888 }
889 
890 HRESULT
892  LPCMINVOKECOMMANDINFO lpcmi)
893 {
895 
896  return S_OK;
897 }
898 
899 HRESULT
901 {
902  ERR("TODO: Undo");
903  return E_NOTIMPL;
904 }
905 
906 HRESULT
908 {
909  HRESULT hr = E_FAIL;
910  if (!m_pDataObj)
911  {
912  ERR("m_pDataObj is NULL\n");
913  return hr;
914  }
915 
916  CComPtr<IContextMenu> pContextMenu;
917  if (bCopy)
918  hr = SHCoCreateInstance(NULL, &CLSID_CopyToMenu, NULL,
919  IID_PPV_ARG(IContextMenu, &pContextMenu));
920  else
921  hr = SHCoCreateInstance(NULL, &CLSID_MoveToMenu, NULL,
922  IID_PPV_ARG(IContextMenu, &pContextMenu));
923  if (FAILED_UNEXPECTEDLY(hr))
924  return hr;
925 
927  hr = pContextMenu->QueryInterface(IID_PPV_ARG(IShellExtInit, &pInit));
928  if (FAILED_UNEXPECTEDLY(hr))
929  return hr;
930 
931  hr = pInit->Initialize(m_pidlFolder, m_pDataObj, NULL);
932  if (FAILED_UNEXPECTEDLY(hr))
933  return hr;
934 
935  if (bCopy)
936  lpici->lpVerb = "copyto";
937  else
938  lpici->lpVerb = "moveto";
939 
940  return pContextMenu->InvokeCommand(lpici);
941 }
942 
943 // This code is taken from CNewMenu and should be shared between the 2 classes
944 HRESULT
946  LPCMINVOKECOMMANDINFO lpici)
947 {
948  WCHAR wszPath[MAX_PATH];
949  WCHAR wszName[MAX_PATH];
950  WCHAR wszNewFolder[25];
951  HRESULT hr;
952 
953  /* Get folder path */
955  if (FAILED_UNEXPECTEDLY(hr))
956  return hr;
957 
958  if (!LoadStringW(shell32_hInstance, IDS_NEWFOLDER, wszNewFolder, _countof(wszNewFolder)))
959  return E_FAIL;
960 
961  /* Create the name of the new directory */
962  if (!PathYetAnotherMakeUniqueName(wszName, wszPath, NULL, wszNewFolder))
963  return E_FAIL;
964 
965  /* Create the new directory and show the appropriate dialog in case of error */
966  if (SHCreateDirectory(lpici->hwnd, wszName) != ERROR_SUCCESS)
967  return E_FAIL;
968 
969  /* Show and select the new item in the def view */
970  LPITEMIDLIST pidl;
971  PITEMID_CHILD pidlNewItem;
973 
974  /* Notify the view object about the new item */
976 
977  if (!m_site)
978  return S_OK;
979 
980  /* Get a pointer to the shell view */
982  if (FAILED_UNEXPECTEDLY(hr))
983  return S_OK;
984 
985  /* Attempt to get the pidl of the new item */
986  hr = SHILCreateFromPathW(wszName, &pidl, NULL);
987  if (FAILED_UNEXPECTEDLY(hr))
988  return hr;
989 
990  pidlNewItem = ILFindLastID(pidl);
991 
992  hr = psv->SelectItem(pidlNewItem, SVSI_DESELECTOTHERS | SVSI_EDIT | SVSI_ENSUREVISIBLE |
993  SVSI_FOCUSED | SVSI_SELECT);
994  if (FAILED_UNEXPECTEDLY(hr))
995  return hr;
996 
997  SHFree(pidl);
998 
999  return S_OK;
1000 }
1001 
1003 {
1005 
1006  while(pEntry && idCmd >= pEntry->iIdCmdFirst + pEntry->NumIds)
1007  pEntry = pEntry->pNext;
1008 
1009  if (!pEntry)
1010  return NULL;
1011 
1012  if (idCmd < pEntry->iIdCmdFirst || idCmd > pEntry->iIdCmdFirst + pEntry->NumIds)
1013  return NULL;
1014 
1015  return pEntry;
1016 }
1017 
1018 // FIXME: 260 is correct, but should this be part of the SDK or just MAX_PATH?
1019 #define MAX_VERB 260
1020 
1021 BOOL
1023 {
1024  WCHAR UnicodeStr[MAX_VERB];
1025 
1026  /* Loop through all the static verbs looking for a match */
1027  for (UINT i = 0; i < _countof(g_StaticInvokeCmdMap); i++)
1028  {
1029  /* We can match both ANSI and unicode strings */
1030  if (IsUnicode)
1031  {
1032  /* The static verbs are ANSI, get a unicode version before doing the compare */
1033  SHAnsiToUnicode(g_StaticInvokeCmdMap[i].szStringVerb, UnicodeStr, MAX_VERB);
1034  if (!wcscmp(UnicodeStr, (LPWSTR)Verb))
1035  {
1036  /* Return the Corresponding Id */
1037  *idCmd = g_StaticInvokeCmdMap[i].IntVerb;
1038  return TRUE;
1039  }
1040  }
1041  else
1042  {
1043  if (!strcmp(g_StaticInvokeCmdMap[i].szStringVerb, (LPSTR)Verb))
1044  {
1045  *idCmd = g_StaticInvokeCmdMap[i].IntVerb;
1046  return TRUE;
1047  }
1048  }
1049  }
1050 
1051  return FALSE;
1052 }
1053 
1054 HRESULT
1056  LPCMINVOKECOMMANDINFO lpcmi)
1057 {
1058  TRACE("verb %p first %x last %x\n", lpcmi->lpVerb, m_iIdSHEFirst, m_iIdSHELast);
1059 
1060  UINT idCmd = LOWORD(lpcmi->lpVerb);
1061  PDynamicShellEntry pEntry = GetDynamicEntry(idCmd);
1062  if (!pEntry)
1063  return E_FAIL;
1064 
1065  /* invoke the dynamic context menu */
1066  lpcmi->lpVerb = MAKEINTRESOURCEA(idCmd - pEntry->iIdCmdFirst);
1067  return pEntry->pCM->InvokeCommand(lpcmi);
1068 }
1069 
1070 DWORD
1072 {
1074  HWND hwndTree;
1075  LPCWSTR FlagsName;
1076  WCHAR wszKey[256];
1077  HRESULT hr;
1078  DWORD wFlags;
1079  DWORD cbVerb;
1080 
1081  if (!m_site)
1082  return 0;
1083 
1084  /* Get a pointer to the shell browser */
1086  if (FAILED_UNEXPECTEDLY(hr))
1087  return 0;
1088 
1089  /* See if we are in Explore or Browse mode. If the browser's tree is present, we are in Explore mode.*/
1090  if (SUCCEEDED(psb->GetControlWindow(FCW_TREE, &hwndTree)) && hwndTree)
1091  FlagsName = L"ExplorerFlags";
1092  else
1093  FlagsName = L"BrowserFlags";
1094 
1095  /* Try to get the flag from the verb */
1096  hr = StringCbPrintfW(wszKey, sizeof(wszKey), L"shell\\%s", pEntry->szVerb);
1097  if (FAILED_UNEXPECTEDLY(hr))
1098  return 0;
1099 
1100  cbVerb = sizeof(wFlags);
1101  if (RegGetValueW(pEntry->hkClass, wszKey, FlagsName, RRF_RT_REG_DWORD, NULL, &wFlags, &cbVerb) == ERROR_SUCCESS)
1102  {
1103  return wFlags;
1104  }
1105 
1106  return 0;
1107 }
1108 
1109 HRESULT
1112 {
1114  HRESULT hr;
1115 
1116  if (!m_site)
1117  return E_FAIL;
1118 
1119  /* Get a pointer to the shell browser */
1121  if (FAILED_UNEXPECTEDLY(hr))
1122  return 0;
1123 
1124  return psb->BrowseObject(ILCombine(m_pidlFolder, pidl), wFlags);
1125 }
1126 
1127 HRESULT
1129 {
1130  LPITEMIDLIST pidlFull = ILCombine(m_pidlFolder, pidl);
1131  if (pidlFull == NULL)
1132  {
1133  return E_FAIL;
1134  }
1135 
1136  WCHAR wszPath[MAX_PATH];
1137  BOOL bHasPath = SHGetPathFromIDListW(pidlFull, wszPath);
1138 
1139  WCHAR wszDir[MAX_PATH];
1140  if (bHasPath)
1141  {
1142  wcscpy(wszDir, wszPath);
1143  PathRemoveFileSpec(wszDir);
1144  }
1145  else
1146  {
1148  }
1149 
1150  SHELLEXECUTEINFOW sei;
1151  ZeroMemory(&sei, sizeof(sei));
1152  sei.cbSize = sizeof(sei);
1153  sei.hwnd = lpcmi->hwnd;
1154  sei.nShow = SW_SHOWNORMAL;
1155  sei.lpVerb = pEntry->szVerb;
1156  sei.lpDirectory = wszDir;
1157  sei.lpIDList = pidlFull;
1158  sei.hkeyClass = pEntry->hkClass;
1160  if (bHasPath)
1161  {
1162  sei.lpFile = wszPath;
1163  }
1164 
1165  ShellExecuteExW(&sei);
1166 
1167  ILFree(pidlFull);
1168 
1169  return S_OK;
1170 }
1171 
1172 HRESULT
1174  LPCMINVOKECOMMANDINFO lpcmi)
1175 {
1177  INT iCmd = LOWORD(lpcmi->lpVerb) - m_iIdSCMFirst;
1178  HRESULT hr;
1179  UINT i;
1180 
1181  while (pEntry && (iCmd--) > 0)
1182  pEntry = pEntry->pNext;
1183 
1184  if (iCmd > 0)
1185  return E_FAIL;
1186 
1187  /* Get the browse flags to see if we need to browse */
1188  DWORD wFlags = BrowserFlagsFromVerb(lpcmi, pEntry);
1189  BOOL bBrowsed = FALSE;
1190 
1191  for (i=0; i < m_cidl; i++)
1192  {
1193  /* Check if we need to browse */
1194  if (wFlags > 0)
1195  {
1196  /* In xp if we have browsed, we don't open any more folders.
1197  * In win7 we browse to the first folder we find and
1198  * open new windows for each of the rest of the folders */
1199  if (bBrowsed)
1200  continue;
1201 
1202  hr = TryToBrowse(lpcmi, m_apidl[i], wFlags);
1203  if (SUCCEEDED(hr))
1204  {
1205  bBrowsed = TRUE;
1206  continue;
1207  }
1208  }
1209 
1210  InvokePidl(lpcmi, m_apidl[i], pEntry);
1211  }
1212 
1213  return S_OK;
1214 }
1215 
1216 HRESULT
1217 WINAPI
1219  LPCMINVOKECOMMANDINFO lpcmi)
1220 {
1221  CMINVOKECOMMANDINFO LocalInvokeInfo;
1222  HRESULT Result;
1223  UINT CmdId;
1224 
1225  /* Take a local copy of the fixed members of the
1226  struct as we might need to modify the verb */
1227  LocalInvokeInfo = *lpcmi;
1228 
1229  /* Check if this is a string verb */
1230  if (HIWORD(LocalInvokeInfo.lpVerb))
1231  {
1232  /* Get the ID which corresponds to this verb, and update our local copy */
1233  if (MapVerbToCmdId((LPVOID)LocalInvokeInfo.lpVerb, &CmdId, FALSE))
1234  LocalInvokeInfo.lpVerb = MAKEINTRESOURCEA(CmdId);
1235  }
1236 
1237  CmdId = LOWORD(LocalInvokeInfo.lpVerb);
1238 
1239  if (m_pDynamicEntries && CmdId >= m_iIdSHEFirst && CmdId < m_iIdSHELast)
1240  {
1241  LocalInvokeInfo.lpVerb -= m_iIdSHEFirst;
1242  Result = InvokeShellExt(&LocalInvokeInfo);
1243  return Result;
1244  }
1245 
1246  if (m_pStaticEntries && CmdId >= m_iIdSCMFirst && CmdId < m_iIdSCMLast)
1247  {
1248  LocalInvokeInfo.lpVerb -= m_iIdSCMFirst;
1249  Result = InvokeRegVerb(&LocalInvokeInfo);
1250  return Result;
1251  }
1252 
1253  if (m_iIdCBFirst != m_iIdCBLast && CmdId >= m_iIdCBFirst && CmdId < m_iIdCBLast)
1254  {
1256  return Result;
1257  }
1258 
1259  if (m_iIdDfltFirst != m_iIdDfltLast && CmdId >= m_iIdDfltFirst && CmdId < m_iIdDfltLast)
1260  {
1261  CmdId -= m_iIdDfltFirst;
1262  /* See the definitions of IDM_CUT and co to see how this works */
1263  CmdId += 0x7000;
1264  }
1265 
1266  /* Check if this is a Id */
1267  switch (CmdId)
1268  {
1269  case FCIDM_SHVIEW_INSERT:
1270  Result = DoPaste(&LocalInvokeInfo, FALSE);
1271  break;
1273  Result = DoPaste(&LocalInvokeInfo, TRUE);
1274  break;
1275  case FCIDM_SHVIEW_OPEN:
1276  case FCIDM_SHVIEW_EXPLORE:
1277  Result = DoOpenOrExplore(&LocalInvokeInfo);
1278  break;
1279  case FCIDM_SHVIEW_COPY:
1280  case FCIDM_SHVIEW_CUT:
1281  Result = DoCopyOrCut(&LocalInvokeInfo, CmdId == FCIDM_SHVIEW_COPY);
1282  break;
1284  Result = DoCreateLink(&LocalInvokeInfo);
1285  break;
1286  case FCIDM_SHVIEW_DELETE:
1287  Result = DoDelete(&LocalInvokeInfo);
1288  break;
1289  case FCIDM_SHVIEW_RENAME:
1290  Result = DoRename(&LocalInvokeInfo);
1291  break;
1293  Result = DoProperties(&LocalInvokeInfo);
1294  break;
1296  Result = DoCreateNewFolder(&LocalInvokeInfo);
1297  break;
1298  case FCIDM_SHVIEW_COPYTO:
1299  Result = DoCopyToMoveToFolder(&LocalInvokeInfo, TRUE);
1300  break;
1301  case FCIDM_SHVIEW_MOVETO:
1302  Result = DoCopyToMoveToFolder(&LocalInvokeInfo, FALSE);
1303  break;
1304  case FCIDM_SHVIEW_UNDO:
1305  Result = DoUndo(&LocalInvokeInfo);
1306  break;
1307  default:
1308  Result = E_INVALIDARG;
1309  ERR("Unhandled Verb %xl\n", LOWORD(LocalInvokeInfo.lpVerb));
1310  break;
1311  }
1312 
1313  return Result;
1314 }
1315 
1316 HRESULT
1317 WINAPI
1319  UINT_PTR idCommand,
1320  UINT uFlags,
1321  UINT* lpReserved,
1322  LPSTR lpszName,
1323  UINT uMaxNameLen)
1324 {
1325  /* We don't handle the help text yet */
1326  if (uFlags == GCS_HELPTEXTA ||
1327  uFlags == GCS_HELPTEXTW ||
1328  HIWORD(idCommand) != 0)
1329  {
1330  return E_NOTIMPL;
1331  }
1332 
1333  UINT CmdId = LOWORD(idCommand);
1334 
1335  if (m_pDynamicEntries && CmdId >= m_iIdSHEFirst && CmdId < m_iIdSHELast)
1336  {
1337  idCommand -= m_iIdSHEFirst;
1338  PDynamicShellEntry pEntry = GetDynamicEntry(idCommand);
1339  if (!pEntry)
1340  return E_FAIL;
1341 
1342  idCommand -= pEntry->iIdCmdFirst;
1343  return pEntry->pCM->GetCommandString(idCommand,
1344  uFlags,
1345  lpReserved,
1346  lpszName,
1347  uMaxNameLen);
1348  }
1349 
1350  if (m_pStaticEntries && CmdId >= m_iIdSCMFirst && CmdId < m_iIdSCMLast)
1351  {
1352  /* Validation just returns S_OK on a match. The id exists. */
1353  if (uFlags == GCS_VALIDATEA || uFlags == GCS_VALIDATEW)
1354  return S_OK;
1355 
1356  CmdId -= m_iIdSCMFirst;
1357 
1359  while (pEntry && (CmdId--) > 0)
1360  pEntry = pEntry->pNext;
1361 
1362  if (!pEntry)
1363  return E_INVALIDARG;
1364 
1365  if (uFlags == GCS_VERBW)
1366  return StringCchCopyW((LPWSTR)lpszName, uMaxNameLen, pEntry->szVerb);
1367 
1368  if (uFlags == GCS_VERBA)
1369  {
1370  if (SHUnicodeToAnsi(pEntry->szVerb, lpszName, uMaxNameLen))
1371  return S_OK;
1372  }
1373 
1374  return E_INVALIDARG;
1375  }
1376 
1377  //FIXME: Should we handle callbacks here?
1378  if (m_iIdDfltFirst != m_iIdDfltLast && CmdId >= m_iIdDfltFirst && CmdId < m_iIdDfltLast)
1379  {
1380  CmdId -= m_iIdDfltFirst;
1381  /* See the definitions of IDM_CUT and co to see how this works */
1382  CmdId += 0x7000;
1383  }
1384 
1385  /* Loop looking for a matching Id */
1386  for (UINT i = 0; i < _countof(g_StaticInvokeCmdMap); i++)
1387  {
1388  if (g_StaticInvokeCmdMap[i].IntVerb == CmdId)
1389  {
1390  /* Validation just returns S_OK on a match */
1391  if (uFlags == GCS_VALIDATEA || uFlags == GCS_VALIDATEW)
1392  return S_OK;
1393 
1394  /* Return a copy of the ANSI verb */
1395  if (uFlags == GCS_VERBA)
1396  return StringCchCopyA(lpszName, uMaxNameLen, g_StaticInvokeCmdMap[i].szStringVerb);
1397 
1398  /* Convert the ANSI verb to unicode and return that */
1399  if (uFlags == GCS_VERBW)
1400  {
1401  if (SHAnsiToUnicode(g_StaticInvokeCmdMap[i].szStringVerb, (LPWSTR)lpszName, uMaxNameLen))
1402  return S_OK;
1403  }
1404  }
1405  }
1406 
1407  return E_INVALIDARG;
1408 }
1409 
1410 HRESULT
1411 WINAPI
1413  UINT uMsg,
1414  WPARAM wParam,
1415  LPARAM lParam)
1416 {
1417  /* FIXME: Should we implement this as well? */
1418  return S_OK;
1419 }
1420 
1422 {
1423  if (uMsg == WM_DRAWITEM)
1424  {
1425  DRAWITEMSTRUCT* pDrawStruct = reinterpret_cast<DRAWITEMSTRUCT*>(lParam);
1426  *CmdId = pDrawStruct->itemID;
1427  return S_OK;
1428  }
1429  else if (uMsg == WM_MEASUREITEM)
1430  {
1431  MEASUREITEMSTRUCT* pMeasureStruct = reinterpret_cast<MEASUREITEMSTRUCT*>(lParam);
1432  *CmdId = pMeasureStruct->itemID;
1433  return S_OK;
1434  }
1435 
1436  return E_FAIL;
1437 }
1438 
1440 {
1441  if (uMsg == WM_DRAWITEM)
1442  {
1443  DRAWITEMSTRUCT* pDrawStruct = reinterpret_cast<DRAWITEMSTRUCT*>(lParam);
1444  pDrawStruct->itemID = CmdId;
1445  return S_OK;
1446  }
1447  else if (uMsg == WM_MEASUREITEM)
1448  {
1449  MEASUREITEMSTRUCT* pMeasureStruct = reinterpret_cast<MEASUREITEMSTRUCT*>(lParam);
1450  pMeasureStruct->itemID = CmdId;
1451  return S_OK;
1452  }
1453 
1454  return E_FAIL;
1455 }
1456 
1457 HRESULT
1458 WINAPI
1460  UINT uMsg,
1461  WPARAM wParam,
1462  LPARAM lParam,
1463  LRESULT *plResult)
1464 {
1465  if (uMsg == WM_INITMENUPOPUP)
1466  {
1468  while (pEntry)
1469  {
1470  SHForwardContextMenuMsg(pEntry->pCM, uMsg, wParam, lParam, plResult, TRUE);
1471  pEntry = pEntry->pNext;
1472  }
1473  return S_OK;
1474  }
1475 
1476  UINT CmdId;
1477  HRESULT hr = SHGetMenuIdFromMenuMsg(uMsg, lParam, &CmdId);
1478  if (FAILED(hr))
1479  return S_FALSE;
1480 
1481  if (CmdId < m_iIdSHEFirst || CmdId >= m_iIdSHELast)
1482  return S_FALSE;
1483 
1484  CmdId -= m_iIdSHEFirst;
1485  PDynamicShellEntry pEntry = GetDynamicEntry(CmdId);
1486  if (pEntry)
1487  {
1488  SHSetMenuIdInMenuMsg(uMsg, lParam, CmdId - pEntry->iIdCmdFirst);
1489  SHForwardContextMenuMsg(pEntry->pCM, uMsg, wParam, lParam, plResult, TRUE);
1490  }
1491 
1492  return S_OK;
1493 }
1494 
1495 HRESULT
1496 WINAPI
1498 {
1499  m_site = pUnkSite;
1500  return S_OK;
1501 }
1502 
1503 HRESULT
1504 WINAPI
1506 {
1507  if (!m_site)
1508  return E_FAIL;
1509 
1510  return m_site->QueryInterface(riid, ppvSite);
1511 }
1512 
1513 static
1514 HRESULT
1516 {
1517  return ShellObjectCreatorInit<CDefaultContextMenu>(pdcm, lpfn, riid, ppv);
1518 }
1519 
1520 /*************************************************************************
1521  * SHCreateDefaultContextMenu [SHELL32.325] Vista API
1522  *
1523  */
1524 
1525 HRESULT
1526 WINAPI
1528 {
1529  HRESULT hr;
1530 
1531  if (!ppv)
1532  return E_INVALIDARG;
1533 
1535  if (FAILED_UNEXPECTEDLY(hr))
1536  return hr;
1537 
1538  return S_OK;
1539 }
1540 
1541 /*************************************************************************
1542  * CDefFolderMenu_Create2 [SHELL32.701]
1543  *
1544  */
1545 
1546 HRESULT
1547 WINAPI
1549  PCIDLIST_ABSOLUTE pidlFolder,
1550  HWND hwnd,
1551  UINT cidl,
1552  PCUITEMID_CHILD_ARRAY apidl,
1553  IShellFolder *psf,
1554  LPFNDFMCALLBACK lpfn,
1555  UINT nKeys,
1556  const HKEY *ahkeyClsKeys,
1557  IContextMenu **ppcm)
1558 {
1559  DEFCONTEXTMENU dcm;
1560  dcm.hwnd = hwnd;
1561  dcm.pcmcb = NULL;
1562  dcm.pidlFolder = pidlFolder;
1563  dcm.psf = psf;
1564  dcm.cidl = cidl;
1565  dcm.apidl = apidl;
1566  dcm.punkAssociationInfo = NULL;
1567  dcm.cKeys = nKeys;
1568  dcm.aKeys = ahkeyClsKeys;
1569 
1571  if (FAILED_UNEXPECTEDLY(hr))
1572  return hr;
1573 
1574  return S_OK;
1575 }
LSTATUS WINAPI RegGetValueW(HKEY hKey, LPCWSTR pszSubKey, LPCWSTR pszValue, DWORD dwFlags, LPDWORD pdwType, PVOID pvData, LPDWORD pcbData)
Definition: reg.c:1965
#define SHCNE_MKDIR
Definition: shlobj.h:1732
virtual HRESULT STDMETHODCALLTYPE SetSite(IUnknown *pUnkSite)
#define FCIDM_SHVIEW_UNDO
Definition: shresdef.h:770
HRESULT SHSetMenuIdInMenuMsg(UINT uMsg, LPARAM lParam, UINT CmdId)
const DOCKBAR PVOID HWND HWND * hwnd
Definition: tooldock.h:22
HRESULT WINAPI OleSetClipboard(IDataObject *data)
Definition: clipboard.c:2199
#define IDS_NEWFOLDER
#define MFT_STRING
Definition: winuser.h:741
#define REFIID
Definition: guiddef.h:118
#define SEE_MASK_CLASSKEY
Definition: shellapi.h:26
HGLOBAL NTAPI GlobalAlloc(UINT uFlags, SIZE_T dwBytes)
Definition: heapmem.c:368
HRESULT QueryContextMenu([in] HMENU hmenu, [in] UINT indexMenu, [in] UINT idCmdFirst, [in] UINT idCmdLast, [in] UINT uFlags)
void WINAPI ILFree(LPITEMIDLIST pidl)
Definition: pidl.c:925
struct _DynamicShellEntry_ * PDynamicShellEntry
#define MK_SHIFT
Definition: winuser.h:2344
#define MF_BYCOMMAND
Definition: winuser.h:202
int memcmp(void *Buffer1, void *Buffer2, ACPI_SIZE Count)
Definition: utclib.c:112
VOID WINAPI CoTaskMemFree(LPVOID ptr)
Definition: ifs.c:442
HRESULT DoUndo(LPCMINVOKECOMMANDINFO lpcmi)
#define IDS_FIND_VERB
Definition: shresdef.h:201
UINT AddStaticContextMenusToMenu(HMENU hMenu, UINT *IndexMenu, UINT iIdCmdFirst, UINT iIdCmdLast)
#define ERROR_SUCCESS
Definition: deptool.c:10
UINT WINAPI Shell_MergeMenus(HMENU hmDst, HMENU hmSrc, UINT uInsert, UINT uIDAdjust, UINT uIDAdjustMax, ULONG uFlags)
Definition: shlmenu.c:857
struct _StaticInvokeCommandMap_ g_StaticInvokeCmdMap[]
#define CFSTR_SHELLIDLIST
Definition: shlobj.h:477
#define CFSTR_PREFERREDDROPEFFECT
Definition: shlobj.h:487
HRESULT hr
Definition: shlfolder.c:183
#define IDM_RENAME
Definition: shresdef.h:808
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
const HKEY * aKeys
Definition: shlobj.h:2374
#define InitFormatEtc(fe, cf, med)
Definition: editor.h:32
#define KEY_READ
Definition: nt_native.h:1023
#define TRUE
Definition: types.h:120
#define WM_INITMENUPOPUP
Definition: winuser.h:1728
REFIID riid
Definition: precomp.h:44
UINT WINAPI RegisterClipboardFormatW(_In_ LPCWSTR)
#define PathRemoveFileSpec
Definition: shlwapi.h:1035
HRESULT DoPaste(LPCMINVOKECOMMANDINFO lpcmi, BOOL bLink)
HRESULT WINAPI SHCreateDefaultContextMenu(const DEFCONTEXTMENU *pdcm, REFIID riid, void **ppv)
#define WARN(fmt,...)
Definition: debug.h:112
LPITEMIDLIST WINAPI ILCombine(LPCITEMIDLIST pidl1, LPCITEMIDLIST pidl2)
Definition: pidl.c:699
#define FCIDM_SHVIEW_OPEN
Definition: shresdef.h:794
const ITEMIDLIST UNALIGNED * LPCITEMIDLIST
Definition: shtypes.idl:42
IContextMenuCB * pcmcb
Definition: shlobj.h:2367
BOOL WINAPI SHGetPathFromIDListW(LPCITEMIDLIST pidl, LPWSTR pszPath)
Definition: pidl.c:1294
WINE_DEFAULT_DEBUG_CHANNEL(dmenu)
virtual HRESULT STDMETHODCALLTYPE GetSite(REFIID riid, void **ppvSite)
#define FCIDM_SHVIEW_COPYTO
Definition: shresdef.h:772
REFIID LPVOID * ppv
Definition: atlbase.h:39
PIDLIST_ABSOLUTE m_pidlFolder
const char * wine_dbgstr_guid(const GUID *guid)
#define RRF_RT_REG_SZ
Definition: driver.c:575
#define ZeroMemory
Definition: winbase.h:1648
struct _StaticShellEntry_ StaticShellEntry
#define MAKEINTRESOURCEA(i)
Definition: winuser.h:581
LPWSTR dwTypeData
Definition: winuser.h:3244
UINT_PTR WPARAM
Definition: windef.h:207
HRESULT DoRename(LPCMINVOKECOMMANDINFO lpcmi)
#define IDS_OPEN_VERB
Definition: shresdef.h:197
UINT uFlags
Definition: api.c:59
#define MFS_DEFAULT
Definition: winuser.h:743
char * LPSTR
Definition: xmlstorage.h:182
#define SID_IFolderView
virtual HRESULT WINAPI GetCommandString(UINT_PTR idCommand, UINT uFlags, UINT *lpReserved, LPSTR lpszName, UINT uMaxNameLen)
#define IID_PPV_ARG(Itype, ppType)
#define E_FAIL
Definition: ddrawi.h:102
int WINAPI LoadStringW(_In_opt_ HINSTANCE hInstance, _In_ UINT uID, _Out_writes_to_(cchBufferMax, return+1) LPWSTR lpBuffer, _In_ int cchBufferMax)
HRESULT InvokeRegVerb(LPCMINVOKECOMMANDINFO lpcmi)
int32_t INT
Definition: typedefs.h:58
#define FCIDM_SHVIEW_PROPERTIES
Definition: shresdef.h:766
HRESULT WINAPI IUnknown_QueryService(IUnknown *, REFGUID, REFIID, LPVOID *)
Definition: ordinal.c:1494
WPARAM wParam
Definition: combotst.c:138
#define IDM_COPY
Definition: shresdef.h:804
#define IDS_RUNAS_VERB
Definition: shresdef.h:199
#define SEVERITY_SUCCESS
Definition: winerror.h:64
uint32_t ULONG_PTR
Definition: typedefs.h:65
struct _StaticShellEntry_ * PStaticShellEntry
#define FCIDM_SHVIEW_INSERTLINK
Definition: shresdef.h:771
_In_ PSID _Out_writes_to_opt_ cchName LPSTR _Inout_ LPDWORD cchName
Definition: winbase.h:2729
#define GHND
Definition: winbase.h:294
HRESULT WINAPI SHForwardContextMenuMsg(IUnknown *pUnk, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT *pResult, BOOL useIContextMenu2)
Definition: rosordinal.c:11
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
IShellFolder * psf
Definition: shlobj.h:2369
virtual HRESULT WINAPI InvokeCommand(LPCMINVOKECOMMANDINFO lpcmi)
LONG WINAPI RegCloseKey(HKEY hKey)
Definition: reg.c:423
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
#define MFS_ENABLED
Definition: winuser.h:745
#define FALSE
Definition: types.h:117
const PCUITEMID_CHILD * PCUITEMID_CHILD_ARRAY
Definition: shtypes.idl:71
#define IDS_EXPLORE_VERB
Definition: shresdef.h:198
virtual HRESULT WINAPI HandleMenuMsg2(UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT *plResult)
#define MIIM_STATE
Definition: winuser.h:716
unsigned int BOOL
Definition: ntddk_ex.h:94
HRESULT DoOpenOrExplore(LPCMINVOKECOMMANDINFO lpcmi)
long LONG
Definition: pedump.c:60
HRESULT WINAPI OleGetClipboard(IDataObject **obj)
Definition: clipboard.c:2249
#define FCIDM_SHVIEW_INSERT
Definition: shresdef.h:769
HRESULT TryToBrowse(LPCMINVOKECOMMANDINFO lpcmi, LPCITEMIDLIST pidl, DWORD wFlags)
LONG WINAPI RegOpenKeyW(HKEY hKey, LPCWSTR lpSubKey, PHKEY phkResult)
Definition: reg.c:3296
LPCWSTR lpDirectory
Definition: shellapi.h:332
STRSAFEAPI StringCchCopyW(STRSAFE_LPWSTR pszDest, size_t cchDest, STRSAFE_LPCWSTR pszSrc)
Definition: strsafe.h:149
#define debugstr_w
Definition: kernel32.h:32
HRESULT WINAPI IUnknown_SetSite(IUnknown *obj, IUnknown *site)
Definition: ordinal.c:1404
virtual HRESULT WINAPI QueryContextMenu(HMENU hMenu, UINT indexMenu, UINT idCmdFirst, UINT idCmdLast, UINT uFlags)
ULONG Release()
#define S_FALSE
Definition: winerror.h:2357
#define FCIDM_SHVIEW_MOVETO
Definition: shresdef.h:773
#define VK_SHIFT
Definition: winuser.h:2177
#define E_INVALIDARG
Definition: ddrawi.h:101
#define DFM_INVOKECOMMAND
Definition: precomp.h:45
smooth NULL
Definition: ftsmooth.c:416
#define IDS_PRINT_VERB
Definition: shresdef.h:202
STRSAFEAPI StringCbPrintfW(STRSAFE_LPWSTR pszDest, size_t cbDest, STRSAFE_LPCWSTR pszFormat,...)
Definition: strsafe.h:557
_At_(*)(_In_ PWSK_CLIENT Client, _In_opt_ PUNICODE_STRING NodeName, _In_opt_ PUNICODE_STRING ServiceName, _In_opt_ ULONG NameSpace, _In_opt_ GUID *Provider, _In_opt_ PADDRINFOEXW Hints, _Outptr_ PADDRINFOEXW *Result, _In_opt_ PEPROCESS OwningProcess, _In_opt_ PETHREAD OwningThread, _Inout_ PIRP Irp Result)(Mem)) NTSTATUS(WSKAPI *PFN_WSK_GET_ADDRESS_INFO
Definition: wsk.h:426
LONG_PTR LPARAM
Definition: windef.h:208
LPITEMIDLIST WINAPI ILFindLastID(LPCITEMIDLIST pidl)
Definition: pidl.c:189
BOOL WINAPI DECLSPEC_HOTPATCH ShellExecuteExW(LPSHELLEXECUTEINFOW sei)
Definition: shlexec.cpp:2263
const char * LPCSTR
Definition: xmlstorage.h:183
#define MAKE_HRESULT(sev, fac, code)
Definition: dmerror.h:30
HRESULT WINAPI SHCoCreateInstance(LPCWSTR aclsid, const CLSID *clsid, LPUNKNOWN pUnkOuter, REFIID refiid, LPVOID *ppv)
Definition: shellole.c:105
#define IDM_DELETE
Definition: shresdef.h:807
#define FCIDM_SHVIEW_NEWFOLDER
Definition: shresdef.h:790
#define MIIM_ID
Definition: winuser.h:717
#define MAX_VERB
#define BEGIN_COM_MAP(x)
Definition: atlcom.h:541
BOOL EnumerateDynamicContextHandlerForKey(HKEY hRootKey)
#define IID_NULL_PPV_ARG(Itype, ppType)
#define TRACE(s)
Definition: solgame.cpp:4
HRESULT InvokeShellExt(LPCMINVOKECOMMANDINFO lpcmi)
#define IDS_EDIT_VERB
Definition: shresdef.h:200
LONG RegLoadMUIStringW(IN HKEY hKey, IN LPCWSTR pszValue OPTIONAL, OUT LPWSTR pszOutBuf, IN DWORD cbOutBuf, OUT LPDWORD pcbData OPTIONAL, IN DWORD Flags, IN LPCWSTR pszDirectory OPTIONAL)
Definition: muireg.c:53
#define GetProcessHeap()
Definition: compat.h:595
#define FCIDM_SHVIEW_EXPLORE
Definition: shresdef.h:793
PVOID WINAPI HeapAlloc(HANDLE, DWORD, SIZE_T)
LONG WINAPI RegQueryValueExW(_In_ HKEY hkeyorg, _In_ LPCWSTR name, _In_ LPDWORD reserved, _In_ LPDWORD type, _In_ LPBYTE data, _In_ LPDWORD count)
Definition: reg.c:4116
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define FCIDM_SHVIEW_COPY
Definition: shresdef.h:768
LONG HRESULT
Definition: typedefs.h:79
BOOL WINAPI DeleteMenu(_In_ HMENU, _In_ UINT, _In_ UINT)
UINT idCmdFirst
Definition: shlobj.h:1317
#define _countof(array)
Definition: sndvol32.h:68
#define FAILED_UNEXPECTEDLY(hr)
Definition: shellutils.h:71
#define MAX_PATH
Definition: compat.h:34
#define WINAPI
Definition: msvc.h:6
HRESULT GetCommandString([in] UINT_PTR idCmd, [in] UINT uType, [out] UINT *pwReserved, [out, size_is(cchMax)] LPSTR pszName, [in] UINT cchMax)
#define DFM_MERGECONTEXTMENU
Definition: precomp.h:44
#define STDMETHODCALLTYPE
Definition: bdasup.h:9
const IID IID_IObjectWithSite
#define DFM_CMD_PROPERTIES
Definition: shlobj.h:2429
DWORD WINAPI SHAnsiToUnicode(LPCSTR lpSrcStr, LPWSTR lpDstStr, int iLen)
Definition: string.c:2659
BOOL IsShellExtensionAlreadyLoaded(const CLSID *pclsid)
unsigned long DWORD
Definition: ntddk_ex.h:95
#define WM_MEASUREITEM
Definition: winuser.h:1628
unsigned __int3264 UINT_PTR
Definition: mstsclib_h.h:274
HRESULT DoProperties(LPCMINVOKECOMMANDINFO lpcmi)
#define MFT_SEPARATOR
Definition: winuser.h:739
#define FCIDM_SHVIEW_DELETE
Definition: shresdef.h:765
struct _DynamicShellEntry_ * pNext
#define wcsicmp
Definition: compat.h:15
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)
REFCLSID clsid
Definition: msctf.c:82
static const WCHAR L[]
Definition: oid.c:1250
LPVOID NTAPI GlobalLock(HGLOBAL hMem)
Definition: heapmem.c:755
static HRESULT CDefaultContextMenu_CreateInstance(const DEFCONTEXTMENU *pdcm, LPFNDFMCALLBACK lpfn, REFIID riid, void **ppv)
PDynamicShellEntry GetDynamicEntry(UINT idCmd)
HRESULT(CALLBACK * LPFNDFMCALLBACK)(_In_opt_ IShellFolder *, _In_opt_ HWND, _In_opt_ IDataObject *, UINT, WPARAM, LPARAM)
Definition: shlobj.h:2385
#define MIIM_TYPE
Definition: winuser.h:720
void AddStaticEntry(const HKEY hkeyClass, const WCHAR *szVerb)
HRESULT DoCopyOrCut(LPCMINVOKECOMMANDINFO lpcmi, BOOL bCopy)
SHORT WINAPI GetAsyncKeyState(_In_ int)
HRESULT CRecyclerDropTarget_CreateInstance(REFIID riid, LPVOID *ppvOut)
#define IDM_PROPERTIES
Definition: resources.h:9
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
INT WINAPI SHUnicodeToAnsi(LPCWSTR lpSrcStr, LPSTR lpDstStr, INT iLen)
Definition: string.c:2783
HMENU WINAPI GetSubMenu(_In_ HMENU, _In_ int)
HRESULT DoCreateLink(LPCMINVOKECOMMANDINFO lpcmi)
CComPtr< IUnknown > m_site
void _ILFreeaPidl(LPITEMIDLIST *apidl, UINT cidl)
Definition: pidl.c:2635
BOOL WINAPI DestroyMenu(_In_ HMENU)
#define SHCNF_PATHW
Definition: shlobj.h:1764
#define FCIDM_SHVIEW_CREATELINK
Definition: shresdef.h:788
HRESULT DoCreateNewFolder(LPCMINVOKECOMMANDINFO lpici)
CComPtr< IShellFolder > m_psf
_In_ DWORD _Out_ _In_ WORD wFlags
Definition: wincon.h:534
#define ERR(fmt,...)
Definition: debug.h:110
int WINAPI SHCreateDirectory(HWND hWnd, LPCWSTR path)
Definition: shlfileop.cpp:788
DWORD BrowserFlagsFromVerb(LPCMINVOKECOMMANDINFO lpcmi, PStaticShellEntry pEntry)
_Check_return_ _CRTIMP int __cdecl wcscmp(_In_z_ const wchar_t *_Str1, _In_z_ const wchar_t *_Str2)
STRSAFEAPI StringCchCopyA(STRSAFE_LPSTR pszDest, size_t cchDest, STRSAFE_LPCSTR pszSrc)
Definition: strsafe.h:145
#define S_OK
Definition: intsafe.h:51
#define SW_SHOWNORMAL
Definition: winuser.h:764
#define shell32_hInstance
virtual HRESULT WINAPI HandleMenuMsg(UINT uMsg, WPARAM wParam, LPARAM lParam)
#define LoadMenu
Definition: winuser.h:5792
CComPtr< IDataObject > m_pDataObj
#define FCIDM_SHVIEW_RENAME
Definition: shresdef.h:787
PDynamicShellEntry m_pDynamicEntries
LPITEMIDLIST WINAPI ILClone(LPCITEMIDLIST pidl)
Definition: pidl.c:228
#define COM_INTERFACE_ENTRY_IID(iid, x)
Definition: atlcom.h:561
#define E_NOTIMPL
Definition: ddrawi.h:99
struct _StaticShellEntry_ * pNext
#define SEE_MASK_IDLIST
Definition: shellapi.h:27
BOOL WINAPI InsertMenuItemW(_In_ HMENU, _In_ UINT, _In_ BOOL, _In_ LPCMENUITEMINFOW)
#define SID_IShellBrowser
unsigned int UINT
Definition: ndis.h:50
BOOL NTAPI GlobalUnlock(HGLOBAL hMem)
Definition: heapmem.c:1190
#define MK_CONTROL
Definition: winuser.h:2345
HRESULT InvokeCommand([in] LPCMINVOKECOMMANDINFO lpici)
HRESULT WINAPI SHILCreateFromPathW(LPCWSTR path, LPITEMIDLIST *ppidl, DWORD *attributes)
Definition: pidl.c:392
#define IDM_CUT
Definition: shresdef.h:803
HRESULT _DoCallback(UINT uMsg, WPARAM wParam, LPVOID lParam)
#define WM_DRAWITEM
Definition: winuser.h:1627
void WINAPI SHFree(LPVOID pv)
Definition: shellole.c:331
CONST void * LPCVOID
Definition: windef.h:191
HRESULT SHGetMenuIdFromMenuMsg(UINT uMsg, LPARAM lParam, UINT *CmdId)
GLuint res
Definition: glext.h:9613
UINT AddShellExtensionsToMenu(HMENU hMenu, UINT *pIndexMenu, UINT idCmdFirst, UINT idCmdLast)
HRESULT WINAPI CLSIDFromString(LPCOLESTR idstr, LPCLSID id)
Definition: compobj.c:2338
#define HIWORD(l)
Definition: typedefs.h:247
HANDLE HKEY
Definition: registry.h:24
LONG WINAPI RegOpenKeyExW(HKEY hKey, LPCWSTR lpSubKey, DWORD ulOptions, REGSAM samDesired, PHKEY phkResult)
Definition: reg.c:3366
int strcmp(const char *String1, const char *String2)
Definition: utclib.c:469
HRESULT InvokePidl(LPCMINVOKECOMMANDINFO lpcmi, LPCITEMIDLIST pidl, PStaticShellEntry pEntry)
#define UNIMPLEMENTED
Definition: debug.h:115
CComPtr< IContextMenuCB > m_pmcb
HRESULT LoadDynamicContextMenuHandler(HKEY hKey, const CLSID *pclsid)
IUnknown * punkAssociationInfo
Definition: shlobj.h:2372
BOOL WINAPI PathYetAnotherMakeUniqueName(LPWSTR buffer, LPCWSTR path, LPCWSTR shortname, LPCWSTR longname)
Definition: shellpath.c:368
#define FCIDM_SHVIEW_CUT
Definition: shresdef.h:767
LONG WINAPI RegEnumKeyExW(_In_ HKEY hKey, _In_ DWORD dwIndex, _Out_ LPWSTR lpName, _Inout_ LPDWORD lpcbName, _Reserved_ LPDWORD lpReserved, _Out_opt_ LPWSTR lpClass, _Inout_opt_ LPDWORD lpcbClass, _Out_opt_ PFILETIME lpftLastWriteTime)
Definition: reg.c:2527
#define END_COM_MAP()
Definition: atlcom.h:552
#define IDM_CREATELINK
Definition: shresdef.h:806
T * Detach()
Definition: atlcomcli.h:156
WCHAR * LPWSTR
Definition: xmlstorage.h:184
#define MIIM_DATA
Definition: winuser.h:721
HRESULT DoDelete(LPCMINVOKECOMMANDINFO lpcmi)
LONG_PTR LRESULT
Definition: windef.h:209
PStaticShellEntry m_pStaticEntries
return STATUS_SUCCESS
Definition: btrfs.c:3014
BOOL MapVerbToCmdId(PVOID Verb, PUINT idCmd, BOOL IsUnicode)
PCUITEMID_CHILD_ARRAY apidl
Definition: shlobj.h:2371
HRESULT WINAPI Initialize(const DEFCONTEXTMENU *pdcm, LPFNDFMCALLBACK lpfn)
ITEMIDLIST UNALIGNED * LPITEMIDLIST
Definition: shtypes.idl:41
static const CLSID *static CLSID *static const GUID VARIANT VARIANT *static IServiceProvider DWORD *static HMENU
Definition: ordinal.c:60
#define RRF_RT_REG_DWORD
Definition: driver.c:578
void AddStaticEntriesForKey(HKEY hKey)
PCIDLIST_ABSOLUTE pidlFolder
Definition: shlobj.h:2368
LPARAM lParam
Definition: combotst.c:139
#define LOWORD(l)
Definition: pedump.c:82
size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
#define HeapFree(x, y, z)
Definition: compat.h:594
HRESULT WINAPI CDefFolderMenu_Create2(PCIDLIST_ABSOLUTE pidlFolder, HWND hwnd, UINT cidl, PCUITEMID_CHILD_ARRAY apidl, IShellFolder *psf, LPFNDFMCALLBACK lpfn, UINT nKeys, const HKEY *ahkeyClsKeys, IContextMenu **ppcm)
#define IDM_INSERT
Definition: shresdef.h:805
HRESULT DoCopyToMoveToFolder(LPCMINVOKECOMMANDINFO lpici, BOOL bCopy)
static BOOL HasClipboardData()
PITEMID_CHILD * _ILCopyaPidl(PCUITEMID_CHILD_ARRAY apidlsrc, UINT cidl)
Definition: pidl.c:2652
unsigned int * PUINT
Definition: ndis.h:50
static IShellFolder IShellItem **static IBindCtx LPITEMIDLIST SFGAOF
Definition: ebrowser.c:83
#define SUCCEEDED(hr)
Definition: intsafe.h:49
PCUITEMID_CHILD_ARRAY m_apidl
void WINAPI _InsertMenuItemW(HMENU hMenu, UINT indexMenu, BOOL fByPosition, UINT wID, UINT fType, LPCWSTR dwTypeData, UINT fState)
BOOL WINAPI SHSimulateDrop(IDropTarget *pDrop, IDataObject *pDataObj, DWORD grfKeyState, PPOINTL lpPt, DWORD *pdwEffect)
Definition: ordinal.c:1821
#define HKEY_LOCAL_MACHINE
Definition: winreg.h:12
struct _DynamicShellEntry_ DynamicShellEntry