ReactOS  0.4.14-dev-358-gbef841c
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 
11 extern "C"
12 {
13  //fixme: this isn't in wine's shlwapi header, and the definition doesnt match the
14  // windows headers. When wine's header and lib are fixed this can be removed.
15  DWORD WINAPI SHAnsiToUnicode(LPCSTR lpSrcStr, LPWSTR lpDstStr, int iLen);
16  INT WINAPI SHUnicodeToAnsi(LPCWSTR lpSrcStr, LPSTR lpDstStr, INT iLen);
17 };
18 
20 
21 typedef struct _DynamicShellEntry_
22 {
29 
30 typedef struct _StaticShellEntry_
31 {
36 
37 
38 //
39 // verbs for InvokeCommandInfo
40 //
42 {
46 {
47  { "RunAs", 0 }, // Unimplemented
48  { "Print", 0 }, // Unimplemented
49  { "Preview", 0 }, // Unimplemented
50  { "Open", FCIDM_SHVIEW_OPEN },
51  { CMDSTR_NEWFOLDERA, FCIDM_SHVIEW_NEWFOLDER },
52  { "cut", FCIDM_SHVIEW_CUT},
53  { "copy", FCIDM_SHVIEW_COPY},
54  { "paste", FCIDM_SHVIEW_INSERT},
55  { "link", FCIDM_SHVIEW_CREATELINK},
56  { "delete", FCIDM_SHVIEW_DELETE},
57  { "properties", FCIDM_SHVIEW_PROPERTIES},
58  { "rename", FCIDM_SHVIEW_RENAME},
59 };
60 
61 
63  public CComObjectRootEx<CComMultiThreadModelNoCS>,
64  public IContextMenu3,
65  public IObjectWithSite
66 {
67  private:
79  PDynamicShellEntry m_pDynamicEntries; /* first dynamic shell extension entry */
80  UINT m_iIdSHEFirst; /* first used id */
81  UINT m_iIdSHELast; /* last used id */
82  PStaticShellEntry m_pStaticEntries; /* first static shell extension entry */
83  UINT m_iIdSCMFirst; /* first static used id */
84  UINT m_iIdSCMLast; /* last static used id */
85  UINT m_iIdCBFirst; /* first callback used id */
86  UINT m_iIdCBLast; /* last callback used id */
87  UINT m_iIdDfltFirst; /* first default part id */
88  UINT m_iIdDfltLast; /* last default part id */
89 
91  void AddStaticEntry(const HKEY hkeyClass, const WCHAR *szVerb);
92  void AddStaticEntriesForKey(HKEY hKey);
94  HRESULT LoadDynamicContextMenuHandler(HKEY hKey, const CLSID *pclsid);
96  UINT AddShellExtensionsToMenu(HMENU hMenu, UINT* pIndexMenu, UINT idCmdFirst, UINT idCmdLast);
97  UINT AddStaticContextMenusToMenu(HMENU hMenu, UINT* IndexMenu, UINT iIdCmdFirst, UINT iIdCmdLast);
112  BOOL MapVerbToCmdId(PVOID Verb, PUINT idCmd, BOOL IsUnicode);
113 
114  public:
118 
119  // IContextMenu
120  virtual HRESULT WINAPI QueryContextMenu(HMENU hMenu, UINT indexMenu, UINT idCmdFirst, UINT idCmdLast, UINT uFlags);
122  virtual HRESULT WINAPI GetCommandString(UINT_PTR idCommand, UINT uFlags, UINT *lpReserved, LPSTR lpszName, UINT uMaxNameLen);
123 
124  // IContextMenu2
126 
127  // IContextMenu3
128  virtual HRESULT WINAPI HandleMenuMsg2(UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT *plResult);
129 
130  // IObjectWithSite
131  virtual HRESULT STDMETHODCALLTYPE SetSite(IUnknown *pUnkSite);
132  virtual HRESULT STDMETHODCALLTYPE GetSite(REFIID riid, void **ppvSite);
133 
135  COM_INTERFACE_ENTRY_IID(IID_IContextMenu, IContextMenu)
136  COM_INTERFACE_ENTRY_IID(IID_IContextMenu2, IContextMenu2)
137  COM_INTERFACE_ENTRY_IID(IID_IContextMenu3, IContextMenu3)
139  END_COM_MAP()
140 };
141 
143  m_psf(NULL),
144  m_pmcb(NULL),
145  m_pfnmcb(NULL),
146  m_cidl(0),
147  m_apidl(NULL),
148  m_pDataObj(NULL),
149  m_aKeys(NULL),
150  m_cKeys(NULL),
151  m_pidlFolder(NULL),
152  m_bGroupPolicyActive(0),
153  m_pDynamicEntries(NULL),
154  m_iIdSHEFirst(0),
155  m_iIdSHELast(0),
156  m_pStaticEntries(NULL),
157  m_iIdSCMFirst(0),
158  m_iIdSCMLast(0),
159  m_iIdCBFirst(0),
160  m_iIdCBLast(0),
161  m_iIdDfltFirst(0),
162  m_iIdDfltLast(0)
163 
164 {
165 }
166 
168 {
169  /* Free dynamic shell extension entries */
170  PDynamicShellEntry pDynamicEntry = m_pDynamicEntries, pNextDynamic;
171  while (pDynamicEntry)
172  {
173  pNextDynamic = pDynamicEntry->pNext;
174  pDynamicEntry->pCM->Release();
175  HeapFree(GetProcessHeap(), 0, pDynamicEntry);
176  pDynamicEntry = pNextDynamic;
177  }
178 
179  /* Free static shell extension entries */
180  PStaticShellEntry pStaticEntry = m_pStaticEntries, pNextStatic;
181  while (pStaticEntry)
182  {
183  pNextStatic = pStaticEntry->pNext;
184  HeapFree(GetProcessHeap(), 0, pStaticEntry->szVerb);
185  HeapFree(GetProcessHeap(), 0, pStaticEntry);
186  pStaticEntry = pNextStatic;
187  }
188 
189  for (UINT i = 0; i < m_cKeys; i++)
192 
193  if (m_pidlFolder)
195  _ILFreeaPidl(const_cast<PITEMID_CHILD *>(m_apidl), m_cidl);
196 }
197 
199 {
200  TRACE("cidl %u\n", pdcm->cidl);
201 
202  if (!pdcm->pcmcb && !lpfn)
203  {
204  ERR("CDefaultContextMenu needs a callback!\n");
205  return E_INVALIDARG;
206  }
207 
208  m_cidl = pdcm->cidl;
209  m_apidl = const_cast<PCUITEMID_CHILD_ARRAY>(_ILCopyaPidl(pdcm->apidl, m_cidl));
210  if (m_cidl && !m_apidl)
211  return E_OUTOFMEMORY;
212  m_psf = pdcm->psf;
213  m_pmcb = pdcm->pcmcb;
214  m_pfnmcb = lpfn;
215 
216  m_cKeys = pdcm->cKeys;
217  if (pdcm->cKeys)
218  {
219  m_aKeys = (HKEY*)HeapAlloc(GetProcessHeap(), 0, sizeof(HKEY) * pdcm->cKeys);
220  if (!m_aKeys)
221  return E_OUTOFMEMORY;
222  memcpy(m_aKeys, pdcm->aKeys, sizeof(HKEY) * pdcm->cKeys);
223  }
224 
225  m_psf->GetUIObjectOf(pdcm->hwnd, m_cidl, m_apidl, IID_NULL_PPV_ARG(IDataObject, &m_pDataObj));
226 
227  if (pdcm->pidlFolder)
228  {
230  }
231  else
232  {
234  if (SUCCEEDED(m_psf->QueryInterface(IID_PPV_ARG(IPersistFolder2, &pf))))
235  {
236  if (FAILED(pf->GetCurFolder(&m_pidlFolder)))
237  ERR("GetCurFolder failed\n");
238  }
239  TRACE("pidlFolder %p\n", m_pidlFolder);
240  }
241 
242  return S_OK;
243 }
244 
246 {
247  if (m_pmcb)
248  {
249  return m_pmcb->CallBack(m_psf, NULL, m_pDataObj, uMsg, wParam, (LPARAM)lParam);
250  }
251  else if(m_pfnmcb)
252  {
253  return m_pfnmcb(m_psf, NULL, m_pDataObj, uMsg, wParam, (LPARAM)lParam);
254  }
255 
256  return E_FAIL;
257 }
258 
259 void CDefaultContextMenu::AddStaticEntry(const HKEY hkeyClass, const WCHAR *szVerb)
260 {
261  PStaticShellEntry pEntry = m_pStaticEntries, pLastEntry = NULL;
262  while(pEntry)
263  {
264  if (!wcsicmp(pEntry->szVerb, szVerb))
265  {
266  /* entry already exists */
267  return;
268  }
269  pLastEntry = pEntry;
270  pEntry = pEntry->pNext;
271  }
272 
273  TRACE("adding verb %s\n", debugstr_w(szVerb));
274 
275  pEntry = (StaticShellEntry *)HeapAlloc(GetProcessHeap(), 0, sizeof(StaticShellEntry));
276  if (pEntry)
277  {
278  pEntry->pNext = NULL;
279  pEntry->szVerb = (LPWSTR)HeapAlloc(GetProcessHeap(), 0, (wcslen(szVerb) + 1) * sizeof(WCHAR));
280  if (pEntry->szVerb)
281  wcscpy(pEntry->szVerb, szVerb);
282  pEntry->hkClass = hkeyClass;
283  }
284 
285  if (!wcsicmp(szVerb, L"open"))
286  {
287  /* open verb is always inserted in front */
288  pEntry->pNext = m_pStaticEntries;
289  m_pStaticEntries = pEntry;
290  }
291  else if (pLastEntry)
292  pLastEntry->pNext = pEntry;
293  else
294  m_pStaticEntries = pEntry;
295 }
296 
298 {
299  WCHAR wszName[40];
300  DWORD cchName, dwIndex = 0;
301  HKEY hShellKey;
302 
303  LRESULT lres = RegOpenKeyExW(hKey, L"shell", 0, KEY_READ, &hShellKey);
304  if (lres != STATUS_SUCCESS)
305  return;
306 
307  while(TRUE)
308  {
309  cchName = _countof(wszName);
310  if (RegEnumKeyExW(hShellKey, dwIndex++, wszName, &cchName, NULL, NULL, NULL, NULL) != ERROR_SUCCESS)
311  break;
312 
313  AddStaticEntry(hKey, wszName);
314  }
315 
316  RegCloseKey(hShellKey);
317 }
318 
319 static
320 BOOL
322 {
323  BOOL bRet = FALSE;
324  CComPtr<IDataObject> pDataObj;
325 
326  if (SUCCEEDED(OleGetClipboard(&pDataObj)))
327  {
328  FORMATETC formatetc;
329 
330  TRACE("pDataObj=%p\n", pDataObj.p);
331 
332  /* Set the FORMATETC structure*/
333  InitFormatEtc(formatetc, RegisterClipboardFormatW(CFSTR_SHELLIDLIST), TYMED_HGLOBAL);
334  bRet = SUCCEEDED(pDataObj->QueryGetData(&formatetc));
335  }
336 
337  return bRet;
338 }
339 
340 BOOL
342 {
344 
345  while (pEntry)
346  {
347  if (!memcmp(&pEntry->ClassID, pclsid, sizeof(CLSID)))
348  return TRUE;
349  pEntry = pEntry->pNext;
350  }
351 
352  return FALSE;
353 }
354 
355 HRESULT
357 {
358  HRESULT hr;
359 
360  TRACE("LoadDynamicContextMenuHandler entered with This %p hKey %p pclsid %s\n", this, hKey, wine_dbgstr_guid(pclsid));
361 
362  if (IsShellExtensionAlreadyLoaded(pclsid))
363  return S_OK;
364 
367  if (FAILED(hr))
368  {
369  ERR("SHCoCreateInstance(IContextMenu) failed.clsid %s hr 0x%x\n", wine_dbgstr_guid(pclsid), hr);
370  return hr;
371  }
372 
373  CComPtr<IShellExtInit> pExtInit;
374  hr = pcm->QueryInterface(IID_PPV_ARG(IShellExtInit, &pExtInit));
375  if (FAILED(hr))
376  {
377  ERR("IContextMenu->QueryInterface(IShellExtInit) failed.clsid %s hr 0x%x\n", wine_dbgstr_guid(pclsid), hr);
378  return hr;
379  }
380 
381  hr = pExtInit->Initialize(m_pidlFolder, m_pDataObj, hKey);
382  if (FAILED(hr))
383  {
384  WARN("IShellExtInit::Initialize failed.clsid %s hr 0x%x\n", wine_dbgstr_guid(pclsid), hr);
385  return hr;
386  }
387 
388  if (m_site)
389  IUnknown_SetSite(pcm, m_site);
390 
392  if (!pEntry)
393  return E_OUTOFMEMORY;
394 
395  pEntry->iIdCmdFirst = 0;
396  pEntry->pNext = NULL;
397  pEntry->NumIds = 0;
398  pEntry->pCM = pcm.Detach();
399  memcpy(&pEntry->ClassID, pclsid, sizeof(CLSID));
400 
401  if (m_pDynamicEntries)
402  {
404 
405  while (pLastEntry->pNext)
406  pLastEntry = pLastEntry->pNext;
407 
408  pLastEntry->pNext = pEntry;
409  }
410  else
411  m_pDynamicEntries = pEntry;
412 
413  return S_OK;
414 }
415 
416 BOOL
418 {
419  WCHAR wszName[MAX_PATH], wszBuf[MAX_PATH], *pwszClsid;
420  DWORD cchName;
421  HRESULT hr;
422  HKEY hKey;
423 
424  if (RegOpenKeyExW(hRootKey, L"shellex\\ContextMenuHandlers", 0, KEY_READ, &hKey) != ERROR_SUCCESS)
425  {
426  TRACE("RegOpenKeyExW failed\n");
427  return FALSE;
428  }
429 
430  DWORD dwIndex = 0;
431  while (TRUE)
432  {
433  cchName = _countof(wszName);
434  if (RegEnumKeyExW(hKey, dwIndex++, wszName, &cchName, NULL, NULL, NULL, NULL) != ERROR_SUCCESS)
435  break;
436 
437  /* Key name or key value is CLSID */
438  CLSID clsid;
439  hr = CLSIDFromString(wszName, &clsid);
440  if (hr == S_OK)
441  pwszClsid = wszName;
442  else
443  {
444  DWORD cchBuf = _countof(wszBuf);
445  if (RegGetValueW(hKey, wszName, NULL, RRF_RT_REG_SZ, NULL, wszBuf, &cchBuf) == ERROR_SUCCESS)
446  hr = CLSIDFromString(wszBuf, &clsid);
447  pwszClsid = wszBuf;
448  }
449 
450  if (FAILED(hr))
451  {
452  ERR("CLSIDFromString failed for clsid %S hr 0x%x\n", pwszClsid, hr);
453  continue;
454  }
455 
457  {
459  L"Software\\Microsoft\\Windows\\CurrentVersion\\Shell Extensions\\Approved",
460  pwszClsid,
462  NULL,
463  NULL,
464  NULL) != ERROR_SUCCESS)
465  {
466  ERR("Shell extension %s not approved!\n", pwszClsid);
467  continue;
468  }
469  }
470 
472  if (FAILED(hr))
473  WARN("Failed to get context menu entires from shell extension! clsid: %S\n", pwszClsid);
474  }
475 
476  RegCloseKey(hKey);
477  return TRUE;
478 }
479 
480 UINT
481 CDefaultContextMenu::AddShellExtensionsToMenu(HMENU hMenu, UINT* pIndexMenu, UINT idCmdFirst, UINT idCmdLast)
482 {
483  UINT cIds = 0;
484 
485  if (!m_pDynamicEntries)
486  return cIds;
487 
489  do
490  {
491  HRESULT hr = pEntry->pCM->QueryContextMenu(hMenu, *pIndexMenu, idCmdFirst + cIds, idCmdLast, CMF_NORMAL);
492  if (SUCCEEDED(hr))
493  {
494  pEntry->iIdCmdFirst = cIds;
495  pEntry->NumIds = LOWORD(hr);
496  (*pIndexMenu) += pEntry->NumIds;
497 
498  cIds += pEntry->NumIds;
499  if(idCmdFirst + cIds >= idCmdLast)
500  break;
501  }
502  TRACE("pEntry %p hr %x contextmenu %p cmdfirst %x num ids %x\n", pEntry, hr, pEntry->pCM, pEntry->iIdCmdFirst, pEntry->NumIds);
503  pEntry = pEntry->pNext;
504  } while (pEntry);
505 
506  return cIds;
507 }
508 
509 UINT
511  HMENU hMenu,
512  UINT* pIndexMenu,
513  UINT iIdCmdFirst,
514  UINT iIdCmdLast)
515 {
516  MENUITEMINFOW mii;
517  UINT idResource;
518  WCHAR wszVerb[40];
519  UINT fState;
520  UINT cIds = 0;
521 
522  mii.cbSize = sizeof(mii);
524  mii.fType = MFT_STRING;
525  mii.dwTypeData = NULL;
526 
528 
529  while (pEntry)
530  {
531  fState = MFS_ENABLED;
532  mii.dwTypeData = NULL;
533 
534  /* set first entry as default */
535  if (pEntry == m_pStaticEntries)
536  fState |= MFS_DEFAULT;
537 
538  if (!wcsicmp(pEntry->szVerb, L"open"))
539  {
540  /* override default when open verb is found */
541  fState |= MFS_DEFAULT;
542  idResource = IDS_OPEN_VERB;
543  }
544  else if (!wcsicmp(pEntry->szVerb, L"explore"))
545  idResource = IDS_EXPLORE_VERB;
546  else if (!wcsicmp(pEntry->szVerb, L"runas"))
547  idResource = IDS_RUNAS_VERB;
548  else if (!wcsicmp(pEntry->szVerb, L"edit"))
549  idResource = IDS_EDIT_VERB;
550  else if (!wcsicmp(pEntry->szVerb, L"find"))
551  idResource = IDS_FIND_VERB;
552  else if (!wcsicmp(pEntry->szVerb, L"print"))
553  idResource = IDS_PRINT_VERB;
554  else if (!wcsicmp(pEntry->szVerb, L"printto"))
555  {
556  pEntry = pEntry->pNext;
557  continue;
558  }
559  else
560  idResource = 0;
561 
562  /* By default use verb for menu item name */
563  mii.dwTypeData = pEntry->szVerb;
564 
565  WCHAR wszKey[256];
566  HRESULT hr;
567  hr = StringCbPrintfW(wszKey, sizeof(wszKey), L"shell\\%s", pEntry->szVerb);
568  if (FAILED_UNEXPECTEDLY(hr))
569  {
570  pEntry = pEntry->pNext;
571  continue;
572  }
573 
574  BOOL Extended = FALSE;
575  HKEY hkVerb;
576  if (idResource > 0)
577  {
578  if (LoadStringW(shell32_hInstance, idResource, wszVerb, _countof(wszVerb)))
579  mii.dwTypeData = wszVerb; /* use translated verb */
580  else
581  ERR("Failed to load string\n");
582 
583  LONG res = RegOpenKeyW(pEntry->hkClass, wszKey, &hkVerb);
584  if (res == ERROR_SUCCESS)
585  {
586  res = RegQueryValueExW(hkVerb, L"Extended", NULL, NULL, NULL, NULL);
587  Extended = (res == ERROR_SUCCESS);
588 
589  RegCloseKey(hkVerb);
590  }
591  }
592  else
593  {
594  LONG res = RegOpenKeyW(pEntry->hkClass, wszKey, &hkVerb);
595  if (res == ERROR_SUCCESS)
596  {
597  DWORD cbVerb = sizeof(wszVerb);
598  res = RegLoadMUIStringW(hkVerb, NULL, wszVerb, cbVerb, NULL, 0, NULL);
599  if (res == ERROR_SUCCESS)
600  {
601  /* use description for the menu entry */
602  mii.dwTypeData = wszVerb;
603  }
604 
605  res = RegQueryValueExW(hkVerb, L"Extended", NULL, NULL, NULL, NULL);
606  Extended = (res == ERROR_SUCCESS);
607 
608  RegCloseKey(hkVerb);
609  }
610  }
611 
612  if (!Extended || GetAsyncKeyState(VK_SHIFT) < 0)
613  {
614  mii.cch = wcslen(mii.dwTypeData);
615  mii.fState = fState;
616  mii.wID = iIdCmdFirst + cIds;
617  InsertMenuItemW(hMenu, *pIndexMenu, TRUE, &mii);
618  (*pIndexMenu)++;
619  cIds++;
620  }
621 
622  pEntry = pEntry->pNext;
623 
624  if (mii.wID >= iIdCmdLast)
625  break;
626  }
627 
628  return cIds;
629 }
630 
632  HMENU hMenu,
633  UINT indexMenu,
634  BOOL fByPosition,
635  UINT wID,
636  UINT fType,
637  LPCWSTR dwTypeData,
638  UINT fState)
639 {
640  MENUITEMINFOW mii;
641  WCHAR wszText[100];
642 
643  ZeroMemory(&mii, sizeof(mii));
644  mii.cbSize = sizeof(mii);
645  if (fType == MFT_SEPARATOR)
646  mii.fMask = MIIM_ID | MIIM_TYPE;
647  else if (fType == MFT_STRING)
648  {
649  mii.fMask = MIIM_ID | MIIM_TYPE | MIIM_STATE;
650  if ((ULONG_PTR)HIWORD((ULONG_PTR)dwTypeData) == 0)
651  {
652  if (LoadStringW(shell32_hInstance, LOWORD((ULONG_PTR)dwTypeData), wszText, _countof(wszText)))
653  mii.dwTypeData = wszText;
654  else
655  {
656  ERR("failed to load string %p\n", dwTypeData);
657  return;
658  }
659  }
660  else
661  mii.dwTypeData = (LPWSTR)dwTypeData;
662  mii.fState = fState;
663  }
664 
665  mii.wID = wID;
666  mii.fType = fType;
667  InsertMenuItemW(hMenu, indexMenu, fByPosition, &mii);
668 }
669 
670 HRESULT
671 WINAPI
673  HMENU hMenu,
674  UINT IndexMenu,
675  UINT idCmdFirst,
676  UINT idCmdLast,
677  UINT uFlags)
678 {
679  HRESULT hr;
680  UINT idCmdNext = idCmdFirst;
681  UINT cIds = 0;
682 
683  TRACE("BuildShellItemContextMenu entered\n");
684 
685  /* Load static verbs and shell extensions from registry */
686  for (UINT i = 0; i < m_cKeys; i++)
687  {
690  }
691 
692  /* Add static context menu handlers */
693  cIds = AddStaticContextMenusToMenu(hMenu, &IndexMenu, idCmdFirst, idCmdLast);
694  m_iIdSCMFirst = 0;
695  m_iIdSCMLast = cIds;
696  idCmdNext = idCmdFirst + cIds;
697 
698  /* Add dynamic context menu handlers */
699  cIds += AddShellExtensionsToMenu(hMenu, &IndexMenu, idCmdNext, idCmdLast);
701  m_iIdSHELast = cIds;
702  idCmdNext = idCmdFirst + cIds;
703  TRACE("SH_LoadContextMenuHandlers first %x last %x\n", m_iIdSHEFirst, m_iIdSHELast);
704 
705  /* Now let the callback add its own items */
706  QCMINFO qcminfo = {hMenu, IndexMenu, idCmdNext, idCmdLast, NULL};
708  {
709  cIds += qcminfo.idCmdFirst;
710  IndexMenu += qcminfo.idCmdFirst;
712  m_iIdCBLast = cIds;
713  idCmdNext = idCmdFirst + cIds;
714  }
715 
716  if (uFlags & CMF_VERBSONLY)
717  return MAKE_HRESULT(SEVERITY_SUCCESS, 0, cIds);
718 
719  /* If this is a background context menu we are done */
720  if (!m_cidl)
721  return MAKE_HRESULT(SEVERITY_SUCCESS, 0, cIds);
722 
723  /* Get the attributes of the items */
724  SFGAOF rfg = SFGAO_BROWSABLE | SFGAO_CANCOPY | SFGAO_CANLINK | SFGAO_CANMOVE | SFGAO_CANDELETE | SFGAO_CANRENAME | SFGAO_HASPROPSHEET | SFGAO_FILESYSTEM | SFGAO_FOLDER;
725  hr = m_psf->GetAttributesOf(m_cidl, m_apidl, &rfg);
726  if (FAILED_UNEXPECTEDLY(hr))
727  return MAKE_HRESULT(SEVERITY_SUCCESS, 0, cIds);
728 
729  /* Add the default part of the menu */
730  HMENU hmenuDefault = LoadMenu(_AtlBaseModule.GetResourceInstance(), L"MENU_SHV_FILE");
731 
732  /* Remove uneeded entries */
733  if (!(rfg & SFGAO_CANMOVE))
734  DeleteMenu(hmenuDefault, IDM_CUT, MF_BYCOMMAND);
735  if (!(rfg & SFGAO_CANCOPY))
736  DeleteMenu(hmenuDefault, IDM_COPY, MF_BYCOMMAND);
737  if (!((rfg & SFGAO_FILESYSTEM) && HasClipboardData()))
738  DeleteMenu(hmenuDefault, IDM_INSERT, MF_BYCOMMAND);
739  if (!(rfg & SFGAO_CANLINK))
740  DeleteMenu(hmenuDefault, IDM_CREATELINK, MF_BYCOMMAND);
741  if (!(rfg & SFGAO_CANDELETE))
742  DeleteMenu(hmenuDefault, IDM_DELETE, MF_BYCOMMAND);
743  if (!(rfg & SFGAO_CANRENAME))
744  DeleteMenu(hmenuDefault, IDM_RENAME, MF_BYCOMMAND);
745  if (!(rfg & SFGAO_HASPROPSHEET))
746  DeleteMenu(hmenuDefault, IDM_PROPERTIES, MF_BYCOMMAND);
747 
748  UINT idMax = Shell_MergeMenus(hMenu, GetSubMenu(hmenuDefault, 0), IndexMenu, idCmdNext, idCmdLast, 0);
749  m_iIdDfltFirst = cIds;
750  cIds += idMax - idCmdNext;
751  m_iIdDfltLast = cIds;
752 
753  DestroyMenu(hmenuDefault);
754 
755  return MAKE_HRESULT(SEVERITY_SUCCESS, 0, cIds);
756 }
757 
759 {
760  HRESULT hr;
761 
763  hr = OleGetClipboard(&pda);
764  if (FAILED_UNEXPECTEDLY(hr))
765  return hr;
766 
767  FORMATETC formatetc2;
768  STGMEDIUM medium2;
770 
771  DWORD dwKey= 0;
772 
773  if (SUCCEEDED(pda->GetData(&formatetc2, &medium2)))
774  {
775  DWORD * pdwFlag = (DWORD*)GlobalLock(medium2.hGlobal);
776  if (pdwFlag)
777  {
778  if (*pdwFlag == DROPEFFECT_COPY)
779  dwKey = MK_CONTROL;
780  else
781  dwKey = MK_SHIFT;
782  }
783  else {
784  ERR("No drop effect obtained");
785  }
786  GlobalUnlock(medium2.hGlobal);
787  }
788 
789  if (bLink)
790  {
791  dwKey = MK_CONTROL|MK_SHIFT;
792  }
793 
794  CComPtr<IDropTarget> pdrop;
795  if (m_cidl)
796  hr = m_psf->GetUIObjectOf(NULL, 1, &m_apidl[0], IID_NULL_PPV_ARG(IDropTarget, &pdrop));
797  else
798  hr = m_psf->CreateViewObject(NULL, IID_PPV_ARG(IDropTarget, &pdrop));
799 
800  if (FAILED_UNEXPECTEDLY(hr))
801  return hr;
802 
803  SHSimulateDrop(pdrop, pda, dwKey, NULL, NULL);
804 
805  TRACE("CP result %x\n", hr);
806  return S_OK;
807 }
808 
809 HRESULT
811 {
813  return E_FAIL;
814 }
815 
817 {
818  if (!m_cidl || !m_pDataObj)
819  return E_FAIL;
820 
822  HRESULT hr = m_psf->CreateViewObject(NULL, IID_PPV_ARG(IDropTarget, &pDT));
823  if (FAILED_UNEXPECTEDLY(hr))
824  return hr;
825 
827 
828  return S_OK;
829 }
830 
832 {
833  if (!m_cidl || !m_pDataObj)
834  return E_FAIL;
835 
838  if (FAILED_UNEXPECTEDLY(hr))
839  return hr;
840 
841  SHSimulateDrop(pDT, m_pDataObj, 0, NULL, NULL);
842 
843  return S_OK;
844 }
845 
847 {
848  if (!m_cidl || !m_pDataObj)
849  return E_FAIL;
850 
851  FORMATETC formatetc;
853  STGMEDIUM medium = {0};
854  medium.tymed = TYMED_HGLOBAL;
855  medium.hGlobal = GlobalAlloc(GHND, sizeof(DWORD));
856  DWORD* pdwFlag = (DWORD*)GlobalLock(medium.hGlobal);
857  if (pdwFlag)
858  *pdwFlag = bCopy ? DROPEFFECT_COPY : DROPEFFECT_MOVE;
859  GlobalUnlock(medium.hGlobal);
860  m_pDataObj->SetData(&formatetc, &medium, TRUE);
861 
863  if (FAILED_UNEXPECTEDLY(hr))
864  return hr;
865 
866  return S_OK;
867 }
868 
870 {
872  HRESULT hr;
873 
874  if (!m_site || !m_cidl)
875  return E_FAIL;
876 
877  /* Get a pointer to the shell browser */
879  if (FAILED_UNEXPECTEDLY(hr))
880  return hr;
881 
882  CComPtr<IShellView> lpSV;
883  hr = psb->QueryActiveShellView(&lpSV);
884  if (FAILED_UNEXPECTEDLY(hr))
885  return hr;
886 
887  SVSIF selFlags = SVSI_DESELECTOTHERS | SVSI_EDIT | SVSI_ENSUREVISIBLE | SVSI_FOCUSED | SVSI_SELECT;
888  hr = lpSV->SelectItem(m_apidl[0], selFlags);
889  if (FAILED_UNEXPECTEDLY(hr))
890  return hr;
891 
892  return S_OK;
893 }
894 
895 HRESULT
897  LPCMINVOKECOMMANDINFO lpcmi)
898 {
900 
901  return S_OK;
902 }
903 
904 // This code is taken from CNewMenu and should be shared between the 2 classes
905 HRESULT
907  LPCMINVOKECOMMANDINFO lpici)
908 {
909  WCHAR wszPath[MAX_PATH];
910  WCHAR wszName[MAX_PATH];
911  WCHAR wszNewFolder[25];
912  HRESULT hr;
913 
914  /* Get folder path */
916  if (FAILED_UNEXPECTEDLY(hr))
917  return hr;
918 
919  if (!LoadStringW(shell32_hInstance, IDS_NEWFOLDER, wszNewFolder, _countof(wszNewFolder)))
920  return E_FAIL;
921 
922  /* Create the name of the new directory */
923  if (!PathYetAnotherMakeUniqueName(wszName, wszPath, NULL, wszNewFolder))
924  return E_FAIL;
925 
926  /* Create the new directory and show the appropriate dialog in case of error */
927  if (SHCreateDirectory(lpici->hwnd, wszName) != ERROR_SUCCESS)
928  return E_FAIL;
929 
930  /* Show and select the new item in the def view */
931  LPITEMIDLIST pidl;
932  PITEMID_CHILD pidlNewItem;
934 
935  /* Notify the view object about the new item */
937 
938  if (!m_site)
939  return S_OK;
940 
941  /* Get a pointer to the shell view */
943  if (FAILED_UNEXPECTEDLY(hr))
944  return S_OK;
945 
946  /* Attempt to get the pidl of the new item */
947  hr = SHILCreateFromPathW(wszName, &pidl, NULL);
948  if (FAILED_UNEXPECTEDLY(hr))
949  return hr;
950 
951  pidlNewItem = ILFindLastID(pidl);
952 
953  hr = psv->SelectItem(pidlNewItem, SVSI_DESELECTOTHERS | SVSI_EDIT | SVSI_ENSUREVISIBLE |
954  SVSI_FOCUSED | SVSI_SELECT);
955  if (FAILED_UNEXPECTEDLY(hr))
956  return hr;
957 
958  SHFree(pidl);
959 
960  return S_OK;
961 }
962 
964 {
966 
967  while(pEntry && idCmd >= pEntry->iIdCmdFirst + pEntry->NumIds)
968  pEntry = pEntry->pNext;
969 
970  if (!pEntry)
971  return NULL;
972 
973  if (idCmd < pEntry->iIdCmdFirst || idCmd > pEntry->iIdCmdFirst + pEntry->NumIds)
974  return NULL;
975 
976  return pEntry;
977 }
978 
979 // FIXME: 260 is correct, but should this be part of the SDK or just MAX_PATH?
980 #define MAX_VERB 260
981 
982 BOOL
984 {
985  WCHAR UnicodeStr[MAX_VERB];
986 
987  /* Loop through all the static verbs looking for a match */
988  for (UINT i = 0; i < _countof(g_StaticInvokeCmdMap); i++)
989  {
990  /* We can match both ANSI and unicode strings */
991  if (IsUnicode)
992  {
993  /* The static verbs are ANSI, get a unicode version before doing the compare */
994  SHAnsiToUnicode(g_StaticInvokeCmdMap[i].szStringVerb, UnicodeStr, MAX_VERB);
995  if (!wcscmp(UnicodeStr, (LPWSTR)Verb))
996  {
997  /* Return the Corresponding Id */
998  *idCmd = g_StaticInvokeCmdMap[i].IntVerb;
999  return TRUE;
1000  }
1001  }
1002  else
1003  {
1004  if (!strcmp(g_StaticInvokeCmdMap[i].szStringVerb, (LPSTR)Verb))
1005  {
1006  *idCmd = g_StaticInvokeCmdMap[i].IntVerb;
1007  return TRUE;
1008  }
1009  }
1010  }
1011 
1012  return FALSE;
1013 }
1014 
1015 HRESULT
1017  LPCMINVOKECOMMANDINFO lpcmi)
1018 {
1019  TRACE("verb %p first %x last %x\n", lpcmi->lpVerb, m_iIdSHEFirst, m_iIdSHELast);
1020 
1021  UINT idCmd = LOWORD(lpcmi->lpVerb);
1022  PDynamicShellEntry pEntry = GetDynamicEntry(idCmd);
1023  if (!pEntry)
1024  return E_FAIL;
1025 
1026  /* invoke the dynamic context menu */
1027  lpcmi->lpVerb = MAKEINTRESOURCEA(idCmd - pEntry->iIdCmdFirst);
1028  return pEntry->pCM->InvokeCommand(lpcmi);
1029 }
1030 
1031 DWORD
1033 {
1035  HWND hwndTree;
1036  LPCWSTR FlagsName;
1037  WCHAR wszKey[256];
1038  HRESULT hr;
1039  DWORD wFlags;
1040  DWORD cbVerb;
1041 
1042  if (!m_site)
1043  return 0;
1044 
1045  /* Get a pointer to the shell browser */
1047  if (FAILED_UNEXPECTEDLY(hr))
1048  return 0;
1049 
1050  /* See if we are in Explore or Browse mode. If the browser's tree is present, we are in Explore mode.*/
1051  if (SUCCEEDED(psb->GetControlWindow(FCW_TREE, &hwndTree)) && hwndTree)
1052  FlagsName = L"ExplorerFlags";
1053  else
1054  FlagsName = L"BrowserFlags";
1055 
1056  /* Try to get the flag from the verb */
1057  hr = StringCbPrintfW(wszKey, sizeof(wszKey), L"shell\\%s", pEntry->szVerb);
1058  if (FAILED_UNEXPECTEDLY(hr))
1059  return 0;
1060 
1061  cbVerb = sizeof(wFlags);
1062  if (RegGetValueW(pEntry->hkClass, wszKey, FlagsName, RRF_RT_REG_DWORD, NULL, &wFlags, &cbVerb) == ERROR_SUCCESS)
1063  {
1064  return wFlags;
1065  }
1066 
1067  return 0;
1068 }
1069 
1070 HRESULT
1073 {
1075  HRESULT hr;
1076 
1077  if (!m_site)
1078  return E_FAIL;
1079 
1080  /* Get a pointer to the shell browser */
1082  if (FAILED_UNEXPECTEDLY(hr))
1083  return 0;
1084 
1085  return psb->BrowseObject(ILCombine(m_pidlFolder, pidl), wFlags);
1086 }
1087 
1088 HRESULT
1090 {
1091  LPITEMIDLIST pidlFull = ILCombine(m_pidlFolder, pidl);
1092  if (pidlFull == NULL)
1093  {
1094  return E_FAIL;
1095  }
1096 
1097  WCHAR wszPath[MAX_PATH];
1098  BOOL bHasPath = SHGetPathFromIDListW(pidlFull, wszPath);
1099 
1100  WCHAR wszDir[MAX_PATH];
1101  if (bHasPath)
1102  {
1103  wcscpy(wszDir, wszPath);
1104  PathRemoveFileSpec(wszDir);
1105  }
1106  else
1107  {
1109  }
1110 
1111  SHELLEXECUTEINFOW sei;
1112  ZeroMemory(&sei, sizeof(sei));
1113  sei.cbSize = sizeof(sei);
1114  sei.hwnd = lpcmi->hwnd;
1115  sei.nShow = SW_SHOWNORMAL;
1116  sei.lpVerb = pEntry->szVerb;
1117  sei.lpDirectory = wszDir;
1118  sei.lpIDList = pidlFull;
1119  sei.hkeyClass = pEntry->hkClass;
1121  if (bHasPath)
1122  {
1123  sei.lpFile = wszPath;
1124  }
1125 
1126  ShellExecuteExW(&sei);
1127 
1128  ILFree(pidlFull);
1129 
1130  return S_OK;
1131 }
1132 
1133 HRESULT
1135  LPCMINVOKECOMMANDINFO lpcmi)
1136 {
1138  INT iCmd = LOWORD(lpcmi->lpVerb) - m_iIdSCMFirst;
1139  HRESULT hr;
1140  UINT i;
1141 
1142  while (pEntry && (iCmd--) > 0)
1143  pEntry = pEntry->pNext;
1144 
1145  if (iCmd > 0)
1146  return E_FAIL;
1147 
1148  /* Get the browse flags to see if we need to browse */
1149  DWORD wFlags = BrowserFlagsFromVerb(lpcmi, pEntry);
1150  BOOL bBrowsed = FALSE;
1151 
1152  for (i=0; i < m_cidl; i++)
1153  {
1154  /* Check if we need to browse */
1155  if (wFlags > 0)
1156  {
1157  /* In xp if we have browsed, we don't open any more folders.
1158  * In win7 we browse to the first folder we find and
1159  * open new windows for each of the rest of the folders */
1160  if (bBrowsed)
1161  continue;
1162 
1163  hr = TryToBrowse(lpcmi, m_apidl[i], wFlags);
1164  if (SUCCEEDED(hr))
1165  {
1166  bBrowsed = TRUE;
1167  continue;
1168  }
1169  }
1170 
1171  InvokePidl(lpcmi, m_apidl[i], pEntry);
1172  }
1173 
1174  return S_OK;
1175 }
1176 
1177 HRESULT
1178 WINAPI
1180  LPCMINVOKECOMMANDINFO lpcmi)
1181 {
1182  CMINVOKECOMMANDINFO LocalInvokeInfo;
1183  HRESULT Result;
1184  UINT CmdId;
1185 
1186  /* Take a local copy of the fixed members of the
1187  struct as we might need to modify the verb */
1188  LocalInvokeInfo = *lpcmi;
1189 
1190  /* Check if this is a string verb */
1191  if (HIWORD(LocalInvokeInfo.lpVerb))
1192  {
1193  /* Get the ID which corresponds to this verb, and update our local copy */
1194  if (MapVerbToCmdId((LPVOID)LocalInvokeInfo.lpVerb, &CmdId, FALSE))
1195  LocalInvokeInfo.lpVerb = MAKEINTRESOURCEA(CmdId);
1196  }
1197 
1198  CmdId = LOWORD(LocalInvokeInfo.lpVerb);
1199 
1200  if (m_pDynamicEntries && CmdId >= m_iIdSHEFirst && CmdId < m_iIdSHELast)
1201  {
1202  LocalInvokeInfo.lpVerb -= m_iIdSHEFirst;
1203  Result = InvokeShellExt(&LocalInvokeInfo);
1204  return Result;
1205  }
1206 
1207  if (m_pStaticEntries && CmdId >= m_iIdSCMFirst && CmdId < m_iIdSCMLast)
1208  {
1209  LocalInvokeInfo.lpVerb -= m_iIdSCMFirst;
1210  Result = InvokeRegVerb(&LocalInvokeInfo);
1211  return Result;
1212  }
1213 
1214  if (m_iIdCBFirst != m_iIdCBLast && CmdId >= m_iIdCBFirst && CmdId < m_iIdCBLast)
1215  {
1217  return Result;
1218  }
1219 
1220  if (m_iIdDfltFirst != m_iIdDfltLast && CmdId >= m_iIdDfltFirst && CmdId < m_iIdDfltLast)
1221  {
1222  CmdId -= m_iIdDfltFirst;
1223  /* See the definitions of IDM_CUT and co to see how this works */
1224  CmdId += 0x7000;
1225  }
1226 
1227  /* Check if this is a Id */
1228  switch (CmdId)
1229  {
1230  case FCIDM_SHVIEW_INSERT:
1231  Result = DoPaste(&LocalInvokeInfo, FALSE);
1232  break;
1234  Result = DoPaste(&LocalInvokeInfo, TRUE);
1235  break;
1236  case FCIDM_SHVIEW_OPEN:
1237  case FCIDM_SHVIEW_EXPLORE:
1238  Result = DoOpenOrExplore(&LocalInvokeInfo);
1239  break;
1240  case FCIDM_SHVIEW_COPY:
1241  case FCIDM_SHVIEW_CUT:
1242  Result = DoCopyOrCut(&LocalInvokeInfo, CmdId == FCIDM_SHVIEW_COPY);
1243  break;
1245  Result = DoCreateLink(&LocalInvokeInfo);
1246  break;
1247  case FCIDM_SHVIEW_DELETE:
1248  Result = DoDelete(&LocalInvokeInfo);
1249  break;
1250  case FCIDM_SHVIEW_RENAME:
1251  Result = DoRename(&LocalInvokeInfo);
1252  break;
1254  Result = DoProperties(&LocalInvokeInfo);
1255  break;
1257  Result = DoCreateNewFolder(&LocalInvokeInfo);
1258  break;
1259  default:
1260  Result = E_INVALIDARG;
1261  ERR("Unhandled Verb %xl\n", LOWORD(LocalInvokeInfo.lpVerb));
1262  break;
1263  }
1264 
1265  return Result;
1266 }
1267 
1268 HRESULT
1269 WINAPI
1271  UINT_PTR idCommand,
1272  UINT uFlags,
1273  UINT* lpReserved,
1274  LPSTR lpszName,
1275  UINT uMaxNameLen)
1276 {
1277  /* We don't handle the help text yet */
1278  if (uFlags == GCS_HELPTEXTA ||
1279  uFlags == GCS_HELPTEXTW ||
1280  HIWORD(idCommand) != 0)
1281  {
1282  return E_NOTIMPL;
1283  }
1284 
1285  UINT CmdId = LOWORD(idCommand);
1286 
1287  if (m_pDynamicEntries && CmdId >= m_iIdSHEFirst && CmdId < m_iIdSHELast)
1288  {
1289  idCommand -= m_iIdSHEFirst;
1290  PDynamicShellEntry pEntry = GetDynamicEntry(idCommand);
1291  if (!pEntry)
1292  return E_FAIL;
1293 
1294  idCommand -= pEntry->iIdCmdFirst;
1295  return pEntry->pCM->GetCommandString(idCommand,
1296  uFlags,
1297  lpReserved,
1298  lpszName,
1299  uMaxNameLen);
1300  }
1301 
1302  if (m_pStaticEntries && CmdId >= m_iIdSCMFirst && CmdId < m_iIdSCMLast)
1303  {
1304  /* Validation just returns S_OK on a match. The id exists. */
1305  if (uFlags == GCS_VALIDATEA || uFlags == GCS_VALIDATEW)
1306  return S_OK;
1307 
1308  CmdId -= m_iIdSCMFirst;
1309 
1311  while (pEntry && (CmdId--) > 0)
1312  pEntry = pEntry->pNext;
1313 
1314  if (!pEntry)
1315  return E_INVALIDARG;
1316 
1317  if (uFlags == GCS_VERBW)
1318  return StringCchCopyW((LPWSTR)lpszName, uMaxNameLen, pEntry->szVerb);
1319 
1320  if (uFlags == GCS_VERBA)
1321  {
1322  if (SHUnicodeToAnsi(pEntry->szVerb, lpszName, uMaxNameLen))
1323  return S_OK;
1324  }
1325 
1326  return E_INVALIDARG;
1327  }
1328 
1329  //FIXME: Should we handle callbacks here?
1330  if (m_iIdDfltFirst != m_iIdDfltLast && CmdId >= m_iIdDfltFirst && CmdId < m_iIdDfltLast)
1331  {
1332  CmdId -= m_iIdDfltFirst;
1333  /* See the definitions of IDM_CUT and co to see how this works */
1334  CmdId += 0x7000;
1335  }
1336 
1337  /* Loop looking for a matching Id */
1338  for (UINT i = 0; i < _countof(g_StaticInvokeCmdMap); i++)
1339  {
1340  if (g_StaticInvokeCmdMap[i].IntVerb == CmdId)
1341  {
1342  /* Validation just returns S_OK on a match */
1343  if (uFlags == GCS_VALIDATEA || uFlags == GCS_VALIDATEW)
1344  return S_OK;
1345 
1346  /* Return a copy of the ANSI verb */
1347  if (uFlags == GCS_VERBA)
1348  return StringCchCopyA(lpszName, uMaxNameLen, g_StaticInvokeCmdMap[i].szStringVerb);
1349 
1350  /* Convert the ANSI verb to unicode and return that */
1351  if (uFlags == GCS_VERBW)
1352  {
1353  if (SHAnsiToUnicode(g_StaticInvokeCmdMap[i].szStringVerb, (LPWSTR)lpszName, uMaxNameLen))
1354  return S_OK;
1355  }
1356  }
1357  }
1358 
1359  return E_INVALIDARG;
1360 }
1361 
1362 HRESULT
1363 WINAPI
1365  UINT uMsg,
1366  WPARAM wParam,
1367  LPARAM lParam)
1368 {
1369  /* FIXME: Should we implement this as well? */
1370  return S_OK;
1371 }
1372 
1374 {
1375  if (uMsg == WM_DRAWITEM)
1376  {
1377  DRAWITEMSTRUCT* pDrawStruct = reinterpret_cast<DRAWITEMSTRUCT*>(lParam);
1378  *CmdId = pDrawStruct->itemID;
1379  return S_OK;
1380  }
1381  else if (uMsg == WM_MEASUREITEM)
1382  {
1383  MEASUREITEMSTRUCT* pMeasureStruct = reinterpret_cast<MEASUREITEMSTRUCT*>(lParam);
1384  *CmdId = pMeasureStruct->itemID;
1385  return S_OK;
1386  }
1387 
1388  return E_FAIL;
1389 }
1390 
1392 {
1393  if (uMsg == WM_DRAWITEM)
1394  {
1395  DRAWITEMSTRUCT* pDrawStruct = reinterpret_cast<DRAWITEMSTRUCT*>(lParam);
1396  pDrawStruct->itemID = CmdId;
1397  return S_OK;
1398  }
1399  else if (uMsg == WM_MEASUREITEM)
1400  {
1401  MEASUREITEMSTRUCT* pMeasureStruct = reinterpret_cast<MEASUREITEMSTRUCT*>(lParam);
1402  pMeasureStruct->itemID = CmdId;
1403  return S_OK;
1404  }
1405 
1406  return E_FAIL;
1407 }
1408 
1409 HRESULT
1410 WINAPI
1412  UINT uMsg,
1413  WPARAM wParam,
1414  LPARAM lParam,
1415  LRESULT *plResult)
1416 {
1417  if (uMsg == WM_INITMENUPOPUP)
1418  {
1420  while (pEntry)
1421  {
1422  SHForwardContextMenuMsg(pEntry->pCM, uMsg, wParam, lParam, plResult, TRUE);
1423  pEntry = pEntry->pNext;
1424  }
1425  return S_OK;
1426  }
1427 
1428  UINT CmdId;
1429  HRESULT hr = SHGetMenuIdFromMenuMsg(uMsg, lParam, &CmdId);
1430  if (FAILED(hr))
1431  return S_FALSE;
1432 
1433  if (CmdId < m_iIdSHEFirst || CmdId >= m_iIdSHELast)
1434  return S_FALSE;
1435 
1436  CmdId -= m_iIdSHEFirst;
1437  PDynamicShellEntry pEntry = GetDynamicEntry(CmdId);
1438  if (pEntry)
1439  {
1440  SHSetMenuIdInMenuMsg(uMsg, lParam, CmdId - pEntry->iIdCmdFirst);
1441  SHForwardContextMenuMsg(pEntry->pCM, uMsg, wParam, lParam, plResult, TRUE);
1442  }
1443 
1444  return S_OK;
1445 }
1446 
1447 HRESULT
1448 WINAPI
1450 {
1451  m_site = pUnkSite;
1452  return S_OK;
1453 }
1454 
1455 HRESULT
1456 WINAPI
1458 {
1459  if (!m_site)
1460  return E_FAIL;
1461 
1462  return m_site->QueryInterface(riid, ppvSite);
1463 }
1464 
1465 static
1466 HRESULT
1468 {
1469  return ShellObjectCreatorInit<CDefaultContextMenu>(pdcm, lpfn, riid, ppv);
1470 }
1471 
1472 /*************************************************************************
1473  * SHCreateDefaultContextMenu [SHELL32.325] Vista API
1474  *
1475  */
1476 
1477 HRESULT
1478 WINAPI
1480 {
1481  HRESULT hr;
1482 
1483  if (!ppv)
1484  return E_INVALIDARG;
1485 
1487  if (FAILED_UNEXPECTEDLY(hr))
1488  return hr;
1489 
1490  return S_OK;
1491 }
1492 
1493 /*************************************************************************
1494  * CDefFolderMenu_Create2 [SHELL32.701]
1495  *
1496  */
1497 
1498 HRESULT
1499 WINAPI
1501  PCIDLIST_ABSOLUTE pidlFolder,
1502  HWND hwnd,
1503  UINT cidl,
1504  PCUITEMID_CHILD_ARRAY apidl,
1505  IShellFolder *psf,
1506  LPFNDFMCALLBACK lpfn,
1507  UINT nKeys,
1508  const HKEY *ahkeyClsKeys,
1509  IContextMenu **ppcm)
1510 {
1511  DEFCONTEXTMENU dcm;
1512  dcm.hwnd = hwnd;
1513  dcm.pcmcb = NULL;
1514  dcm.pidlFolder = pidlFolder;
1515  dcm.psf = psf;
1516  dcm.cidl = cidl;
1517  dcm.apidl = apidl;
1518  dcm.punkAssociationInfo = NULL;
1519  dcm.cKeys = nKeys;
1520  dcm.aKeys = ahkeyClsKeys;
1521 
1523  if (FAILED_UNEXPECTEDLY(hr))
1524  return hr;
1525 
1526  return S_OK;
1527 }
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:1723
virtual HRESULT STDMETHODCALLTYPE SetSite(IUnknown *pUnkSite)
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 TRUE
Definition: types.h:120
#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:420
#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:469
#define CFSTR_PREFERREDDROPEFFECT
Definition: shlobj.h:479
HRESULT hr
Definition: shlfolder.c:183
#define IDM_RENAME
Definition: shresdef.h:778
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
const HKEY * aKeys
Definition: shlobj.h:2348
#define InitFormatEtc(fe, cf, med)
Definition: editor.h:33
#define KEY_READ
Definition: nt_native.h:1023
#define WM_INITMENUPOPUP
Definition: winuser.h:1728
REFIID riid
Definition: precomp.h:44
UINT WINAPI RegisterClipboardFormatW(_In_ LPCWSTR)
#define _countof(array)
Definition: fontsub.cpp:30
#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:111
LPITEMIDLIST WINAPI ILCombine(LPCITEMIDLIST pidl1, LPCITEMIDLIST pidl2)
Definition: pidl.c:699
#define FCIDM_SHVIEW_OPEN
Definition: shresdef.h:765
const ITEMIDLIST UNALIGNED * LPCITEMIDLIST
Definition: shtypes.idl:42
IContextMenuCB * pcmcb
Definition: shlobj.h:2341
BOOL WINAPI SHGetPathFromIDListW(LPCITEMIDLIST pidl, LPWSTR pszPath)
Definition: pidl.c:1280
WINE_DEFAULT_DEBUG_CHANNEL(dmenu)
virtual HRESULT STDMETHODCALLTYPE GetSite(REFIID riid, void **ppvSite)
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:1642
struct _StaticShellEntry_ StaticShellEntry
#define MAKEINTRESOURCEA(i)
Definition: winuser.h:581
LPWSTR dwTypeData
Definition: winuser.h:3243
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:56
#define FCIDM_SHVIEW_PROPERTIES
Definition: shresdef.h:738
HRESULT WINAPI IUnknown_QueryService(IUnknown *, REFGUID, REFIID, LPVOID *)
Definition: ordinal.c:1448
WPARAM wParam
Definition: combotst.c:138
#define IDM_COPY
Definition: shresdef.h:774
#define IDS_RUNAS_VERB
Definition: shresdef.h:199
#define SEVERITY_SUCCESS
Definition: winerror.h:64
uint32_t ULONG_PTR
Definition: typedefs.h:63
struct _StaticShellEntry_ * PStaticShellEntry
#define FCIDM_SHVIEW_INSERTLINK
Definition: shresdef.h:743
_In_ PSID _Out_writes_to_opt_ cchName LPSTR _Inout_ LPDWORD cchName
Definition: winbase.h:2713
#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:2343
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
HINSTANCE shell32_hInstance
Definition: misc.cpp:82
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:741
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:1358
virtual HRESULT WINAPI QueryContextMenu(HMENU hMenu, UINT indexMenu, UINT idCmdFirst, UINT idCmdLast, UINT uFlags)
ULONG Release()
#define S_FALSE
Definition: winerror.h:2357
INT WINAPI SHUnicodeToAnsi(LPCWSTR lpSrcStr, LPSTR lpDstStr, INT iLen)
Definition: string.c:2749
#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:2235
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:777
#define FCIDM_SHVIEW_NEWFOLDER
Definition: shresdef.h:761
#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:403
#define FCIDM_SHVIEW_EXPLORE
Definition: shresdef.h:764
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:740
LONG HRESULT
Definition: typedefs.h:77
BOOL WINAPI DeleteMenu(_In_ HMENU, _In_ UINT, _In_ UINT)
UINT idCmdFirst
Definition: shlobj.h:1308
#define FAILED_UNEXPECTEDLY(hr)
Definition: shellutils.h:71
#define MAX_PATH
Definition: compat.h:26
#define WINAPI
Definition: msvc.h:8
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:2403
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:737
struct _DynamicShellEntry_ * pNext
_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:2359
#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
HMENU WINAPI GetSubMenu(_In_ HMENU, _In_ int)
HRESULT DoCreateLink(LPCMINVOKECOMMANDINFO lpcmi)
void WINAPI SHChangeNotify(LONG wEventId, UINT uFlags, LPCVOID dwItem1, LPCVOID dwItem2)
Definition: changenotify.c:340
CComPtr< IUnknown > m_site
void _ILFreeaPidl(LPITEMIDLIST *apidl, UINT cidl)
Definition: pidl.c:2621
#define wcsicmp
Definition: string.h:1152
BOOL WINAPI DestroyMenu(_In_ HMENU)
#define SHCNF_PATHW
Definition: shlobj.h:1755
#define FCIDM_SHVIEW_CREATELINK
Definition: shresdef.h:759
HRESULT DoCreateNewFolder(LPCMINVOKECOMMANDINFO lpici)
CComPtr< IShellFolder > m_psf
_In_ DWORD _Out_ _In_ WORD wFlags
Definition: wincon.h:519
#define ERR(fmt,...)
Definition: debug.h:109
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:59
#define SW_SHOWNORMAL
Definition: winuser.h:764
virtual HRESULT WINAPI HandleMenuMsg(UINT uMsg, WPARAM wParam, LPARAM lParam)
#define LoadMenu
Definition: winuser.h:5718
CComPtr< IDataObject > m_pDataObj
#define FCIDM_SHVIEW_RENAME
Definition: shresdef.h:758
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:773
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:246
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:114
CComPtr< IContextMenuCB > m_pmcb
HRESULT LoadDynamicContextMenuHandler(HKEY hKey, const CLSID *pclsid)
IUnknown * punkAssociationInfo
Definition: shlobj.h:2346
BOOL WINAPI PathYetAnotherMakeUniqueName(LPWSTR buffer, LPCWSTR path, LPCWSTR shortname, LPCWSTR longname)
Definition: shellpath.c:320
#define FCIDM_SHVIEW_CUT
Definition: shresdef.h:739
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:776
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
DWORD WINAPI SHAnsiToUnicode(LPCSTR lpSrcStr, LPWSTR lpDstStr, int iLen)
Definition: string.c:2625
PStaticShellEntry m_pStaticEntries
return STATUS_SUCCESS
Definition: btrfs.c:2938
BOOL MapVerbToCmdId(PVOID Verb, PUINT idCmd, BOOL IsUnicode)
PCUITEMID_CHILD_ARRAY apidl
Definition: shlobj.h:2345
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:2342
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:402
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:775
static BOOL HasClipboardData()
PITEMID_CHILD * _ILCopyaPidl(PCUITEMID_CHILD_ARRAY apidlsrc, UINT cidl)
Definition: pidl.c:2638
unsigned int * PUINT
Definition: ndis.h:50
static IShellFolder IShellItem **static IBindCtx LPITEMIDLIST SFGAOF
Definition: ebrowser.c:83
#define SUCCEEDED(hr)
Definition: intsafe.h:57
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:1775
#define HKEY_LOCAL_MACHINE
Definition: winreg.h:12
struct _DynamicShellEntry_ DynamicShellEntry