ReactOS 0.4.17-dev-1017-ge38a44d
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#include <compat_undoc.h>
11
13
14// FIXME: 260 is correct, but should this be part of the SDK or just MAX_PATH?
15#define MAX_VERB 260
16
17static HRESULT
19{
20 WCHAR buf[42];
21 DWORD cb = sizeof(buf);
24}
25
27{
28 MENUITEMINFOW mii;
29 mii.cbSize = FIELD_OFFSET(MENUITEMINFOW, hbmpItem); // USER32 version agnostic
30 mii.fMask = MIIM_TYPE;
31 mii.fType = Flags;
32 return InsertMenuItemW(hMenu, Pos, TRUE, &mii);
33}
34
35static void DCMA_DestroyEntry(DCMENTRY &dcme)
36{
37 if (!dcme.pCM)
38 return;
40 dcme.pCM->Release();
41 dcme.pCM = NULL;
42}
43
45{
46 UINT i = 0;
47 for (DCMENTRY *p; (p = DCMA_GetEntry(hDCMA, i)) != NULL; ++i)
49 DSA_Destroy(hDCMA);
50}
51
53 _In_ HDCMA hDCMA,
54 _In_ HDCIA hDCIA,
55 _In_opt_ LPCITEMIDLIST pidlFolder,
57 _In_opt_ HKEY *pKeys,
58 _In_opt_ UINT nKeys,
59 _In_ QCMINFO *pQCMI,
60 _In_opt_ UINT fCmf,
61 _In_opt_ IUnknown *pUnkSite)
62{
63 UINT idCmdBase = pQCMI->idCmdFirst, idCmdFirst = idCmdBase;
64 UINT nOffset = 0;
65
66 // Insert in reverse order
67 for (int iCls = DCIA_GetCount(hDCIA) - 1; iCls >= 0; --iCls)
68 {
69 REFCLSID clsid = *DCIA_GetEntry(hDCIA, iCls);
70 if (fCmf & CMF_DEFAULTONLY)
71 {
72 WCHAR szKey[MAX_PATH];
73 wcscpy(szKey, L"CLSID\\");
74 StringFromGUID2(clsid, szKey + _countof(L"CLSID\\") - 1, CHARS_IN_GUID);
75 wcscpy(szKey + _countof(L"CLSID\\") - 1 + CHARS_IN_GUID - 1, L"\\shellex\\MayChangeDefaultMenu");
77 continue;
78 }
79
80 for (UINT iKey = 0; iKey < nKeys; ++iKey)
81 {
84 if (FAILED(hr))
85 break;
86 if (FAILED(hr = pInit->Initialize(pidlFolder, pDO, pKeys[iKey])))
87 continue;
88
89 IContextMenu *pCM;
90 if (FAILED(hr = pInit->QueryInterface(IID_PPV_ARG(IContextMenu, &pCM))))
91 break;
92 IUnknown_SetSite(pCM, pUnkSite);
93
94 hr = pCM->QueryContextMenu(pQCMI->hmenu, pQCMI->indexMenu + nOffset, idCmdFirst, pQCMI->idCmdLast, fCmf);
95 const UINT nCount = HRESULT_CODE(hr);
96 const UINT idThisFirst = idCmdFirst - idCmdBase;
97 DCMENTRY dcme = { pCM, idThisFirst, idThisFirst + nCount - 1 };
98 if (hr > 0)
99 {
100 idCmdFirst += nCount;
101 if (DSA_AppendItem(hDCMA, &dcme) >= 0)
102 {
103 if (nOffset == 0 && GetMenuDefaultItem(pQCMI->hmenu, TRUE, 0) == 0)
104 nOffset++; // Insert new items below the default
105 break;
106 }
107 }
108 DCMA_DestroyEntry(dcme);
109 }
110 }
111 return idCmdFirst;
112}
113
114HRESULT DCMA_InvokeCommand(HDCMA hDCMA, CMINVOKECOMMANDINFO *pICI)
115{
117 for (UINT i = 0;; ++i)
118 {
119 DCMENTRY *p = DCMA_GetEntry(hDCMA, i);
120 if (!p)
121 return hr;
122
123 UINT id = LOWORD(pICI->lpVerb);
124 if (!IS_INTRESOURCE(pICI->lpVerb))
125 {
126 if (SUCCEEDED(hr = p->pCM->InvokeCommand(pICI)))
127 return hr;
128 }
129 else if (id >= p->idCmdFirst && id <= p->idCmdLast)
130 {
131 CMINVOKECOMMANDINFOEX ici;
132 CopyMemory(&ici, pICI, min(sizeof(ici), pICI->cbSize));
133 ici.cbSize = min(sizeof(ici), pICI->cbSize);
134 ici.lpVerb = MAKEINTRESOURCEA(id - p->idCmdFirst);
135 ici.lpVerbW = (PWSTR)ici.lpVerb;
136 return p->pCM->InvokeCommand((CMINVOKECOMMANDINFO*)&ici);
137 }
138 }
139}
140
142{
148
149typedef struct _StaticShellEntry_
150{
154
155#define DCM_FCIDM_SHVIEW_OFFSET 0x7000 // Offset from the menu ids in the menu resource to FCIDM_SHVIEW_*
156
157//
158// verbs for InvokeCommandInfo
159//
160static const struct _StaticInvokeCommandMap_
161{
166{
167 // Note: Verbs from the registry should not be listed here
168 { CMDSTR_NEWFOLDERA, FCIDM_SHVIEW_NEWFOLDER, (SHORT)DFM_CMD_NEWFOLDER },
169 { "cut", FCIDM_SHVIEW_CUT, /* ? */ },
177
179{
180 for (SIZE_T i = 0; i < _countof(g_StaticInvokeCmdMap); ++i)
181 {
182 if (g_StaticInvokeCmdMap[i].IntVerb == CmdId && CmdId)
183 return g_StaticInvokeCmdMap[i].szStringVerb;
184 }
185 return NULL;
186}
187
189{
190 for (UINT i = 0; i < _countof(g_StaticInvokeCmdMap); ++i)
191 {
192 if (!lstrcmpiA(g_StaticInvokeCmdMap[i].szStringVerb, verba))
193 return (int)g_StaticInvokeCmdMap[i].DfmCmd;
194 }
195 return 0;
196}
197
198static HRESULT
199MapVerbToCmdId(PVOID Verb, BOOL IsUnicode, IContextMenu *pCM, UINT idFirst, UINT idLast)
200{
201 const UINT gcs = IsUnicode ? GCS_VERBW : GCS_VERBA;
202 for (UINT id = idFirst; id <= idLast; ++id)
203 {
205 *buf = UNICODE_NULL;
206 HRESULT hr = pCM->GetCommandString(id, gcs, NULL, (LPSTR)buf, _countof(buf));
207 if (FAILED(hr) || !*buf)
208 continue;
209 else if (IsUnicode && !_wcsicmp((LPWSTR)Verb, buf))
210 return id;
211 else if (!IsUnicode && !lstrcmpiA((LPSTR)Verb, (LPSTR)buf))
212 return id;
213 }
215}
216
217static inline bool IsVerbListSeparator(WCHAR Ch)
218{
219 return Ch == L' ' || Ch == L','; // learn.microsoft.com/en-us/windows/win32/shell/context-menu-handlers
220}
221
223{
224 for (UINT index = 0; *List; ++index)
225 {
226 while (IsVerbListSeparator(*List))
227 List++;
229 while (*List && !IsVerbListSeparator(*List))
230 List++;
231 // "List > Start" to verify that the list item is non-empty to avoid the edge case where Verb is "" and the list contains ",,"
232 if (!_wcsnicmp(Verb, Start, List - Start) && List > Start)
233 return index;
234 }
235 return -1;
236}
237
239{
240 for (UINT i = 0; *List; ++i)
241 {
242 while (IsVerbListSeparator(*List))
243 List++;
245 while (*List && !IsVerbListSeparator(*List))
246 List++;
247 if (List > Start && i == Index)
249 }
251}
252
254{
255 static const struct { PCWSTR pszVerb; WORD iResId; } map[] =
256 {
257 // { L"open", IDS_OPEN_VERB }, These two have already been handled
258 // { L"explore", IDS_EXPLORE_VERB },
259 { L"edit", IDS_EDIT_VERB },
260 { L"print", IDS_PRINT_VERB },
261 { L"runas", IDS_RUNAS_VERB },
262 { L"openas", IDS_OPEN_VERB },
263 { L"find", IDS_FIND_VERB },
264 };
265 for (SIZE_T i = 0; i < _countof(map); ++i)
266 {
267 if (!_wcsicmp(pszVerb, map[i].pszVerb) &&
268 LoadStringW(shell32_hInstance, map[i].iResId, pszBuf, cchMax))
269 {
270 return S_OK;
271 }
272 }
273
274 // Try to make a friendly verb based on the verb subkey
275 if (pszVerb[0] < 127 && !StrChrW(pszVerb, '&') && SUCCEEDED(StringCchCopyW(pszBuf + 1, --cchMax, pszVerb)))
276 {
277 *pszBuf = L'&';
278 return S_OK; // This can be changed to S_FALSE if the caller needs to know we faked it
279 }
280 return E_FAIL;
281}
282
284 public CComObjectRootEx<CComMultiThreadModelNoCS>,
285 public IContextMenu3,
286 public IObjectWithSite,
287 public IServiceProvider
288{
289 private:
297 HKEY m_aKeys[16]; // This limit is documented for both the old API and for DEFCONTEXTMENU
301 UINT m_iIdQCMFirst; /* The first id passed to us in QueryContextMenu */
303 UINT m_iIdSHEFirst; /* first used id */
304 UINT m_iIdSHELast; /* last used id */
306 UINT m_iIdSCMFirst; /* first static used id */
307 UINT m_iIdSCMLast; /* last static used id */
308 UINT m_iIdCBFirst; /* first callback used id */
309 UINT m_iIdCBLast; /* last callback used id */
310 UINT m_iIdDfltFirst; /* first default part id */
311 UINT m_iIdDfltLast; /* last default part id */
312 HWND m_hwnd; /* window passed to callback */
314
317 void AddStaticEntry(const HKEY hkeyClass, const WCHAR *szVerb, UINT uFlags);
319 void TryPickDefault(HMENU hMenu, UINT idCmdFirst, UINT DfltOffset, UINT uFlags);
323 UINT AddShellExtensionsToMenu(HMENU hMenu, UINT* pIndexMenu, UINT idCmdFirst, UINT idCmdLast, UINT uFlags);
324 UINT AddStaticContextMenusToMenu(HMENU hMenu, UINT* IndexMenu, UINT iIdCmdFirst, UINT iIdCmdLast, UINT uFlags);
339 BOOL MapVerbToCmdId(PVOID Verb, PUINT idCmd, BOOL IsUnicode);
340
342 {
344 }
345
346 public:
350
351 // IContextMenu
352 STDMETHOD(QueryContextMenu)(HMENU hMenu, UINT indexMenu, UINT idCmdFirst, UINT idCmdLast, UINT uFlags) override;
354 STDMETHOD(GetCommandString)(UINT_PTR idCommand, UINT uFlags, UINT *lpReserved, LPSTR lpszName, UINT uMaxNameLen) override;
355
356 // IContextMenu2
358
359 // IContextMenu3
360 STDMETHOD(HandleMenuMsg2)(UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT *plResult) override;
361
362 // IObjectWithSite
363 STDMETHOD(SetSite)(IUnknown *pUnkSite) override;
364 STDMETHOD(GetSite)(REFIID riid, void **ppvSite) override;
365
366 // IServiceProvider
368 {
369 return IUnknown_QueryService(m_site, svc, riid, ppv);
370 }
371
373 COM_INTERFACE_ENTRY_IID(IID_IContextMenu, IContextMenu)
374 COM_INTERFACE_ENTRY_IID(IID_IContextMenu2, IContextMenu2)
375 COM_INTERFACE_ENTRY_IID(IID_IContextMenu3, IContextMenu3)
377 COM_INTERFACE_ENTRY_IID(IID_IServiceProvider, IServiceProvider)
379};
380
382 m_psf(NULL),
383 m_pmcb(NULL),
384 m_pfnmcb(NULL),
385 m_cidl(0),
386 m_apidl(NULL),
387 m_pDataObj(NULL),
388 m_cKeys(0),
389 m_pidlFolder(NULL),
390 m_bGroupPolicyActive(0),
391 m_iIdQCMFirst(0),
392 m_iIdSHEFirst(0),
393 m_iIdSHELast(0),
394 m_iIdSCMFirst(0),
395 m_iIdSCMLast(0),
396 m_iIdCBFirst(0),
397 m_iIdCBLast(0),
398 m_iIdDfltFirst(0),
399 m_iIdDfltLast(0),
400 m_hwnd(NULL)
401{
403}
404
406{
407 for (POSITION it = m_DynamicEntries.GetHeadPosition(); it != NULL;)
408 {
409 const DynamicShellEntry& info = m_DynamicEntries.GetNext(it);
410 IUnknown_SetSite(info.pCM.p, NULL);
411 }
412 m_DynamicEntries.RemoveAll();
413 m_StaticEntries.RemoveAll();
414
415 for (UINT i = 0; i < m_cKeys; i++)
417
418 if (m_pidlFolder)
420 _ILFreeaPidl(const_cast<PITEMID_CHILD *>(m_apidl), m_cidl);
421}
422
424{
425 TRACE("cidl %u\n", pdcm->cidl);
426
427 HRESULT hr = S_OK;
428 if (!pdcm->pcmcb && !lpfn)
429 {
430 ERR("CDefaultContextMenu needs a callback!\n");
431 return E_INVALIDARG;
432 }
433
434 m_cidl = pdcm->cidl;
436 if (m_cidl && !m_apidl)
437 return E_OUTOFMEMORY;
438 m_psf = pdcm->psf;
439 m_pmcb = pdcm->pcmcb;
440 m_pfnmcb = lpfn;
441 m_hwnd = pdcm->hwnd;
442
443 for (UINT i = 0; i < pdcm->cKeys; ++i)
444 {
445 if (i >= _countof(m_aKeys))
447 else if ((m_aKeys[i] = SHRegDuplicateHKey(pdcm->aKeys[i])) != NULL)
448 m_cKeys++;
449 else
451 }
452
453 m_psf->GetUIObjectOf(pdcm->hwnd, m_cidl, m_apidl, IID_NULL_PPV_ARG(IDataObject, &m_pDataObj));
454
455 if (pdcm->pidlFolder)
456 {
458 }
459 else
460 {
462 if (SUCCEEDED(m_psf->QueryInterface(IID_PPV_ARG(IPersistFolder2, &pf))))
463 {
464 if (FAILED(pf->GetCurFolder(&m_pidlFolder)))
465 ERR("GetCurFolder failed\n");
466 }
467 TRACE("pidlFolder %p\n", m_pidlFolder);
468 }
469
470 return hr;
471}
472
474{
475 if (m_pmcb)
476 {
477 return m_pmcb->CallBack(m_psf, m_hwnd, m_pDataObj, uMsg, wParam, (LPARAM)lParam);
478 }
479 else if(m_pfnmcb)
480 {
482 }
483
484 return E_FAIL;
485}
486
487void CDefaultContextMenu::AddStaticEntry(const HKEY hkeyClass, const WCHAR *szVerb, UINT uFlags)
488{
489 POSITION it = m_StaticEntries.GetHeadPosition();
490 while (it != NULL)
491 {
492 const StaticShellEntry& info = m_StaticEntries.GetNext(it);
493 if (info.Verb.CompareNoCase(szVerb) == 0)
494 {
495 /* entry already exists */
496 return;
497 }
498 }
499
500 TRACE("adding verb %s\n", debugstr_w(szVerb));
501
502 if (!_wcsicmp(szVerb, L"open") && !(uFlags & CMF_NODEFAULT))
503 {
504 /* open verb is always inserted in front */
505 m_StaticEntries.AddHead({ szVerb, hkeyClass });
506 }
507 else
508 {
509 m_StaticEntries.AddTail({ szVerb, hkeyClass });
510 }
511}
512
514{
515 WCHAR wszName[VERBKEY_CCHMAX];
516 DWORD cchName, dwIndex = 0;
517 HKEY hShellKey;
518
519 LRESULT lres = RegOpenKeyExW(hKey, L"shell", 0, KEY_READ, &hShellKey);
520 if (lres != STATUS_SUCCESS)
521 return;
522
523 if (!*m_DefVerbs)
524 {
525 DWORD cb = sizeof(m_DefVerbs);
527 }
528
529 while(TRUE)
530 {
531 cchName = _countof(wszName);
532 if (RegEnumKeyExW(hShellKey, dwIndex++, wszName, &cchName, NULL, NULL, NULL, NULL) != ERROR_SUCCESS)
533 break;
534
535 AddStaticEntry(hKey, wszName, uFlags);
536 }
537
538 RegCloseKey(hShellKey);
539}
540
541static
542BOOL
544{
545 BOOL bRet = FALSE;
546 CComPtr<IDataObject> pDataObj;
547
548 if (SUCCEEDED(OleGetClipboard(&pDataObj)))
549 {
550 FORMATETC formatetc;
551
552 TRACE("pDataObj=%p\n", pDataObj.p);
553
554 /* Set the FORMATETC structure*/
555 InitFormatEtc(formatetc, RegisterClipboardFormatW(CFSTR_SHELLIDLIST), TYMED_HGLOBAL);
556 bRet = SUCCEEDED(pDataObj->QueryGetData(&formatetc));
557 }
558
559 return bRet;
560}
561
562BOOL
564{
565 POSITION it = m_DynamicEntries.GetHeadPosition();
566 while (it != NULL)
567 {
568 const DynamicShellEntry& info = m_DynamicEntries.GetNext(it);
569 if (info.ClassID == clsid)
570 return TRUE;
571 }
572
573 return FALSE;
574}
575
578{
579 HRESULT hr;
580 TRACE("LoadDynamicContextMenuHandler entered with This %p hKey %p pclsid %s\n", this, hKey, wine_dbgstr_guid(&clsid));
581
583 return S_OK;
584
587 if (FAILED(hr))
588 {
589 ERR("SHCoCreateInstance(IContextMenu) failed.clsid %s hr 0x%x\n", wine_dbgstr_guid(&clsid), hr);
590 return hr;
591 }
592
593 CComPtr<IShellExtInit> pExtInit;
594 hr = pcm->QueryInterface(IID_PPV_ARG(IShellExtInit, &pExtInit));
595 if (FAILED(hr))
596 {
597 ERR("IContextMenu->QueryInterface(IShellExtInit) failed.clsid %s hr 0x%x\n", wine_dbgstr_guid(&clsid), hr);
598 return hr;
599 }
600
601 hr = pExtInit->Initialize(m_pDataObj ? NULL : m_pidlFolder, m_pDataObj, hKey);
602 if (FAILED(hr))
603 {
604 WARN("IShellExtInit::Initialize failed.clsid %s hr 0x%x\n", wine_dbgstr_guid(&clsid), hr);
605 return hr;
606 }
607
608 if (m_site)
610
611 m_DynamicEntries.AddTail({ 0, 0, clsid, pcm });
612
613 return S_OK;
614}
615
616BOOL
618{
619 WCHAR wszName[MAX_PATH], wszBuf[MAX_PATH], *pwszClsid;
621 HRESULT hr;
622 HKEY hKey;
623
624 if (RegOpenKeyExW(hRootKey, L"shellex\\ContextMenuHandlers", 0, KEY_READ, &hKey) != ERROR_SUCCESS)
625 {
626 TRACE("RegOpenKeyExW failed\n");
627 return FALSE;
628 }
629
630 DWORD dwIndex = 0;
631 while (TRUE)
632 {
633 cchName = _countof(wszName);
634 if (RegEnumKeyExW(hKey, dwIndex++, wszName, &cchName, NULL, NULL, NULL, NULL) != ERROR_SUCCESS)
635 break;
636
637 /* Key name or key value is CLSID */
638 CLSID clsid;
639 hr = CLSIDFromString(wszName, &clsid);
640 if (hr == S_OK)
641 pwszClsid = wszName;
642 else
643 {
644 DWORD cchBuf = _countof(wszBuf);
645 if (RegGetValueW(hKey, wszName, NULL, RRF_RT_REG_SZ, NULL, wszBuf, &cchBuf) == ERROR_SUCCESS)
646 hr = CLSIDFromString(wszBuf, &clsid);
647 pwszClsid = wszBuf;
648 }
649
650 if (FAILED(hr))
651 {
652 ERR("CLSIDFromString failed for clsid %S hr 0x%x\n", pwszClsid, hr);
653 continue;
654 }
655
657 {
659 L"Software\\Microsoft\\Windows\\CurrentVersion\\Shell Extensions\\Approved",
660 pwszClsid,
662 NULL,
663 NULL,
665 {
666 ERR("Shell extension %s not approved!\n", pwszClsid);
667 continue;
668 }
669 }
670
672 if (FAILED(hr))
673 WARN("Failed to get context menu entires from shell extension! clsid: %S\n", pwszClsid);
674 }
675
677 return TRUE;
678}
679
680UINT
682{
683 UINT cIds = 0;
684
685 if (m_DynamicEntries.IsEmpty())
686 return cIds;
687
688 POSITION it = m_DynamicEntries.GetHeadPosition();
689 while (it != NULL)
690 {
692
693 HRESULT hr = info.pCM->QueryContextMenu(hMenu, *pIndexMenu, idCmdFirst + cIds, idCmdLast, uFlags);
694 if (SUCCEEDED(hr))
695 {
696 info.iIdCmdFirst = cIds;
697 info.NumIds = HRESULT_CODE(hr);
698 (*pIndexMenu) += info.NumIds;
699
700 cIds += info.NumIds;
701 if (idCmdFirst + cIds >= idCmdLast)
702 break;
703 }
704 TRACE("pEntry hr %x contextmenu %p cmdfirst %x num ids %x\n", hr, info.pCM.p, info.iIdCmdFirst, info.NumIds);
705 }
706 return cIds;
707}
708
709UINT
711 HMENU hMenu,
712 UINT* pIndexMenu,
713 UINT iIdCmdFirst,
714 UINT iIdCmdLast,
715 UINT uFlags)
716{
718 MENUITEMINFOW mii = { sizeof(mii) };
719 WCHAR wszDispVerb[80]; // The limit on XP. If the friendly string is longer, it falls back to the verb key.
720 UINT fState, idVerbRes;
721 UINT cIds = 0, indexFirst = *pIndexMenu, indexDefault;
722 int iDefVerbIndex = -1;
723
725 mii.fType = MFT_STRING;
726
727 POSITION it = m_StaticEntries.GetHeadPosition();
728 bool first = true;
729 while (it != NULL)
730 {
732 BOOL forceFirstPos = FALSE;
733 bool hide = false;
734
735 fState = MFS_ENABLED;
736
737 /* set first entry as default */
738 if (first)
739 {
740 fState |= MFS_DEFAULT;
741 first = false;
742 }
743
744 if (info.Verb.CompareNoCase(L"open") == 0)
745 {
746 idVerbRes = IDS_OPEN_VERB;
747 fState |= MFS_DEFAULT; /* override default when open verb is found */
748 forceFirstPos++;
749 }
750 else if (info.Verb.CompareNoCase(L"explore") == 0)
751 {
752 idVerbRes = IDS_EXPLORE_VERB;
753 if (uFlags & CMF_EXPLORE)
754 {
755 fState |= MFS_DEFAULT;
756 forceFirstPos++;
757 }
758 }
759 else if (info.Verb.CompareNoCase(L"printto") == 0)
760 hide = true;
761 else
762 idVerbRes = 0;
763
764 /* By default use verb for menu item name */
765 mii.dwTypeData = (LPWSTR)info.Verb.GetString();
766
767 WCHAR wszKey[sizeof("shell\\") + MAX_VERB];
768 HRESULT hr = StringCbPrintfW(wszKey, sizeof(wszKey), L"shell\\%s", info.Verb.GetString());
770 hide = true;
771
772 UINT cmdFlags = 0;
773 HKEY hkVerb;
774 if (RegOpenKeyExW(info.hkClass, wszKey, 0, KEY_READ, &hkVerb) == ERROR_SUCCESS)
775 {
776 if (!(uFlags & CMF_OPTIMIZEFORINVOKE))
777 {
778 DWORD cbVerb = sizeof(wszDispVerb);
779 LONG res = RegLoadMUIStringW(hkVerb, L"MUIVerb", wszDispVerb, cbVerb, NULL, 0, NULL);
780 if (res || !*wszDispVerb)
781 res = RegLoadMUIStringW(hkVerb, NULL, wszDispVerb, cbVerb, NULL, 0, NULL);
782
783 if ((res == ERROR_SUCCESS && *wszDispVerb) ||
784 (idVerbRes && LoadStringW(shell32_hInstance, idVerbRes, wszDispVerb, _countof(wszDispVerb))) ||
785 SUCCEEDED(GetFriendlyVerb(info.Verb, wszDispVerb, _countof(wszDispVerb))))
786 {
787 mii.dwTypeData = wszDispVerb;
788 }
789 }
790 }
791 else
792 {
793 hkVerb = NULL;
794 }
795
796 if (hkVerb)
797 {
798 if (!hide && !(uFlags & CMF_EXTENDEDVERBS))
799 hide = RegValueExists(hkVerb, L"Extended");
800
801 if (!hide)
802 hide = RegValueExists(hkVerb, L"ProgrammaticAccessOnly");
803
804 if (!hide && !(uFlags & CMF_DISABLEDVERBS))
805 hide = RegValueExists(hkVerb, L"LegacyDisable");
806
807 if (DWORD dwRest = (hide ? 0 : RegGetDword(hkVerb, NULL, L"SuppressionPolicy", 0)))
808 hide = SHRestricted((RESTRICTIONS)dwRest);
809
810 if (RegValueExists(hkVerb, L"NeverDefault"))
811 fState &= ~MFS_DEFAULT;
812
813 if (RegValueExists(hkVerb, L"SeparatorBefore"))
814 cmdFlags |= ECF_SEPARATORBEFORE;
815 if (RegValueExists(hkVerb, L"SeparatorAfter"))
816 cmdFlags |= ECF_SEPARATORAFTER;
817
818 RegCloseKey(hkVerb);
819 }
820
821 if (((uFlags & CMF_NODEFAULT) && ntver >= _WIN32_WINNT_VISTA) ||
822 ((uFlags & CMF_DONOTPICKDEFAULT) && ntver >= _WIN32_WINNT_WIN7))
823 {
824 fState &= ~MFS_DEFAULT;
825 }
826
827 if (!hide)
828 {
829 if (cmdFlags & ECF_SEPARATORBEFORE)
830 {
831 if (InsertMenuItemAt(hMenu, *pIndexMenu, MF_SEPARATOR))
832 (*pIndexMenu)++;
833 }
834
835 UINT pos = *pIndexMenu;
836 int verbIndex = hkVerb ? FindVerbInDefaultVerbList(m_DefVerbs, info.Verb) : -1;
837 if (verbIndex >= 0)
838 {
839 if (verbIndex < iDefVerbIndex || iDefVerbIndex < 0)
840 {
841 iDefVerbIndex = verbIndex;
842 fState |= MFS_DEFAULT;
843 forceFirstPos = TRUE;
844 }
845 else
846 {
847 fState &= ~MFS_DEFAULT; // We have already set a better default
848 pos = indexDefault;
849 }
850 }
851 else if (iDefVerbIndex >= 0)
852 {
853 fState &= ~MFS_DEFAULT; // We have already set the default
854 if (forceFirstPos)
855 pos = indexDefault;
856 forceFirstPos = FALSE;
857 }
858
859 mii.fState = fState;
860 mii.wID = iIdCmdFirst + cIds;
861 if (InsertMenuItemW(hMenu, forceFirstPos ? indexFirst : pos, TRUE, &mii))
862 (*pIndexMenu)++;
863
864 if (cmdFlags & ECF_SEPARATORAFTER)
865 {
866 if (InsertMenuItemAt(hMenu, *pIndexMenu, MF_SEPARATOR))
867 (*pIndexMenu)++;
868 }
869
870 if (fState & MFS_DEFAULT)
871 indexDefault = *pIndexMenu; // This is where we want to insert "high priority" verbs
872 }
873 cIds++; // Always increment the id because it acts as the index into m_StaticEntries
874
875 if (mii.wID >= iIdCmdLast)
876 break;
877 }
878
879 return cIds;
880}
881
883 HMENU hMenu,
884 UINT indexMenu,
885 BOOL fByPosition,
886 UINT wID,
887 UINT fType,
888 LPCWSTR dwTypeData,
889 UINT fState)
890{
891 MENUITEMINFOW mii;
892 WCHAR wszText[100];
893
894 ZeroMemory(&mii, sizeof(mii));
895 mii.cbSize = sizeof(mii);
896 if (fType == MFT_SEPARATOR)
897 mii.fMask = MIIM_ID | MIIM_TYPE;
898 else if (fType == MFT_STRING)
899 {
901 if (IS_INTRESOURCE(dwTypeData))
902 {
903 if (LoadStringW(shell32_hInstance, LOWORD((ULONG_PTR)dwTypeData), wszText, _countof(wszText)))
904 mii.dwTypeData = wszText;
905 else
906 {
907 ERR("failed to load string %p\n", dwTypeData);
908 return FALSE;
909 }
910 }
911 else
912 mii.dwTypeData = (LPWSTR)dwTypeData;
913 mii.fState = fState;
914 }
915
916 mii.wID = wID;
917 mii.fType = fType;
918 return InsertMenuItemW(hMenu, indexMenu, fByPosition, &mii);
919}
920
921void
923{
924 // Are we allowed to pick a default?
925 if ((uFlags & CMF_NODEFAULT) ||
926 ((uFlags & CMF_DONOTPICKDEFAULT) && RosGetProcessEffectiveVersion() >= _WIN32_WINNT_WIN7))
927 {
928 return;
929 }
930
931 // Do we already have a default?
932 if ((int)GetMenuDefaultItem(hMenu, MF_BYPOSITION, 0) != -1)
933 return;
934
935 // Does the view want to pick one?
936 INT_PTR forceDfm = 0;
937 if (SUCCEEDED(_DoCallback(DFM_GETDEFSTATICID, 0, &forceDfm)) && forceDfm)
938 {
939 for (UINT i = 0; i < _countof(g_StaticInvokeCmdMap); ++i)
940 {
941 UINT menuItemId = g_StaticInvokeCmdMap[i].IntVerb + DfltOffset - DCM_FCIDM_SHVIEW_OFFSET;
942 if (g_StaticInvokeCmdMap[i].DfmCmd == forceDfm &&
943 SetMenuDefaultItem(hMenu, menuItemId, MF_BYCOMMAND))
944 {
945 return;
946 }
947 }
948 }
949
950 // Don't want to pick something like cut or delete as the default but
951 // a static or dynamic verb is a good default.
953 SetMenuDefaultItem(hMenu, idCmdFirst, MF_BYCOMMAND);
954}
955
957WINAPI
959 HMENU hMenu,
960 UINT IndexMenu,
961 UINT idCmdFirst,
962 UINT idCmdLast,
963 UINT uFlags)
964{
965 HRESULT hr;
966 UINT idCmdNext = m_iIdQCMFirst = idCmdFirst;
967 UINT cIds = 0;
968
969 TRACE("BuildShellItemContextMenu entered\n");
970
971 /* Load static verbs and shell extensions from registry */
972 for (UINT i = 0; i < m_cKeys && !(uFlags & CMF_NOVERBS); i++)
973 {
976 }
977
978 /* Add static context menu handlers */
979 cIds = AddStaticContextMenusToMenu(hMenu, &IndexMenu, idCmdFirst, idCmdLast, uFlags);
980 m_iIdSCMFirst = 0; // FIXME: This should be = idCmdFirst?
981 m_iIdSCMLast = cIds;
982 idCmdNext = idCmdFirst + cIds;
983
984 /* Add dynamic context menu handlers */
985 cIds += AddShellExtensionsToMenu(hMenu, &IndexMenu, idCmdNext, idCmdLast, uFlags);
987 m_iIdSHELast = cIds;
988 idCmdNext = idCmdFirst + cIds;
989 TRACE("SH_LoadContextMenuHandlers first %x last %x\n", m_iIdSHEFirst, m_iIdSHELast);
990
991 /* Now let the callback add its own items */
992 QCMINFO qcminfo = {hMenu, IndexMenu, idCmdNext, idCmdLast, NULL};
994 {
995 UINT added = qcminfo.idCmdFirst - idCmdNext;
996 cIds += added;
997 IndexMenu += added; // Note: This is incorrect, forgets about separators and causes CORE-18577. We should build the menu in reverse order like Windows...
999 m_iIdCBLast = cIds;
1000 idCmdNext = idCmdFirst + cIds;
1001 }
1002
1003 //TODO: DFM_MERGECONTEXTMENU_BOTTOM
1004
1005 UINT idDefaultOffset = 0;
1006 BOOL isBackgroundMenu = !m_cidl;
1007 if (!(uFlags & CMF_VERBSONLY) && !isBackgroundMenu)
1008 {
1009 /* Get the attributes of the items */
1010 SFGAOF rfg = SFGAO_BROWSABLE | SFGAO_CANCOPY | SFGAO_CANLINK | SFGAO_CANMOVE | SFGAO_CANDELETE | SFGAO_CANRENAME | SFGAO_HASPROPSHEET | SFGAO_FILESYSTEM | SFGAO_FOLDER;
1011 hr = m_psf->GetAttributesOf(m_cidl, m_apidl, &rfg);
1013 return MAKE_HRESULT(SEVERITY_SUCCESS, 0, cIds);
1014
1015 /* Add the default part of the menu */
1016 HMENU hmenuDefault = LoadMenuW(_AtlBaseModule.GetResourceInstance(), MAKEINTRESOURCEW(MENU_SHV_FILE));
1017
1018 /* Remove uneeded entries */
1019 if (!(rfg & SFGAO_CANMOVE))
1020 DeleteMenu(hmenuDefault, IDM_CUT, MF_BYCOMMAND);
1021 if (!(rfg & SFGAO_CANCOPY))
1022 DeleteMenu(hmenuDefault, IDM_COPY, MF_BYCOMMAND);
1023 if (!((rfg & SFGAO_FILESYSTEM) && HasClipboardData()))
1024 DeleteMenu(hmenuDefault, IDM_INSERT, MF_BYCOMMAND);
1025 if (!(rfg & SFGAO_CANLINK))
1026 DeleteMenu(hmenuDefault, IDM_CREATELINK, MF_BYCOMMAND);
1027 if (!(rfg & SFGAO_CANDELETE))
1028 DeleteMenu(hmenuDefault, IDM_DELETE, MF_BYCOMMAND);
1029 if (!(rfg & SFGAO_CANRENAME) || !(uFlags & CMF_CANRENAME))
1030 DeleteMenu(hmenuDefault, IDM_RENAME, MF_BYCOMMAND);
1031 if (!(rfg & SFGAO_HASPROPSHEET))
1032 DeleteMenu(hmenuDefault, IDM_PROPERTIES, MF_BYCOMMAND);
1033
1034 idDefaultOffset = idCmdNext;
1035 UINT idMax = Shell_MergeMenus(hMenu, GetSubMenu(hmenuDefault, 0), IndexMenu, idCmdNext, idCmdLast, 0);
1036 m_iIdDfltFirst = cIds;
1037 cIds += idMax - idCmdNext;
1038 m_iIdDfltLast = cIds;
1039
1040 DestroyMenu(hmenuDefault);
1041 }
1042
1043 TryPickDefault(hMenu, idCmdFirst, idDefaultOffset, uFlags);
1044
1045 // TODO: DFM_MERGECONTEXTMENU_TOP
1046
1047 // TODO: Remove duplicate verbs. This will be easier when the static items handling
1048 // has been moved to CLSID_ShellFileDefExt so we only have to deal with ShellEx.
1049 // This is a Windows XP+ feature. On an unknown file type, Windows 2000 will
1050 // display both "Open" (openas from Unknown) and "Open with..." (openas from *).
1051
1052 return MAKE_HRESULT(SEVERITY_SUCCESS, 0, cIds);
1053}
1054
1056{
1058 if (hr == S_OK)
1059 return hr;
1060
1062 hr = OleGetClipboard(&pda);
1064 return hr;
1065
1066 FORMATETC formatetc2;
1067 STGMEDIUM medium2;
1069
1070 DWORD dwKey= 0;
1071
1072 if (SUCCEEDED(pda->GetData(&formatetc2, &medium2)))
1073 {
1074 DWORD * pdwFlag = (DWORD*)GlobalLock(medium2.hGlobal);
1075 if (pdwFlag)
1076 {
1077 if (*pdwFlag == DROPEFFECT_COPY)
1078 dwKey = MK_CONTROL;
1079 else
1080 dwKey = MK_SHIFT;
1081 }
1082 else
1083 {
1084 ERR("No drop effect obtained\n");
1085 }
1086 GlobalUnlock(medium2.hGlobal);
1087 }
1088
1089 if (bLink)
1090 {
1091 dwKey = MK_CONTROL|MK_SHIFT;
1092 }
1093
1095 if (m_cidl)
1096 hr = m_psf->GetUIObjectOf(NULL, 1, &m_apidl[0], IID_NULL_PPV_ARG(IDropTarget, &pdrop));
1097 else
1098 hr = m_psf->CreateViewObject(NULL, IID_PPV_ARG(IDropTarget, &pdrop));
1099
1101 return hr;
1102
1103 SHSimulateDrop(pdrop, pda, dwKey, NULL, NULL);
1104
1105 TRACE("CP result %x\n", hr);
1106 return S_OK;
1107}
1108
1110{
1112 if (hr == S_OK)
1113 return hr;
1114
1115 if (!m_cidl || !m_pDataObj)
1116 return E_FAIL;
1117
1119 hr = m_psf->CreateViewObject(NULL, IID_PPV_ARG(IDropTarget, &pDT));
1121 return hr;
1122
1124
1125 return S_OK;
1126}
1127
1129{
1131 if (hr == S_OK)
1132 return hr;
1133
1134 if (!m_cidl || !m_pDataObj)
1135 return E_FAIL;
1136
1140 return hr;
1141
1142 DWORD grfKeyState = (lpcmi->fMask & CMIC_MASK_SHIFT_DOWN) ? MK_SHIFT : 0;
1143 SHSimulateDrop(pDT, m_pDataObj, grfKeyState, NULL, NULL);
1144
1145 return S_OK;
1146}
1147
1149{
1150 if (!m_cidl || !m_pDataObj)
1151 return E_FAIL;
1152
1154 if (hr == S_OK)
1155 return hr;
1156
1157 FORMATETC formatetc;
1159 STGMEDIUM medium = {0};
1160 medium.tymed = TYMED_HGLOBAL;
1161 medium.hGlobal = GlobalAlloc(GHND, sizeof(DWORD));
1162 DWORD* pdwFlag = (DWORD*)GlobalLock(medium.hGlobal);
1163 if (pdwFlag)
1164 *pdwFlag = bCopy ? DROPEFFECT_COPY : DROPEFFECT_MOVE;
1165 GlobalUnlock(medium.hGlobal);
1166 m_pDataObj->SetData(&formatetc, &medium, TRUE);
1167
1169 if (SUCCEEDED(IUnknown_QueryService(m_site, SID_SFolderView, IID_PPV_ARG(IShellFolderView, &psfv))))
1170 psfv->SetPoints(m_pDataObj);
1171
1174 return hr;
1175
1176 if (psfv)
1177 psfv->SetClipboard(!bCopy);
1178 return S_OK;
1179}
1180
1182{
1184 HRESULT hr;
1185
1187 if (hr == S_OK)
1188 return hr;
1189
1190 if (!m_site || !m_cidl)
1191 return E_FAIL;
1192
1193 /* Get a pointer to the shell browser */
1196 return hr;
1197
1199 hr = psb->QueryActiveShellView(&lpSV);
1201 return hr;
1202
1203 SVSIF selFlags = SVSI_DESELECTOTHERS | SVSI_EDIT | SVSI_ENSUREVISIBLE | SVSI_FOCUSED | SVSI_SELECT;
1204 hr = lpSV->SelectItem(m_apidl[0], selFlags);
1206 return hr;
1207
1208 return S_OK;
1209}
1210
1211HRESULT
1214{
1216
1217 // We are asked to run the default property sheet
1218 if (hr == S_FALSE)
1219 {
1221 }
1222
1223 return hr;
1224}
1225
1226HRESULT
1228{
1229 ERR("TODO: Undo\n");
1230 return E_NOTIMPL;
1231}
1232
1233// This code is taken from CNewMenu and should be shared between the 2 classes
1234HRESULT
1237{
1238 WCHAR wszPath[MAX_PATH];
1239 WCHAR wszName[MAX_PATH];
1240 WCHAR wszNewFolder[25];
1241 HRESULT hr;
1242
1243 /* Get folder path */
1246 return hr;
1247
1248 if (!LoadStringW(shell32_hInstance, IDS_NEWFOLDER, wszNewFolder, _countof(wszNewFolder)))
1249 return E_FAIL;
1250
1251 /* Create the name of the new directory */
1252 if (!PathYetAnotherMakeUniqueName(wszName, wszPath, NULL, wszNewFolder))
1253 return E_FAIL;
1254
1255 /* Create the new directory and show the appropriate dialog in case of error */
1256 if (SHCreateDirectory(lpici->hwnd, wszName) != ERROR_SUCCESS)
1257 return E_FAIL;
1258
1259 /* Show and select the new item in the def view */
1260 LPITEMIDLIST pidl;
1261 PITEMID_CHILD pidlNewItem;
1263
1264 /* Notify the view object about the new item */
1266
1267 if (!m_site)
1268 return S_OK;
1269
1270 /* Get a pointer to the shell view */
1271 hr = IUnknown_QueryService(m_site, SID_SFolderView, IID_PPV_ARG(IShellView, &psv));
1273 return S_OK;
1274
1275 /* Attempt to get the pidl of the new item */
1276 hr = SHILCreateFromPathW(wszName, &pidl, NULL);
1278 return hr;
1279
1280 pidlNewItem = ILFindLastID(pidl);
1281
1282 hr = psv->SelectItem(pidlNewItem, SVSI_DESELECTOTHERS | SVSI_EDIT | SVSI_ENSUREVISIBLE |
1283 SVSI_FOCUSED | SVSI_SELECT);
1285 return hr;
1286
1287 SHFree(pidl);
1288
1289 return S_OK;
1290}
1291
1293{
1294 POSITION it = m_DynamicEntries.GetHeadPosition();
1295 while (it != NULL)
1296 {
1298
1299 if (idCmd >= info.iIdCmdFirst + info.NumIds)
1300 continue;
1301
1302 if (idCmd < info.iIdCmdFirst || idCmd > info.iIdCmdFirst + info.NumIds)
1303 return NULL;
1304
1305 return &info;
1306 }
1307
1308 return NULL;
1309}
1310
1311BOOL
1313{
1314 WCHAR UnicodeStr[MAX_VERB];
1315 UINT i;
1316
1317 /* Loop through all the static verbs looking for a match */
1318 for (i = 0; i < _countof(g_StaticInvokeCmdMap); i++)
1319 {
1320 if (IsUnicode)
1321 {
1322 SHAnsiToUnicode(g_StaticInvokeCmdMap[i].szStringVerb, UnicodeStr, MAX_VERB);
1323 if (!_wcsicmp(UnicodeStr, (LPWSTR)Verb))
1324 {
1325 *idCmd = g_StaticInvokeCmdMap[i].IntVerb;
1326 return TRUE;
1327 }
1328 }
1329 else
1330 {
1331 if (!_stricmp(g_StaticInvokeCmdMap[i].szStringVerb, (LPSTR)Verb))
1332 {
1333 *idCmd = g_StaticInvokeCmdMap[i].IntVerb;
1334 return TRUE;
1335 }
1336 }
1337 }
1338
1339 POSITION it;
1340 HRESULT hr = S_OK;
1341 // Check the registry verbs
1342 if (!IsUnicode)
1343 hr = StringCchPrintfW(UnicodeStr, _countof(UnicodeStr), L"%hs", Verb);
1344 for (i = 0, it = m_StaticEntries.GetHeadPosition(); it && SUCCEEDED(hr); ++i)
1345 {
1346 StaticShellEntry& entry = m_StaticEntries.GetNext(it);
1347 if (!_wcsicmp(entry.Verb, UnicodeStr))
1348 {
1349 *idCmd = m_iIdSCMFirst + i;
1350 return TRUE;
1351 }
1352 }
1353
1354 for (it = m_DynamicEntries.GetHeadPosition(); it != NULL;)
1355 {
1357 if (!entry.NumIds)
1358 continue;
1359 HRESULT hr = ::MapVerbToCmdId(Verb, IsUnicode, entry.pCM, 0, entry.NumIds - 1);
1360 if (SUCCEEDED(hr))
1361 {
1362 *idCmd = m_iIdSHEFirst + entry.iIdCmdFirst + hr;
1363 return TRUE;
1364 }
1365 }
1366
1367 // learn.microsoft.com/en-us/windows/win32/shell/dfm-mapcommandname
1368 PWSTR pszVerbW = (PWSTR)Verb;
1369 if (!IsUnicode)
1370 {
1371 SHAnsiToUnicode((PCSTR)Verb, UnicodeStr, _countof(UnicodeStr));
1372 pszVerbW = UnicodeStr;
1373 }
1374 i = -1;
1375 if (*pszVerbW && SUCCEEDED(_DoCallback(DFM_MAPCOMMANDNAME, (WPARAM)&i, pszVerbW)) && !HIWORD(i))
1376 {
1377 *idCmd = m_iIdCBFirst + i;
1378 return TRUE;
1379 }
1380
1381 return FALSE; // Note: Even if the verb is "open", we must fail if we can't find a handler
1382}
1383
1384HRESULT
1387{
1388 TRACE("verb %p first %x last %x\n", lpcmi->lpVerb, m_iIdSHEFirst, m_iIdSHELast);
1389
1390 UINT idCmd = LOWORD(lpcmi->lpVerb);
1392 if (!pEntry)
1393 return E_FAIL;
1394
1395 /* invoke the dynamic context menu */
1396 lpcmi->lpVerb = MAKEINTRESOURCEA(idCmd - pEntry->iIdCmdFirst);
1397 return pEntry->pCM->InvokeCommand((LPCMINVOKECOMMANDINFO)lpcmi);
1398}
1399
1400DWORD
1402{
1404 HWND hwndTree;
1405 LPCWSTR FlagsName;
1406 WCHAR wszKey[sizeof("shell\\") + MAX_VERB];
1407 HRESULT hr;
1408
1409 if (!m_site)
1410 return 0;
1411
1412 /* Get a pointer to the shell browser */
1414 if (FAILED(hr))
1415 return 0;
1416
1417 /* See if we are in Explore or Browse mode. If the browser's tree is present, we are in Explore mode.*/
1418 if (SUCCEEDED(psb->GetControlWindow(FCW_TREE, &hwndTree)) && hwndTree)
1419 FlagsName = L"ExplorerFlags";
1420 else
1421 FlagsName = L"BrowserFlags";
1422
1424 if (SUCCEEDED(psb->QueryInterface(IID_PPV_ARG(ICommDlgBrowser, &pcdb))))
1425 {
1426 if (LOBYTE(GetVersion()) < 6 || FlagsName[0] == 'E')
1427 return 0; // Don't browse in-place
1428 }
1429
1430 /* Try to get the flag from the verb */
1431 hr = StringCbPrintfW(wszKey, sizeof(wszKey), L"shell\\%s", pEntry->Verb.GetString());
1433 return 0;
1434 return RegGetDword(pEntry->hkClass, wszKey, FlagsName, 0);
1435}
1436
1437HRESULT
1440{
1442 HRESULT hr;
1443
1444 if (!m_site)
1445 return E_FAIL;
1446
1447 /* Get a pointer to the shell browser */
1449 if (FAILED(hr))
1450 return hr;
1451
1452 PIDLIST_ABSOLUTE pidl;
1453 hr = SHILCombine(m_pidlFolder, pidlChild, &pidl);
1455 return hr;
1456
1457 hr = psb->BrowseObject(pidl, wFlags & ~SBSP_RELATIVE);
1458 ILFree(pidl);
1459 return hr;
1460}
1461
1462HRESULT
1464{
1465 const BOOL unicode = IsUnicode(*lpcmi);
1466
1467 LPITEMIDLIST pidlFull = ILCombine(m_pidlFolder, pidl);
1468 if (pidlFull == NULL)
1469 {
1470 return E_FAIL;
1471 }
1472
1473 WCHAR wszPath[MAX_PATH];
1474 BOOL bHasPath = SHGetPathFromIDListW(pidlFull, wszPath);
1475
1476 WCHAR wszDir[MAX_PATH];
1477
1478 SHELLEXECUTEINFOW sei = { sizeof(sei) };
1479 sei.fMask = SEE_MASK_CLASSKEY | SEE_MASK_IDLIST | (CmicFlagsToSeeFlags(lpcmi->fMask) & ~SEE_MASK_INVOKEIDLIST);
1480 sei.hwnd = lpcmi->hwnd;
1481 sei.nShow = lpcmi->nShow;
1482 sei.lpVerb = pEntry->Verb;
1483 sei.lpIDList = pidlFull;
1484 sei.hkeyClass = pEntry->hkClass;
1485 sei.dwHotKey = lpcmi->dwHotKey;
1486 sei.hIcon = lpcmi->hIcon;
1487 sei.lpDirectory = wszDir;
1488
1489 if (unicode && !StrIsNullOrEmpty(lpcmi->lpDirectoryW))
1490 {
1491 sei.lpDirectory = lpcmi->lpDirectoryW;
1492 }
1493 else if (bHasPath)
1494 {
1495 wcscpy(wszDir, wszPath);
1496 PathRemoveFileSpec(wszDir);
1497 }
1498 else
1499 {
1500 if (!SHGetPathFromIDListW(m_pidlFolder, wszDir))
1501 *wszDir = UNICODE_NULL;
1502 }
1503
1504 if (bHasPath)
1505 sei.lpFile = wszPath;
1506
1507 CComHeapPtr<WCHAR> pszParamsW;
1508 if (unicode && !StrIsNullOrEmpty(lpcmi->lpParametersW))
1509 sei.lpParameters = lpcmi->lpParametersW;
1510 else if (!StrIsNullOrEmpty(lpcmi->lpParameters) && __SHCloneStrAtoW(&pszParamsW, lpcmi->lpParameters))
1511 sei.lpParameters = pszParamsW;
1512
1513 if (!sei.lpClass && (lpcmi->fMask & (CMIC_MASK_HASLINKNAME | CMIC_MASK_HASTITLE)) && unicode)
1514 sei.lpClass = lpcmi->lpTitleW; // Forward .lnk path from CShellLink::DoOpen (for consrv STARTF_TITLEISLINKNAME)
1515
1517 ILFree(pidlFull);
1518 return hr;
1519}
1520
1521HRESULT
1524{
1525 INT iCmd = LOWORD(lpcmi->lpVerb);
1526 HRESULT hr;
1527 UINT i;
1528
1529 POSITION it = m_StaticEntries.FindIndex(iCmd);
1530
1531 if (it == NULL)
1533
1535
1536 CRegKey VerbKey;
1537 WCHAR VerbKeyPath[sizeof("shell\\") + MAX_VERB];
1538 hr = StringCbPrintfW(VerbKeyPath, sizeof(VerbKeyPath), L"shell\\%s", pEntry->Verb.GetString());
1539 if (SUCCEEDED(hr) && m_pDataObj &&
1540 VerbKey.Open(pEntry->hkClass, VerbKeyPath, KEY_READ) == ERROR_SUCCESS)
1541 {
1542 CLSID clsid;
1543
1544 DWORD KeyState = 0;
1545 if (lpcmi->fMask & CMIC_MASK_SHIFT_DOWN)
1546 KeyState |= MK_SHIFT;
1547 if (lpcmi->fMask & CMIC_MASK_CONTROL_DOWN)
1548 KeyState |= MK_CONTROL;
1549
1550 POINTL *pPtl = NULL;
1551 C_ASSERT(sizeof(POINT) == sizeof(POINTL));
1552 if (lpcmi->fMask & CMIC_MASK_PTINVOKE)
1553 pPtl = (POINTL*)&lpcmi->ptInvoke;
1554
1556 hr = SHELL_GetRegCLSID(VerbKey, L"command", L"DelegateExecute", clsid);
1557 if (SUCCEEDED(hr))
1558 hr = CoCreateInstance(clsid, NULL, CLSCTX_ALL, IID_PPV_ARG(IExecuteCommand, &pEC));
1559 if (SUCCEEDED(hr))
1560 {
1563 return InvokeIExecuteCommandWithDataObject(pEC, pEntry->Verb.GetString(), pPB, m_pDataObj,
1564 lpcmi, static_cast<IContextMenu*>(this));
1565 }
1566
1568 hr = SHELL_GetRegCLSID(VerbKey, L"DropTarget", L"CLSID", clsid);
1569 if (SUCCEEDED(hr))
1570 hr = CoCreateInstance(clsid, NULL, CLSCTX_ALL, IID_PPV_ARG(IDropTarget, &pDT));
1571 if (SUCCEEDED(hr))
1572 {
1573 CScopedSetObjectWithSite site(pDT, static_cast<IContextMenu*>(this));
1576 IUnknown_InitializeCommand(pDT, pEntry->Verb.GetString(), pPB);
1577 hr = SHSimulateDrop(pDT, m_pDataObj, KeyState, pPtl, NULL);
1578 return hr;
1579 }
1580 }
1581
1582 /* Get the browse flags to see if we need to browse */
1584
1585 for (i=0; i < m_cidl; i++)
1586 {
1587 /* Check if we need to browse */
1588 if (wFlags)
1589 {
1590 hr = TryToBrowse(lpcmi, m_apidl[i], wFlags);
1591 if (SUCCEEDED(hr))
1592 {
1593 /* In WinXP if we have browsed, we don't open any more folders.
1594 * In Win7 we browse to the first folder we find and
1595 * open new windows for each of the rest of the folders */
1597 if (ntver >= _WIN32_WINNT_VISTA)
1598 wFlags = 0; // FIXME: = SBSP_NEWBROWSER | (wFlags & ~SBSP_SAMEBROWSER);
1599 else
1600 i = m_cidl;
1601
1602 continue;
1603 }
1604 }
1605
1606 InvokePidl(lpcmi, m_apidl[i], pEntry);
1607 }
1608
1609 return S_OK;
1610}
1611
1612HRESULT
1614 LPCMINVOKECOMMANDINFOEX lpcmi, WPARAM CmdId)
1615{
1616 BOOL Unicode = IsUnicode(*lpcmi);
1617 WCHAR lParamBuf[MAX_PATH];
1618 LPARAM lParam = 0;
1619
1620 if (Unicode && lpcmi->lpParametersW)
1621 lParam = (LPARAM)lpcmi->lpParametersW;
1622 else if (lpcmi->lpParameters)
1623 lParam = SHAnsiToUnicode(lpcmi->lpParameters, lParamBuf, _countof(lParamBuf)) ? (LPARAM)lParamBuf : 0;
1624
1625 HRESULT hr;
1626#if 0 // TODO: Try DFM_INVOKECOMMANDEX first.
1627 DFMICS dfmics = { sizeof(DFMICS), lpcmi->fMask, lParam, m_iIdSCMFirst?, m_iIdDfltLast?, (LPCMINVOKECOMMANDINFO)lpcmi, m_site };
1628 hr = _DoCallback(DFM_INVOKECOMMANDEX, CmdId, &dfmics);
1629 if (hr == E_NOTIMPL)
1630#endif
1631 hr = _DoCallback(DFM_INVOKECOMMAND, CmdId, (void*)lParam);
1632 return hr;
1633}
1634
1635HRESULT
1636WINAPI
1639{
1640 CMINVOKECOMMANDINFOEX LocalInvokeInfo = {};
1642 UINT CmdId;
1643
1644 /* Take a local copy of the fixed members of the
1645 struct as we might need to modify the verb */
1646 memcpy(&LocalInvokeInfo, lpcmi, min(sizeof(LocalInvokeInfo), lpcmi->cbSize));
1647
1648 /* Check if this is a string verb */
1649 if (!IS_INTRESOURCE(LocalInvokeInfo.lpVerb))
1650 {
1651 /* Get the ID which corresponds to this verb, and update our local copy */
1652 if (MapVerbToCmdId((LPVOID)LocalInvokeInfo.lpVerb, &CmdId, FALSE))
1653 LocalInvokeInfo.lpVerb = MAKEINTRESOURCEA(CmdId);
1654 else
1655 return GetNoAssocError();
1656 }
1657 CmdId = LOWORD(LocalInvokeInfo.lpVerb);
1658
1659 if (!m_DynamicEntries.IsEmpty() && CmdId >= m_iIdSHEFirst && CmdId < m_iIdSHELast)
1660 {
1661 LocalInvokeInfo.lpVerb -= m_iIdSHEFirst;
1662 Result = InvokeShellExt(&LocalInvokeInfo);
1663 return Result;
1664 }
1665
1666 if (!m_StaticEntries.IsEmpty() && CmdId >= m_iIdSCMFirst && CmdId < m_iIdSCMLast)
1667 {
1668 LocalInvokeInfo.lpVerb -= m_iIdSCMFirst;
1669 Result = InvokeRegVerb(&LocalInvokeInfo);
1670 // TODO: if (FAILED(Result) && !(lpcmi->fMask & CMIC_MASK_FLAG_NO_UI)) SHELL_ErrorBox(m_pSite, Result);
1671 return Result;
1672 }
1673
1674 if (m_iIdCBFirst != m_iIdCBLast && CmdId >= m_iIdCBFirst && CmdId < m_iIdCBLast)
1675 {
1676 Result = _DoInvokeCommandCallback(&LocalInvokeInfo, CmdId - m_iIdCBFirst);
1677 return Result;
1678 }
1679
1680 if (m_iIdDfltFirst != m_iIdDfltLast && CmdId >= m_iIdDfltFirst && CmdId < m_iIdDfltLast)
1681 {
1682 CmdId -= m_iIdDfltFirst;
1683 /* See the definitions of IDM_CUT and co to see how this works */
1684 CmdId += DCM_FCIDM_SHVIEW_OFFSET;
1685 }
1686
1687 if (LocalInvokeInfo.cbSize >= sizeof(CMINVOKECOMMANDINFOEX) && (LocalInvokeInfo.fMask & CMIC_MASK_PTINVOKE))
1688 {
1689 if (m_pDataObj && FAILED_UNEXPECTEDLY(DataObject_SetOffset(m_pDataObj, &LocalInvokeInfo.ptInvoke)))
1690 {
1691 ERR("Unable to add OFFSET to DataObject!\n");
1692 }
1693 }
1694
1695 /* Check if this is a Id */
1696 switch (CmdId)
1697 {
1699 Result = DoPaste(&LocalInvokeInfo, FALSE);
1700 break;
1702 Result = DoPaste(&LocalInvokeInfo, TRUE);
1703 break;
1704 case FCIDM_SHVIEW_COPY:
1705 case FCIDM_SHVIEW_CUT:
1706 Result = DoCopyOrCut(&LocalInvokeInfo, CmdId == FCIDM_SHVIEW_COPY);
1707 break;
1709 Result = DoCreateLink(&LocalInvokeInfo);
1710 break;
1712 Result = DoDelete(&LocalInvokeInfo);
1713 break;
1715 Result = DoRename(&LocalInvokeInfo);
1716 break;
1718 Result = DoProperties(&LocalInvokeInfo);
1719 break;
1721 Result = DoCreateNewFolder(&LocalInvokeInfo);
1722 break;
1723 case FCIDM_SHVIEW_UNDO:
1724 Result = DoUndo(&LocalInvokeInfo);
1725 break;
1726 default:
1728 ERR("Unhandled Verb %xl\n", LOWORD(LocalInvokeInfo.lpVerb));
1729 break;
1730 }
1731
1732 return Result;
1733}
1734
1735HRESULT
1736WINAPI
1738 UINT_PTR idCommand,
1739 UINT uFlags,
1741 LPSTR lpszName,
1742 UINT uMaxNameLen)
1743{
1744 /* We don't handle the help text yet */
1745 if (uFlags == GCS_HELPTEXTA ||
1746 uFlags == GCS_HELPTEXTW ||
1747 HIWORD(idCommand) != 0)
1748 {
1749 return E_NOTIMPL;
1750 }
1751
1752 UINT CmdId = LOWORD(idCommand);
1753
1754 if (uFlags == GCS_VERBA || uFlags == GCS_VERBW)
1755 {
1756 UINT uMsg = (uFlags == GCS_VERBA) ? DFM_GETVERBA : DFM_GETVERBW;
1757 WPARAM wParam = MAKEWPARAM(idCommand, uMaxNameLen);
1758 HRESULT hr = _DoCallback(uMsg, wParam, lpszName);
1759 if (hr == S_OK)
1760 return S_OK;
1761 }
1762
1763 if (!m_DynamicEntries.IsEmpty() && CmdId >= m_iIdSHEFirst && CmdId < m_iIdSHELast)
1764 {
1765 idCommand -= m_iIdSHEFirst;
1767 if (!pEntry)
1768 return E_FAIL;
1769
1770 idCommand -= pEntry->iIdCmdFirst;
1771 return pEntry->pCM->GetCommandString(idCommand,
1772 uFlags,
1773 lpReserved,
1774 lpszName,
1775 uMaxNameLen);
1776 }
1777
1778 if (!m_StaticEntries.IsEmpty() && CmdId >= m_iIdSCMFirst && CmdId < m_iIdSCMLast)
1779 {
1780 /* Validation just returns S_OK on a match. The id exists. */
1781 if (uFlags == GCS_VALIDATEA || uFlags == GCS_VALIDATEW)
1782 return S_OK;
1783
1784 CmdId -= m_iIdSCMFirst;
1785
1786 POSITION it = m_StaticEntries.FindIndex(CmdId);
1787
1788 if (it == NULL)
1789 return E_INVALIDARG;
1790
1792
1793 if (uFlags == GCS_VERBW)
1794 return StringCchCopyW((LPWSTR)lpszName, uMaxNameLen, pEntry->Verb);
1795
1796 if (uFlags == GCS_VERBA)
1797 {
1798 if (SHUnicodeToAnsi(pEntry->Verb, lpszName, uMaxNameLen))
1799 return S_OK;
1800 }
1801
1802 return E_INVALIDARG;
1803 }
1804
1805 //FIXME: Should we handle callbacks here?
1806 if (m_iIdDfltFirst != m_iIdDfltLast && CmdId >= m_iIdDfltFirst && CmdId < m_iIdDfltLast)
1807 {
1808 CmdId -= m_iIdDfltFirst;
1809 /* See the definitions of IDM_CUT and co to see how this works */
1810 CmdId += DCM_FCIDM_SHVIEW_OFFSET;
1811 }
1812
1813 /* Loop looking for a matching Id */
1814 for (UINT i = 0; i < _countof(g_StaticInvokeCmdMap); i++)
1815 {
1816 if (g_StaticInvokeCmdMap[i].IntVerb == CmdId)
1817 {
1818 /* Validation just returns S_OK on a match */
1819 if (uFlags == GCS_VALIDATEA || uFlags == GCS_VALIDATEW)
1820 return S_OK;
1821
1822 /* Return a copy of the ANSI verb */
1823 if (uFlags == GCS_VERBA)
1824 return StringCchCopyA(lpszName, uMaxNameLen, g_StaticInvokeCmdMap[i].szStringVerb);
1825
1826 /* Convert the ANSI verb to unicode and return that */
1827 if (uFlags == GCS_VERBW)
1828 {
1829 if (SHAnsiToUnicode(g_StaticInvokeCmdMap[i].szStringVerb, (LPWSTR)lpszName, uMaxNameLen))
1830 return S_OK;
1831 }
1832 }
1833 }
1834
1835 return E_INVALIDARG;
1836}
1837
1838HRESULT
1839WINAPI
1841 UINT uMsg,
1842 WPARAM wParam,
1843 LPARAM lParam)
1844{
1845 return HandleMenuMsg2(uMsg, wParam, lParam, NULL);
1846}
1847
1849{
1850 if (uMsg == WM_DRAWITEM)
1851 {
1852 DRAWITEMSTRUCT* pDrawStruct = reinterpret_cast<DRAWITEMSTRUCT*>(lParam);
1853 *CmdId = pDrawStruct->itemID;
1854 return S_OK;
1855 }
1856 else if (uMsg == WM_MEASUREITEM)
1857 {
1858 MEASUREITEMSTRUCT* pMeasureStruct = reinterpret_cast<MEASUREITEMSTRUCT*>(lParam);
1859 *CmdId = pMeasureStruct->itemID;
1860 return S_OK;
1861 }
1862 return E_FAIL;
1863}
1864
1865HRESULT
1866WINAPI
1868 UINT uMsg,
1869 WPARAM wParam,
1870 LPARAM lParam,
1871 LRESULT *plResult)
1872{
1873 if (!SHELL_IsContextMenuMsg(uMsg))
1874 return E_FAIL;
1875
1876 UINT CmdId;
1877 if (uMsg == WM_INITMENUPOPUP)
1878 {
1879 CmdId = GetMenuItemID((HMENU)wParam, 0);
1880 if (CmdId == ~0ul)
1881 return E_FAIL;
1882 }
1883 else
1884 {
1885 HRESULT hr = SHGetMenuIdFromMenuMsg(uMsg, lParam, &CmdId);
1886 if (FAILED(hr))
1887 return S_FALSE;
1888 }
1889 CmdId -= m_iIdQCMFirst; // Convert from Win32 id to our base
1890
1891 if (CmdId >= m_iIdSHEFirst && CmdId < m_iIdSHELast)
1892 {
1894 return SHForwardContextMenuMsg(pEntry->pCM, uMsg, wParam, lParam, plResult, TRUE);
1895 }
1896 // TODO: _DoCallback(DFM_WM_*, ...)
1897 return E_FAIL;
1898}
1899
1900HRESULT
1901WINAPI
1903{
1904 m_site = pUnkSite;
1905 return S_OK;
1906}
1907
1908HRESULT
1909WINAPI
1911{
1912 if (!m_site)
1913 return E_FAIL;
1914
1915 return m_site->QueryInterface(riid, ppvSite);
1916}
1917
1918static
1919HRESULT
1921{
1922 return ShellObjectCreatorInit<CDefaultContextMenu>(pdcm, lpfn, riid, ppv);
1923}
1924
1925/*************************************************************************
1926 * SHCreateDefaultContextMenu [SHELL32.325] Vista API
1927 *
1928 */
1929
1930HRESULT
1931WINAPI
1933{
1934 HRESULT hr;
1935
1936 if (!ppv)
1937 return E_INVALIDARG;
1938
1941 return hr;
1942
1943 return S_OK;
1944}
1945
1946/*************************************************************************
1947 * CDefFolderMenu_Create2 [SHELL32.701]
1948 *
1949 */
1950
1951HRESULT
1952WINAPI
1954 PCIDLIST_ABSOLUTE pidlFolder,
1955 HWND hwnd,
1956 UINT cidl,
1958 IShellFolder *psf,
1959 LPFNDFMCALLBACK lpfn,
1960 UINT nKeys,
1961 const HKEY *ahkeyClsKeys,
1962 IContextMenu **ppcm)
1963{
1964 DEFCONTEXTMENU dcm;
1965 dcm.hwnd = hwnd;
1966 dcm.pcmcb = NULL;
1967 dcm.pidlFolder = pidlFolder;
1968 dcm.psf = psf;
1969 dcm.cidl = cidl;
1970 dcm.apidl = apidl;
1972 dcm.cKeys = nKeys;
1973 dcm.aKeys = ahkeyClsKeys;
1974
1977 return hr;
1978
1979 return S_OK;
1980}
static const struct _StaticInvokeCommandMap_ g_StaticInvokeCmdMap[]
struct _DynamicShellEntry_ * PDynamicShellEntry
struct _DynamicShellEntry_ DynamicShellEntry
UINT MapVerbToDfmCmd(_In_ LPCSTR verba)
static int FindVerbInDefaultVerbList(LPCWSTR List, LPCWSTR Verb)
static BOOL HasClipboardData()
static HRESULT CDefaultContextMenu_CreateInstance(const DEFCONTEXTMENU *pdcm, LPFNDFMCALLBACK lpfn, REFIID riid, void **ppv)
BOOL WINAPI _InsertMenuItemW(HMENU hMenu, UINT indexMenu, BOOL fByPosition, UINT wID, UINT fType, LPCWSTR dwTypeData, UINT fState)
HRESULT WINAPI SHCreateDefaultContextMenu(const DEFCONTEXTMENU *pdcm, REFIID riid, void **ppv)
static HRESULT SHELL_GetRegCLSID(HKEY hKey, LPCWSTR SubKey, LPCWSTR Value, CLSID &clsid)
UINT DCMA_InsertMenuItems(_In_ HDCMA hDCMA, _In_ HDCIA hDCIA, _In_opt_ LPCITEMIDLIST pidlFolder, _In_opt_ IDataObject *pDO, _In_opt_ HKEY *pKeys, _In_opt_ UINT nKeys, _In_ QCMINFO *pQCMI, _In_opt_ UINT fCmf, _In_opt_ IUnknown *pUnkSite)
PCSTR MapFcidmCmdToVerb(_In_ UINT_PTR CmdId)
static HRESULT GetFriendlyVerb(_In_ PCWSTR pszVerb, _Out_ PWSTR pszBuf, _In_ SIZE_T cchMax)
void DCMA_Destroy(HDCMA hDCMA)
static BOOL InsertMenuItemAt(HMENU hMenu, UINT Pos, UINT Flags)
#define DCM_FCIDM_SHVIEW_OFFSET
static void DCMA_DestroyEntry(DCMENTRY &dcme)
EXTERN_C HRESULT SHELL32_EnumDefaultVerbList(LPCWSTR List, UINT Index, LPWSTR Verb, SIZE_T cchMax)
static bool IsVerbListSeparator(WCHAR Ch)
static HRESULT MapVerbToCmdId(PVOID Verb, BOOL IsUnicode, IContextMenu *pCM, UINT idFirst, UINT idLast)
struct _StaticShellEntry_ StaticShellEntry
struct _StaticShellEntry_ * PStaticShellEntry
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)
HRESULT DCMA_InvokeCommand(HDCMA hDCMA, CMINVOKECOMMANDINFO *pICI)
#define MAX_VERB
HRESULT SHGetMenuIdFromMenuMsg(UINT uMsg, LPARAM lParam, UINT *CmdId)
HRESULT CRecyclerDropTarget_CreateInstance(REFIID riid, LPVOID *ppvOut)
#define IID_PPV_ARG(Itype, ppType)
static _Out_opt_ PULONGLONG Start
#define shell32_hInstance
UINT cchMax
#define WINE_DEFAULT_DEBUG_CHANNEL(t)
Definition: precomp.h:23
#define index(s, c)
Definition: various.h:29
#define IDM_PROPERTIES
Definition: resources.h:9
#define WARN(fmt,...)
Definition: precomp.h:61
#define ERR(fmt,...)
Definition: precomp.h:57
#define EXTERN_C
Definition: basetyps.h:12
#define STDMETHOD(m)
Definition: basetyps.h:62
#define RegCloseKey(hKey)
Definition: registry.h:49
#define _stricmp
Definition: cat.c:22
EXTERN_C void WINAPI SHChangeNotify(LONG wEventId, UINT uFlags, LPCVOID dwItem1, LPCVOID dwItem2)
LONG Open(HKEY hKeyParent, LPCTSTR lpszKeyName, REGSAM samDesired=KEY_READ|KEY_WRITE) noexcept
Definition: atlbase.h:1173
HRESULT InvokeRegVerb(LPCMINVOKECOMMANDINFOEX lpcmi)
STDMETHOD() QueryService(REFGUID svc, REFIID riid, void **ppv) override
UINT AddShellExtensionsToMenu(HMENU hMenu, UINT *pIndexMenu, UINT idCmdFirst, UINT idCmdLast, UINT uFlags)
HRESULT DoRename(LPCMINVOKECOMMANDINFOEX lpcmi)
STDMETHOD() GetCommandString(UINT_PTR idCommand, UINT uFlags, UINT *lpReserved, LPSTR lpszName, UINT uMaxNameLen) override
BOOL MapVerbToCmdId(PVOID Verb, PUINT idCmd, BOOL IsUnicode)
HRESULT DoCreateLink(LPCMINVOKECOMMANDINFOEX lpcmi)
CComPtr< IDataObject > m_pDataObj
UINT AddStaticContextMenusToMenu(HMENU hMenu, UINT *IndexMenu, UINT iIdCmdFirst, UINT iIdCmdLast, UINT uFlags)
CComPtr< IShellFolder > m_psf
HRESULT DoUndo(LPCMINVOKECOMMANDINFOEX lpcmi)
PCUITEMID_CHILD_ARRAY m_apidl
STDMETHOD() SetSite(IUnknown *pUnkSite) override
STDMETHOD() QueryContextMenu(HMENU hMenu, UINT indexMenu, UINT idCmdFirst, UINT idCmdLast, UINT uFlags) override
CComPtr< IContextMenuCB > m_pmcb
PDynamicShellEntry GetDynamicEntry(UINT idCmd)
CAtlList< StaticShellEntry > m_StaticEntries
HRESULT DoCopyOrCut(LPCMINVOKECOMMANDINFOEX lpcmi, BOOL bCopy)
void AddStaticEntry(const HKEY hkeyClass, const WCHAR *szVerb, UINT uFlags)
HRESULT DoDelete(LPCMINVOKECOMMANDINFOEX lpcmi)
DWORD BrowserFlagsFromVerb(LPCMINVOKECOMMANDINFOEX lpcmi, PStaticShellEntry pEntry)
CAtlList< DynamicShellEntry > m_DynamicEntries
HRESULT WINAPI Initialize(const DEFCONTEXTMENU *pdcm, LPFNDFMCALLBACK lpfn)
HRESULT _DoInvokeCommandCallback(LPCMINVOKECOMMANDINFOEX lpcmi, WPARAM CmdId)
BOOL IsShellExtensionAlreadyLoaded(REFCLSID clsid)
STDMETHOD() HandleMenuMsg(UINT uMsg, WPARAM wParam, LPARAM lParam) override
HRESULT TryToBrowse(LPCMINVOKECOMMANDINFOEX lpcmi, LPCITEMIDLIST pidl, DWORD wFlags)
HRESULT DoProperties(LPCMINVOKECOMMANDINFOEX lpcmi)
CComPtr< IUnknown > m_site
BOOL EnumerateDynamicContextHandlerForKey(HKEY hRootKey)
HRESULT DoCreateNewFolder(LPCMINVOKECOMMANDINFOEX lpici)
HRESULT DoPaste(LPCMINVOKECOMMANDINFOEX lpcmi, BOOL bLink)
STDMETHOD() GetSite(REFIID riid, void **ppvSite) override
HRESULT LoadDynamicContextMenuHandler(HKEY hKey, REFCLSID clsid)
void TryPickDefault(HMENU hMenu, UINT idCmdFirst, UINT DfltOffset, UINT uFlags)
HRESULT InvokeShellExt(LPCMINVOKECOMMANDINFOEX lpcmi)
STDMETHOD() HandleMenuMsg2(UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT *plResult) override
HRESULT _DoCallback(UINT uMsg, WPARAM wParam, LPVOID lParam)
STDMETHOD() InvokeCommand(LPCMINVOKECOMMANDINFO lpcmi) override
PIDLIST_ABSOLUTE m_pidlFolder
HRESULT InvokePidl(LPCMINVOKECOMMANDINFOEX lpcmi, LPCITEMIDLIST pidl, PStaticShellEntry pEntry)
void AddStaticEntriesForKey(HKEY hKey, UINT uFlags)
Definition: _map.h:48
#define CHARS_IN_GUID
WPARAM wParam
Definition: combotst.c:138
LPARAM lParam
Definition: combotst.c:139
static UINT RosGetProcessEffectiveVersion(VOID)
Definition: compat_undoc.h:43
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
#define E_INVALIDARG
Definition: ddrawi.h:101
#define E_NOTIMPL
Definition: ddrawi.h:99
#define E_FAIL
Definition: ddrawi.h:102
ush Pos
Definition: deflate.h:92
HRESULT hr
Definition: delayimp.cpp:582
#define ERROR_SUCCESS
Definition: deptool.c:10
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
_In_ D3DDDI_VIDEO_PRESENT_TARGET_ID _In_ ULONG _In_ ULONG Flags
Definition: dispmprt.h:245
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define DFM_GETDEFSTATICID
Definition: precomp.h:47
#define DFM_INVOKECOMMANDEX
Definition: precomp.h:46
#define DFM_MERGECONTEXTMENU
Definition: precomp.h:44
#define DFM_INVOKECOMMAND
Definition: precomp.h:45
LONG WINAPI RegOpenKeyExW(HKEY hKey, LPCWSTR lpSubKey, DWORD ulOptions, REGSAM samDesired, PHKEY phkResult)
Definition: reg.c:3333
LSTATUS WINAPI RegGetValueW(HKEY hKey, LPCWSTR pszSubKey, LPCWSTR pszValue, DWORD dwFlags, LPDWORD pdwType, PVOID pvData, LPDWORD pcbData)
Definition: reg.c:1931
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:2504
UINT uFlags
Definition: api.c:59
INT WINAPI StringFromGUID2(REFGUID guid, LPOLESTR str, INT cmax)
Definition: combase.c:1525
HRESULT WINAPI CLSIDFromString(LPCOLESTR str, LPCLSID clsid)
Definition: combase.c:1470
HRESULT WINAPI DECLSPEC_HOTPATCH CoCreateInstance(REFCLSID rclsid, IUnknown *outer, DWORD cls_context, REFIID riid, void **obj)
Definition: combase.c:1685
void WINAPI CoTaskMemFree(void *ptr)
Definition: malloc.c:389
BOOL WINAPI DSA_Destroy(HDSA hdsa)
Definition: dsa.c:103
LPWSTR WINAPI StrChrW(LPCWSTR lpszStr, WCHAR ch)
Definition: string.c:464
#define ERROR_NO_MORE_ITEMS
Definition: compat.h:105
#define MAX_PATH
Definition: compat.h:34
int WINAPI lstrcmpiA(LPCSTR str1, LPCSTR str2)
Definition: locale.c:4133
#define IS_INTRESOURCE(x)
Definition: loader.c:613
DWORD WINAPI GetVersion(void)
Definition: version.c:1458
static MonoProfilerRuntimeShutdownBeginCallback cb
Definition: metahost.c:118
_ACRTIMP int __cdecl _wcsicmp(const wchar_t *, const wchar_t *)
Definition: wcs.c:164
_ACRTIMP int __cdecl _wcsnicmp(const wchar_t *, const wchar_t *, size_t)
Definition: wcs.c:200
HRESULT WINAPI OleSetClipboard(IDataObject *data)
Definition: clipboard.c:2192
HRESULT WINAPI OleGetClipboard(IDataObject **obj)
Definition: clipboard.c:2246
HRESULT WINAPI IUnknown_QueryService(IUnknown *obj, REFGUID sid, REFIID iid, void **out)
Definition: main.c:181
DWORD WINAPI SHAnsiToUnicode(const char *src, WCHAR *dest, int dest_len)
Definition: main.c:1801
DWORD WINAPI SHUnicodeToAnsi(const WCHAR *src, char *dest, int dest_len)
Definition: main.c:1756
HKEY WINAPI SHRegDuplicateHKey(HKEY hKey)
Definition: main.c:1828
HRESULT WINAPI IUnknown_SetSite(IUnknown *obj, IUnknown *site)
Definition: main.c:222
#define VERBKEY_CCHMAX
Definition: precomp.h:135
#define DCMA_GetEntry(hDCMA, iItem)
Definition: precomp.h:197
EXTERN_C HRESULT IUnknown_InitializeCommand(_In_ IUnknown *pUnk, _In_ PCWSTR pszCommandName, _In_opt_ IPropertyBag *pPB)
Definition: utils.cpp:1783
EXTERN_C HRESULT InvokeIExecuteCommandWithDataObject(_In_ IExecuteCommand *pEC, _In_ PCWSTR pszCommandName, _In_opt_ IPropertyBag *pPB, _In_ IDataObject *pDO, _In_opt_ LPCMINVOKECOMMANDINFOEX pICI, _In_opt_ IUnknown *pSite)
Definition: utils.cpp:1833
HRESULT SHELL32_ShowPropertiesDialog(IDataObject *pdtobj)
Definition: shlfolder.cpp:648
DWORD RegGetDword(HKEY hKey, PCWSTR pszPath, PCWSTR pszName, DWORD nDefVal)
Definition: utils.h:65
BOOL RegKeyExists(HKEY hKey, LPCWSTR Path)
Definition: utils.h:49
#define DCIA_GetCount(hDCIA)
Definition: utils.h:126
static BOOL RegValueExists(HKEY hKey, LPCWSTR Name)
Definition: utils.h:43
#define DCIA_GetEntry(hDCIA, iItem)
Definition: utils.h:127
void WINAPI SHFree(LPVOID pv)
Definition: shellole.c:370
HRESULT WINAPI SHExtCoCreateInstance(_In_opt_ LPCWSTR aclsid, _In_opt_ const CLSID *clsid, _In_opt_ LPUNKNOWN pUnkOuter, _In_ REFIID riid, _Out_ LPVOID *ppv)
Definition: shellole.c:222
HRESULT WINAPI SHCoCreateInstance(LPCWSTR aclsid, const CLSID *clsid, LPUNKNOWN pUnkOuter, REFIID riid, LPVOID *ppv)
Definition: shellole.c:197
BOOL WINAPI PathYetAnotherMakeUniqueName(LPWSTR buffer, LPCWSTR path, LPCWSTR shortname, LPCWSTR longname)
Definition: shellpath.c:848
BOOL WINAPI SHSimulateDrop(IDropTarget *pDrop, IDataObject *pDataObj, DWORD grfKeyState, PPOINTL lpPt, DWORD *pdwEffect)
Definition: ordinal.c:1423
HRESULT WINAPI SHCreatePropertyBagOnRegKey(HKEY hKey, LPCWSTR subkey, DWORD grfMode, REFIID riid, void **ppv)
Definition: ordinal.c:4641
#define FAILED_UNEXPECTEDLY
Definition: utils.cpp:33
#define MAKE_HRESULT(sev, fac, code)
Definition: dmerror.h:29
#define L(x)
Definition: resources.c:13
static IShellFolder IShellItem **static IBindCtx LPITEMIDLIST SFGAOF
Definition: ebrowser.c:83
#define InitFormatEtc(fe, cf, med)
Definition: editor.h:32
#define IDS_NEWFOLDER
unsigned short WORD
Definition: ntddk_ex.h:93
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
PWDFDEVICE_INIT pInit
FxAutoRegKey hKey
PLIST_ENTRY pEntry
Definition: fxioqueue.cpp:4484
GLuint res
Definition: glext.h:9613
GLuint index
Definition: glext.h:6031
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
const GLint * first
Definition: glext.h:5794
GLfloat GLfloat p
Definition: glext.h:8902
GLuint id
Definition: glext.h:5910
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
unsigned int UINT
Definition: sysinfo.c:13
BOOL NTAPI GlobalUnlock(HGLOBAL hMem)
Definition: heapmem.c:1190
HGLOBAL NTAPI GlobalAlloc(UINT uFlags, SIZE_T dwBytes)
Definition: heapmem.c:368
REFIID riid
Definition: atlbase.h:39
REFIID LPVOID * ppv
Definition: atlbase.h:39
struct IContextMenu::tagCMINVOKECOMMANDINFO * LPCMINVOKECOMMANDINFO
HRESULT GetCommandString([in] UINT_PTR idCmd, [in] UINT uType, [out] UINT *pwReserved, [out, size_is(cchMax)] LPSTR pszName, [in] UINT cchMax)
HRESULT QueryContextMenu([in] HMENU hmenu, [in] UINT indexMenu, [in] UINT idCmdFirst, [in] UINT idCmdLast, [in] UINT uFlags)
ULONG Release()
#define S_OK
Definition: intsafe.h:52
#define SUCCEEDED(hr)
Definition: intsafe.h:50
#define FAILED(hr)
Definition: intsafe.h:51
#define C_ASSERT(e)
Definition: intsafe.h:73
static ERESOURCE GlobalLock
Definition: sys_arch.c:8
uint32_t entry
Definition: isohybrid.c:63
#define LOBYTE(W)
Definition: jmemdos.c:487
#define debugstr_w
Definition: kernel32.h:32
#define BEGIN_COM_MAP(x)
Definition: atlcom.h:581
#define COM_INTERFACE_ENTRY_IID(iid, x)
Definition: atlcom.h:601
#define END_COM_MAP()
Definition: atlcom.h:592
if(dx< 0)
Definition: linetemp.h:194
#define HResultFromWin32
Definition: loader.cpp:14
#define ZeroMemory
Definition: minwinbase.h:31
#define CopyMemory
Definition: minwinbase.h:29
LONG_PTR LPARAM
Definition: minwindef.h:175
LONG_PTR LRESULT
Definition: minwindef.h:176
UINT_PTR WPARAM
Definition: minwindef.h:174
CONST void * LPCVOID
Definition: minwindef.h:164
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
const IID IID_IObjectWithSite
static IActiveScriptSite * site
Definition: script.c:149
static const CLSID *static CLSID *static const GUID VARIANT VARIANT *static IServiceProvider DWORD *static HMENU
Definition: ordinal.c:60
#define min(a, b)
Definition: monoChain.cc:55
const CLSID * clsid
Definition: msctf.cpp:50
unsigned __int3264 UINT_PTR
Definition: mstsclib_h.h:274
unsigned int * PUINT
Definition: ndis.h:50
#define _Out_
Definition: no_sal2.h:160
#define _In_
Definition: no_sal2.h:158
#define _In_opt_
Definition: no_sal2.h:212
#define KEY_READ
Definition: nt_native.h:1026
#define UNICODE_NULL
#define STGM_READ
Definition: objbase.h:936
#define LOWORD(l)
Definition: pedump.c:82
short WCHAR
Definition: pedump.c:58
short SHORT
Definition: pedump.c:59
long LONG
Definition: pedump.c:60
PITEMID_CHILD * _ILCopyaPidl(PCUITEMID_CHILD_ARRAY apidlsrc, UINT cidl)
Definition: pidl.c:2631
LPITEMIDLIST WINAPI ILClone(LPCITEMIDLIST pidl)
Definition: pidl.c:238
void WINAPI ILFree(LPITEMIDLIST pidl)
Definition: pidl.c:1051
HRESULT WINAPI SHILCreateFromPathW(LPCWSTR path, LPITEMIDLIST *ppidl, DWORD *attributes)
Definition: pidl.c:404
LPITEMIDLIST WINAPI ILFindLastID(LPCITEMIDLIST pidl)
Definition: pidl.c:199
LPITEMIDLIST WINAPI ILCombine(LPCITEMIDLIST pidl1, LPCITEMIDLIST pidl2)
Definition: pidl.c:817
BOOL WINAPI SHGetPathFromIDListW(LPCITEMIDLIST pidl, LPWSTR pszPath)
Definition: pidl.c:1496
void _ILFreeaPidl(LPITEMIDLIST *apidl, UINT cidl)
Definition: pidl.c:2616
#define DSA_AppendItem(hdsa, pitem)
Definition: commctrl.h:4832
#define REFIID
Definition: guiddef.h:118
#define REFCLSID
Definition: guiddef.h:117
#define PathRemoveFileSpec
Definition: shlwapi.h:504
_In_ UINT cchBuf
Definition: shlwapi.h:378
#define MAKEWPARAM(l, h)
Definition: winuser.h:4117
#define MK_SHIFT
Definition: winuser.h:2405
UINT WINAPI GetMenuDefaultItem(_In_ HMENU hMenu, _In_ UINT fByPos, _In_ UINT gmdiFlags)
#define MF_BYCOMMAND
Definition: winuser.h:202
#define MIIM_ID
Definition: winuser.h:733
BOOL WINAPI SetMenuDefaultItem(_In_ HMENU, _In_ UINT, _In_ UINT)
UINT WINAPI RegisterClipboardFormatW(_In_ LPCWSTR)
BOOL WINAPI DeleteMenu(_In_ HMENU, _In_ UINT, _In_ UINT)
UINT WINAPI GetMenuItemID(_In_ HMENU, _In_ int)
#define MFT_SEPARATOR
Definition: winuser.h:755
#define WM_DRAWITEM
Definition: winuser.h:1673
#define MIIM_STATE
Definition: winuser.h:732
#define MFS_DEFAULT
Definition: winuser.h:759
HMENU WINAPI GetSubMenu(_In_ HMENU, _In_ int)
#define WM_INITMENUPOPUP
Definition: winuser.h:1774
#define MK_CONTROL
Definition: winuser.h:2406
#define MF_SEPARATOR
Definition: winuser.h:137
#define MF_BYPOSITION
Definition: winuser.h:203
#define WM_MEASUREITEM
Definition: winuser.h:1674
#define MFS_ENABLED
Definition: winuser.h:761
#define MAKEINTRESOURCEA(i)
Definition: winuser.h:581
BOOL WINAPI DestroyMenu(_In_ HMENU)
#define MFT_STRING
Definition: winuser.h:757
#define MAKEINTRESOURCEW(i)
Definition: winuser.h:582
HMENU WINAPI LoadMenuW(_In_opt_ HINSTANCE, _In_ LPCWSTR)
#define MIIM_DATA
Definition: winuser.h:737
#define MIIM_TYPE
Definition: winuser.h:736
BOOL WINAPI InsertMenuItemW(_In_ HMENU, _In_ UINT, _In_ BOOL, _In_ LPCMENUITEMINFOW)
#define err(...)
HRESULT WINAPI SHForwardContextMenuMsg(IUnknown *pUnk, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT *pResult, BOOL useIContextMenu2)
Definition: rosordinal.c:11
wcscpy
static __inline const char * wine_dbgstr_guid(const GUID *id)
Definition: debug.h:181
#define LoadStringW
Definition: utils.h:64
#define _WIN32_WINNT_WIN7
Definition: sdkddkver.h:28
#define _WIN32_WINNT_VISTA
Definition: sdkddkver.h:25
static __inline LPWSTR __SHCloneStrAtoW(WCHAR **target, const char *source)
Definition: shell32_main.h:227
#define SEE_MASK_CLASSKEY
Definition: shellapi.h:26
#define SEE_MASK_IDLIST
Definition: shellapi.h:27
#define STATUS_SUCCESS
Definition: shellext.h:65
static BOOL SHELL_IsContextMenuMsg(UINT uMsg)
Definition: shellutils.h:759
BOOL WINAPI DECLSPEC_HOTPATCH ShellExecuteExW(LPSHELLEXECUTEINFOW sei)
Definition: shlexec.cpp:2732
int WINAPI SHCreateDirectory(HWND hWnd, LPCWSTR path)
Definition: shlfileop.cpp:948
#define SID_IShellBrowser
UINT WINAPI Shell_MergeMenus(HMENU hmDst, HMENU hmSrc, UINT uInsert, UINT uIDAdjust, UINT uIDAdjustMax, ULONG uFlags)
Definition: shlmenu.c:856
#define DFM_GETVERBW
Definition: shlobj.h:2620
#define DFM_CMD_DELETE
Definition: shlobj.h:2626
#define CFSTR_SHELLIDLIST
Definition: shlobj.h:560
#define CFSTR_PREFERREDDROPEFFECT
Definition: shlobj.h:570
#define SHCNE_MKDIR
Definition: shlobj.h:1910
#define DFM_CMD_NEWFOLDER
Definition: shlobj.h:2631
#define DFM_CMD_COPY
Definition: shlobj.h:2628
#define DFM_GETVERBA
Definition: shlobj.h:2621
#define DFM_CMD_PASTE
Definition: shlobj.h:2632
#define DFM_CMD_MOVE
Definition: shlobj.h:2627
#define SHCNF_FLUSH
Definition: shlobj.h:1946
#define SHCNF_PATHW
Definition: shlobj.h:1943
#define DFM_MAPCOMMANDNAME
Definition: shlobj.h:2619
#define DFM_CMD_PROPERTIES
Definition: shlobj.h:2630
HRESULT(CALLBACK * LPFNDFMCALLBACK)(_In_opt_ IShellFolder *, _In_opt_ HWND, _In_opt_ IDataObject *, UINT, WPARAM, LPARAM)
Definition: shlobj.h:2586
#define DFM_CMD_RENAME
Definition: shlobj.h:2638
RESTRICTIONS
Definition: shlobj.h:1658
#define DFM_CMD_LINK
Definition: shlobj.h:2629
DWORD WINAPI SHRestricted(RESTRICTIONS rest)
Definition: shpolicy.c:166
#define FCIDM_SHVIEW_CUT
Definition: shresdef.h:869
#define FCIDM_SHVIEW_UNDO
Definition: shresdef.h:872
#define IDM_DELETE
Definition: shresdef.h:909
#define FCIDM_SHVIEW_COPY
Definition: shresdef.h:870
#define IDS_OPEN_VERB
Definition: shresdef.h:210
#define IDM_INSERT
Definition: shresdef.h:907
#define FCIDM_SHVIEW_INSERTLINK
Definition: shresdef.h:873
#define IDS_FIND_VERB
Definition: shresdef.h:214
#define FCIDM_SHVIEW_NEWFOLDER
Definition: shresdef.h:891
#define IDM_RENAME
Definition: shresdef.h:910
#define IDM_COPY
Definition: shresdef.h:906
#define FCIDM_SHVIEW_PROPERTIES
Definition: shresdef.h:868
#define IDS_EXPLORE_VERB
Definition: shresdef.h:211
#define IDM_CUT
Definition: shresdef.h:905
#define IDM_CREATELINK
Definition: shresdef.h:908
#define IDS_PRINT_VERB
Definition: shresdef.h:215
#define FCIDM_SHVIEW_DELETE
Definition: shresdef.h:866
#define FCIDM_SHVIEW_RENAME
Definition: shresdef.h:867
#define FCIDM_SHVIEW_CREATELINK
Definition: shresdef.h:865
#define IDS_RUNAS_VERB
Definition: shresdef.h:212
#define MENU_SHV_FILE
Definition: shresdef.h:903
#define IDS_EDIT_VERB
Definition: shresdef.h:213
#define FCIDM_SHVIEW_INSERT
Definition: shresdef.h:871
ITEMIDLIST UNALIGNED * LPITEMIDLIST
Definition: shtypes.idl:41
const PCUITEMID_CHILD * PCUITEMID_CHILD_ARRAY
Definition: shtypes.idl:71
const ITEMIDLIST UNALIGNED * LPCITEMIDLIST
Definition: shtypes.idl:42
#define _countof(array)
Definition: sndvol32.h:70
#define TRACE(s)
Definition: solgame.cpp:4
STRSAFEAPI StringCchPrintfW(STRSAFE_LPWSTR pszDest, size_t cchDest, STRSAFE_LPCWSTR pszFormat,...)
Definition: strsafe.h:530
STRSAFEAPI StringCchCopyW(STRSAFE_LPWSTR pszDest, size_t cchDest, STRSAFE_LPCWSTR pszSrc)
Definition: strsafe.h:149
STRSAFEAPI StringCchCopyA(STRSAFE_LPSTR pszDest, size_t cchDest, STRSAFE_LPCSTR pszSrc)
Definition: strsafe.h:145
STRSAFEAPI StringCbPrintfW(STRSAFE_LPWSTR pszDest, size_t cbDest, STRSAFE_LPCWSTR pszFormat,...)
Definition: strsafe.h:557
STRSAFEAPI StringCchCopyNW(STRSAFE_LPWSTR pszDest, size_t cchDest, STRSAFE_LPCWSTR pszSrc, size_t cchToCopy)
Definition: strsafe.h:236
IContextMenuCB * pcmcb
Definition: shlobj.h:2568
IShellFolder * psf
Definition: shlobj.h:2570
IUnknown * punkAssociationInfo
Definition: shlobj.h:2573
PCUITEMID_CHILD_ARRAY apidl
Definition: shlobj.h:2572
const HKEY * aKeys
Definition: shlobj.h:2575
PCIDLIST_ABSOLUTE pidlFolder
Definition: shlobj.h:2569
IContextMenu * pCM
Definition: precomp.h:191
Definition: dsa.c:45
CComPtr< IContextMenu > pCM
Definition: scsiwmi.h:51
UINT idCmdFirst
Definition: shlobj.h:1408
LPCWSTR lpDirectory
Definition: shellapi.h:340
LPCWSTR lpParameters
Definition: shellapi.h:339
LPWSTR dwTypeData
Definition: winuser.h:3377
uint16_t * PWSTR
Definition: typedefs.h:56
const char * LPCSTR
Definition: typedefs.h:52
int32_t INT_PTR
Definition: typedefs.h:64
const uint16_t * PCWSTR
Definition: typedefs.h:57
const uint16_t * LPCWSTR
Definition: typedefs.h:57
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
uint16_t * LPWSTR
Definition: typedefs.h:56
ULONG_PTR SIZE_T
Definition: typedefs.h:80
char * LPSTR
Definition: typedefs.h:51
int32_t INT
Definition: typedefs.h:58
const char * PCSTR
Definition: typedefs.h:52
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define HIWORD(l)
Definition: typedefs.h:247
_In_ WDFCOLLECTION _In_ ULONG Index
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING _Out_opt_ PUSHORT _Inout_opt_ PUNICODE_STRING Value
Definition: wdfregistry.h:413
_Must_inspect_result_ _In_ WDFCMRESLIST List
Definition: wdfresource.h:550
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
#define GHND
Definition: winbase.h:321
_In_ PSID _Out_writes_to_opt_ cchName LPSTR _Inout_ LPDWORD cchName
Definition: winbase.h:2497
WINBASEAPI _In_ DWORD _Out_ _In_ WORD wFlags
Definition: wincon_undoc.h:337
_In_ LONG _In_ HWND hwnd
Definition: winddi.h:4023
#define WINAPI
Definition: msvc.h:6
#define S_FALSE
Definition: winerror.h:3451
static HRESULT HRESULT_FROM_WIN32(unsigned int x)
Definition: winerror.h:210
#define SEVERITY_SUCCESS
Definition: winerror.h:177
#define ERROR_NO_ASSOCIATION
Definition: winerror.h:1001
#define HRESULT_CODE(hr)
Definition: winerror.h:188
#define ERROR_NOT_FOUND
Definition: winerror.h:1014
_In_ DWORD _In_ int _In_ int _In_opt_ LPNLSVERSIONINFO _In_opt_ LPVOID lpReserved
Definition: winnls.h:1279
#define HKEY_LOCAL_MACHINE
Definition: winreg.h:12
#define RRF_RT_REG_SZ
Definition: winreg.h:58
#define HKEY_CLASSES_ROOT
Definition: winreg.h:10
_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:409
static void Initialize()
Definition: xlate.c:212
#define IID_NULL_PPV_ARG(Itype, ppType)