ReactOS 0.4.16-dev-188-g678aa63
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
35typedef struct _DynamicShellEntry_
36{
42
43typedef struct _StaticShellEntry_
44{
48
49#define DCM_FCIDM_SHVIEW_OFFSET 0x7000 // Offset from the menu ids in the menu resource to FCIDM_SHVIEW_*
50
51//
52// verbs for InvokeCommandInfo
53//
54static const struct _StaticInvokeCommandMap_
55{
60{
61 { "RunAs", 0 }, // Unimplemented
62 { "Print", 0 }, // Unimplemented
63 { "Preview", 0 }, // Unimplemented
64 { "Open", FCIDM_SHVIEW_OPEN },
65 { CMDSTR_NEWFOLDERA, FCIDM_SHVIEW_NEWFOLDER, (SHORT)DFM_CMD_NEWFOLDER },
66 { "cut", FCIDM_SHVIEW_CUT, /* ? */ },
73 { "copyto", FCIDM_SHVIEW_COPYTO },
74 { "moveto", FCIDM_SHVIEW_MOVETO },
75};
76
78{
79 for (UINT i = 0; i < _countof(g_StaticInvokeCmdMap); ++i)
80 {
81 if (!lstrcmpiA(g_StaticInvokeCmdMap[i].szStringVerb, verba))
82 return (int)g_StaticInvokeCmdMap[i].DfmCmd;
83 }
84 return 0;
85}
86
87static inline bool IsVerbListSeparator(WCHAR Ch)
88{
89 return Ch == L' ' || Ch == L','; // learn.microsoft.com/en-us/windows/win32/shell/context-menu-handlers
90}
91
93{
94 for (UINT index = 0; *List; ++index)
95 {
97 List++;
99 while (*List && !IsVerbListSeparator(*List))
100 List++;
101 // "List > Start" to verify that the list item is non-empty to avoid the edge case where Verb is "" and the list contains ",,"
102 if (!_wcsnicmp(Verb, Start, List - Start) && List > Start)
103 return index;
104 }
105 return -1;
106}
107
109{
110 for (UINT i = 0; *List; ++i)
111 {
112 while (IsVerbListSeparator(*List))
113 List++;
115 while (*List && !IsVerbListSeparator(*List))
116 List++;
117 if (List > Start && i == Index)
118 return StringCchCopyNW(Verb, cchMax, Start, List - Start);
119 }
121}
122
124 public CComObjectRootEx<CComMultiThreadModelNoCS>,
125 public IContextMenu3,
126 public IObjectWithSite,
127 public IServiceProvider
128{
129 private:
142 UINT m_iIdSHEFirst; /* first used id */
143 UINT m_iIdSHELast; /* last used id */
145 UINT m_iIdSCMFirst; /* first static used id */
146 UINT m_iIdSCMLast; /* last static used id */
147 UINT m_iIdCBFirst; /* first callback used id */
148 UINT m_iIdCBLast; /* last callback used id */
149 UINT m_iIdDfltFirst; /* first default part id */
150 UINT m_iIdDfltLast; /* last default part id */
151 HWND m_hwnd; /* window passed to callback */
153
156 void AddStaticEntry(const HKEY hkeyClass, const WCHAR *szVerb, UINT uFlags);
158 void TryPickDefault(HMENU hMenu, UINT idCmdFirst, UINT DfltOffset, UINT uFlags);
162 UINT AddShellExtensionsToMenu(HMENU hMenu, UINT* pIndexMenu, UINT idCmdFirst, UINT idCmdLast, UINT uFlags);
163 UINT AddStaticContextMenusToMenu(HMENU hMenu, UINT* IndexMenu, UINT iIdCmdFirst, UINT iIdCmdLast, UINT uFlags);
180 BOOL MapVerbToCmdId(PVOID Verb, PUINT idCmd, BOOL IsUnicode);
181
182 public:
186
187 // IContextMenu
188 STDMETHOD(QueryContextMenu)(HMENU hMenu, UINT indexMenu, UINT idCmdFirst, UINT idCmdLast, UINT uFlags) override;
190 STDMETHOD(GetCommandString)(UINT_PTR idCommand, UINT uFlags, UINT *lpReserved, LPSTR lpszName, UINT uMaxNameLen) override;
191
192 // IContextMenu2
194
195 // IContextMenu3
196 STDMETHOD(HandleMenuMsg2)(UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT *plResult) override;
197
198 // IObjectWithSite
199 STDMETHOD(SetSite)(IUnknown *pUnkSite) override;
200 STDMETHOD(GetSite)(REFIID riid, void **ppvSite) override;
201
202 // IServiceProvider
204 {
205 return IUnknown_QueryService(m_site, svc, riid, ppv);
206 }
207
209 COM_INTERFACE_ENTRY_IID(IID_IContextMenu, IContextMenu)
210 COM_INTERFACE_ENTRY_IID(IID_IContextMenu2, IContextMenu2)
211 COM_INTERFACE_ENTRY_IID(IID_IContextMenu3, IContextMenu3)
213 COM_INTERFACE_ENTRY_IID(IID_IServiceProvider, IServiceProvider)
215};
216
218 m_psf(NULL),
219 m_pmcb(NULL),
220 m_pfnmcb(NULL),
221 m_cidl(0),
222 m_apidl(NULL),
223 m_pDataObj(NULL),
224 m_aKeys(NULL),
225 m_cKeys(NULL),
226 m_pidlFolder(NULL),
227 m_bGroupPolicyActive(0),
228 m_iIdSHEFirst(0),
229 m_iIdSHELast(0),
230 m_iIdSCMFirst(0),
231 m_iIdSCMLast(0),
232 m_iIdCBFirst(0),
233 m_iIdCBLast(0),
234 m_iIdDfltFirst(0),
235 m_iIdDfltLast(0),
236 m_hwnd(NULL)
237{
239}
240
242{
243 for (POSITION it = m_DynamicEntries.GetHeadPosition(); it != NULL;)
244 {
245 const DynamicShellEntry& info = m_DynamicEntries.GetNext(it);
246 IUnknown_SetSite(info.pCM.p, NULL);
247 }
248 m_DynamicEntries.RemoveAll();
249 m_StaticEntries.RemoveAll();
250
251 for (UINT i = 0; i < m_cKeys; i++)
254
255 if (m_pidlFolder)
257 _ILFreeaPidl(const_cast<PITEMID_CHILD *>(m_apidl), m_cidl);
258}
259
261{
262 TRACE("cidl %u\n", pdcm->cidl);
263
264 if (!pdcm->pcmcb && !lpfn)
265 {
266 ERR("CDefaultContextMenu needs a callback!\n");
267 return E_INVALIDARG;
268 }
269
270 m_cidl = pdcm->cidl;
272 if (m_cidl && !m_apidl)
273 return E_OUTOFMEMORY;
274 m_psf = pdcm->psf;
275 m_pmcb = pdcm->pcmcb;
276 m_pfnmcb = lpfn;
277 m_hwnd = pdcm->hwnd;
278
279 m_cKeys = pdcm->cKeys;
280 if (pdcm->cKeys)
281 {
282 m_aKeys = (HKEY*)HeapAlloc(GetProcessHeap(), 0, sizeof(HKEY) * pdcm->cKeys);
283 if (!m_aKeys)
284 return E_OUTOFMEMORY;
285 memcpy(m_aKeys, pdcm->aKeys, sizeof(HKEY) * pdcm->cKeys);
286 }
287
288 m_psf->GetUIObjectOf(pdcm->hwnd, m_cidl, m_apidl, IID_NULL_PPV_ARG(IDataObject, &m_pDataObj));
289
290 if (pdcm->pidlFolder)
291 {
293 }
294 else
295 {
297 if (SUCCEEDED(m_psf->QueryInterface(IID_PPV_ARG(IPersistFolder2, &pf))))
298 {
299 if (FAILED(pf->GetCurFolder(&m_pidlFolder)))
300 ERR("GetCurFolder failed\n");
301 }
302 TRACE("pidlFolder %p\n", m_pidlFolder);
303 }
304
305 return S_OK;
306}
307
309{
310 if (m_pmcb)
311 {
312 return m_pmcb->CallBack(m_psf, m_hwnd, m_pDataObj, uMsg, wParam, (LPARAM)lParam);
313 }
314 else if(m_pfnmcb)
315 {
317 }
318
319 return E_FAIL;
320}
321
322void CDefaultContextMenu::AddStaticEntry(const HKEY hkeyClass, const WCHAR *szVerb, UINT uFlags)
323{
324 POSITION it = m_StaticEntries.GetHeadPosition();
325 while (it != NULL)
326 {
327 const StaticShellEntry& info = m_StaticEntries.GetNext(it);
328 if (info.Verb.CompareNoCase(szVerb) == 0)
329 {
330 /* entry already exists */
331 return;
332 }
333 }
334
335 TRACE("adding verb %s\n", debugstr_w(szVerb));
336
337 if (!_wcsicmp(szVerb, L"open") && !(uFlags & CMF_NODEFAULT))
338 {
339 /* open verb is always inserted in front */
340 m_StaticEntries.AddHead({ szVerb, hkeyClass });
341 }
342 else
343 {
344 m_StaticEntries.AddTail({ szVerb, hkeyClass });
345 }
346}
347
349{
350 WCHAR wszName[VERBKEY_CCHMAX];
351 DWORD cchName, dwIndex = 0;
352 HKEY hShellKey;
353
354 LRESULT lres = RegOpenKeyExW(hKey, L"shell", 0, KEY_READ, &hShellKey);
355 if (lres != STATUS_SUCCESS)
356 return;
357
358 if (!*m_DefVerbs)
359 {
360 DWORD cb = sizeof(m_DefVerbs);
362 }
363
364 while(TRUE)
365 {
366 cchName = _countof(wszName);
367 if (RegEnumKeyExW(hShellKey, dwIndex++, wszName, &cchName, NULL, NULL, NULL, NULL) != ERROR_SUCCESS)
368 break;
369
370 AddStaticEntry(hKey, wszName, uFlags);
371 }
372
373 RegCloseKey(hShellKey);
374}
375
376static
377BOOL
379{
380 BOOL bRet = FALSE;
381 CComPtr<IDataObject> pDataObj;
382
383 if (SUCCEEDED(OleGetClipboard(&pDataObj)))
384 {
385 FORMATETC formatetc;
386
387 TRACE("pDataObj=%p\n", pDataObj.p);
388
389 /* Set the FORMATETC structure*/
390 InitFormatEtc(formatetc, RegisterClipboardFormatW(CFSTR_SHELLIDLIST), TYMED_HGLOBAL);
391 bRet = SUCCEEDED(pDataObj->QueryGetData(&formatetc));
392 }
393
394 return bRet;
395}
396
397BOOL
399{
400 POSITION it = m_DynamicEntries.GetHeadPosition();
401 while (it != NULL)
402 {
403 const DynamicShellEntry& info = m_DynamicEntries.GetNext(it);
404 if (info.ClassID == clsid)
405 return TRUE;
406 }
407
408 return FALSE;
409}
410
413{
414 HRESULT hr;
415 TRACE("LoadDynamicContextMenuHandler entered with This %p hKey %p pclsid %s\n", this, hKey, wine_dbgstr_guid(&clsid));
416
418 return S_OK;
419
422 if (FAILED(hr))
423 {
424 ERR("SHCoCreateInstance(IContextMenu) failed.clsid %s hr 0x%x\n", wine_dbgstr_guid(&clsid), hr);
425 return hr;
426 }
427
428 CComPtr<IShellExtInit> pExtInit;
429 hr = pcm->QueryInterface(IID_PPV_ARG(IShellExtInit, &pExtInit));
430 if (FAILED(hr))
431 {
432 ERR("IContextMenu->QueryInterface(IShellExtInit) failed.clsid %s hr 0x%x\n", wine_dbgstr_guid(&clsid), hr);
433 return hr;
434 }
435
436 hr = pExtInit->Initialize(m_pDataObj ? NULL : m_pidlFolder, m_pDataObj, hKey);
437 if (FAILED(hr))
438 {
439 WARN("IShellExtInit::Initialize failed.clsid %s hr 0x%x\n", wine_dbgstr_guid(&clsid), hr);
440 return hr;
441 }
442
443 if (m_site)
445
446 m_DynamicEntries.AddTail({ 0, 0, clsid, pcm });
447
448 return S_OK;
449}
450
451BOOL
453{
454 WCHAR wszName[MAX_PATH], wszBuf[MAX_PATH], *pwszClsid;
456 HRESULT hr;
457 HKEY hKey;
458
459 if (RegOpenKeyExW(hRootKey, L"shellex\\ContextMenuHandlers", 0, KEY_READ, &hKey) != ERROR_SUCCESS)
460 {
461 TRACE("RegOpenKeyExW failed\n");
462 return FALSE;
463 }
464
465 DWORD dwIndex = 0;
466 while (TRUE)
467 {
468 cchName = _countof(wszName);
469 if (RegEnumKeyExW(hKey, dwIndex++, wszName, &cchName, NULL, NULL, NULL, NULL) != ERROR_SUCCESS)
470 break;
471
472 /* Key name or key value is CLSID */
473 CLSID clsid;
474 hr = CLSIDFromString(wszName, &clsid);
475 if (hr == S_OK)
476 pwszClsid = wszName;
477 else
478 {
479 DWORD cchBuf = _countof(wszBuf);
480 if (RegGetValueW(hKey, wszName, NULL, RRF_RT_REG_SZ, NULL, wszBuf, &cchBuf) == ERROR_SUCCESS)
481 hr = CLSIDFromString(wszBuf, &clsid);
482 pwszClsid = wszBuf;
483 }
484
485 if (FAILED(hr))
486 {
487 ERR("CLSIDFromString failed for clsid %S hr 0x%x\n", pwszClsid, hr);
488 continue;
489 }
490
492 {
494 L"Software\\Microsoft\\Windows\\CurrentVersion\\Shell Extensions\\Approved",
495 pwszClsid,
497 NULL,
498 NULL,
500 {
501 ERR("Shell extension %s not approved!\n", pwszClsid);
502 continue;
503 }
504 }
505
507 if (FAILED(hr))
508 WARN("Failed to get context menu entires from shell extension! clsid: %S\n", pwszClsid);
509 }
510
512 return TRUE;
513}
514
515UINT
517{
518 UINT cIds = 0;
519
520 if (m_DynamicEntries.IsEmpty())
521 return cIds;
522
523 POSITION it = m_DynamicEntries.GetHeadPosition();
524 while (it != NULL)
525 {
527
528 HRESULT hr = info.pCM->QueryContextMenu(hMenu, *pIndexMenu, idCmdFirst + cIds, idCmdLast, uFlags);
529 if (SUCCEEDED(hr))
530 {
531 info.iIdCmdFirst = cIds;
532 info.NumIds = HRESULT_CODE(hr);
533 (*pIndexMenu) += info.NumIds;
534
535 cIds += info.NumIds;
536 if (idCmdFirst + cIds >= idCmdLast)
537 break;
538 }
539 TRACE("pEntry hr %x contextmenu %p cmdfirst %x num ids %x\n", hr, info.pCM.p, info.iIdCmdFirst, info.NumIds);
540 }
541 return cIds;
542}
543
544UINT
546 HMENU hMenu,
547 UINT* pIndexMenu,
548 UINT iIdCmdFirst,
549 UINT iIdCmdLast,
550 UINT uFlags)
551{
553 MENUITEMINFOW mii = { sizeof(mii) };
554 UINT idResource;
555 WCHAR wszDispVerb[80]; // The limit on XP. If the friendly string is longer, it falls back to the verb key.
556 UINT fState;
557 UINT cIds = 0, indexFirst = *pIndexMenu, indexDefault;
558 int iDefVerbIndex = -1;
559
561 mii.fType = MFT_STRING;
562
563 POSITION it = m_StaticEntries.GetHeadPosition();
564 bool first = true;
565 while (it != NULL)
566 {
568 BOOL forceFirstPos = FALSE;
569
570 fState = MFS_ENABLED;
571
572 /* set first entry as default */
573 if (first)
574 {
575 fState |= MFS_DEFAULT;
576 first = false;
577 }
578
579 if (info.Verb.CompareNoCase(L"open") == 0)
580 {
581 idResource = IDS_OPEN_VERB;
582 fState |= MFS_DEFAULT; /* override default when open verb is found */
583 forceFirstPos++;
584 }
585 else if (info.Verb.CompareNoCase(L"explore") == 0)
586 {
587 idResource = IDS_EXPLORE_VERB;
588 if (uFlags & CMF_EXPLORE)
589 {
590 fState |= MFS_DEFAULT;
591 forceFirstPos++;
592 }
593 }
594 else if (info.Verb.CompareNoCase(L"runas") == 0)
595 idResource = IDS_RUNAS_VERB;
596 else if (info.Verb.CompareNoCase(L"edit") == 0)
597 idResource = IDS_EDIT_VERB;
598 else if (info.Verb.CompareNoCase(L"find") == 0)
599 idResource = IDS_FIND_VERB;
600 else if (info.Verb.CompareNoCase(L"print") == 0)
601 idResource = IDS_PRINT_VERB;
602 else if (info.Verb.CompareNoCase(L"printto") == 0)
603 continue;
604 else
605 idResource = 0;
606
607 /* By default use verb for menu item name */
608 mii.dwTypeData = (LPWSTR)info.Verb.GetString();
609
610 WCHAR wszKey[sizeof("shell\\") + MAX_VERB];
611 HRESULT hr;
612 hr = StringCbPrintfW(wszKey, sizeof(wszKey), L"shell\\%s", info.Verb.GetString());
614 {
615 continue;
616 }
617
618 UINT cmdFlags = 0;
619 bool hide = false;
620 HKEY hkVerb;
621 if (idResource > 0)
622 {
623 if (!(uFlags & CMF_OPTIMIZEFORINVOKE))
624 {
625 if (LoadStringW(shell32_hInstance, idResource, wszDispVerb, _countof(wszDispVerb)))
626 mii.dwTypeData = wszDispVerb; /* use translated verb */
627 else
628 ERR("Failed to load string\n");
629 }
630
631 if (RegOpenKeyW(info.hkClass, wszKey, &hkVerb) != ERROR_SUCCESS)
632 hkVerb = NULL;
633 }
634 else
635 {
636 if (RegOpenKeyW(info.hkClass, wszKey, &hkVerb) == ERROR_SUCCESS)
637 {
638 if (!(uFlags & CMF_OPTIMIZEFORINVOKE))
639 {
640 DWORD cbVerb = sizeof(wszDispVerb);
641 LONG res = RegLoadMUIStringW(hkVerb, L"MUIVerb", wszDispVerb, cbVerb, NULL, 0, NULL);
642 if (res || !*wszDispVerb)
643 res = RegLoadMUIStringW(hkVerb, NULL, wszDispVerb, cbVerb, NULL, 0, NULL);
644
645 if (res == ERROR_SUCCESS && *wszDispVerb)
646 {
647 /* use description for the menu entry */
648 mii.dwTypeData = wszDispVerb;
649 }
650 }
651 }
652 else
653 {
654 hkVerb = NULL;
655 }
656 }
657
658 if (hkVerb)
659 {
660 if (!(uFlags & CMF_EXTENDEDVERBS))
661 hide = RegValueExists(hkVerb, L"Extended");
662
663 if (!hide)
664 hide = RegValueExists(hkVerb, L"ProgrammaticAccessOnly");
665
666 if (!hide && !(uFlags & CMF_DISABLEDVERBS))
667 hide = RegValueExists(hkVerb, L"LegacyDisable");
668
669 if (RegValueExists(hkVerb, L"NeverDefault"))
670 fState &= ~MFS_DEFAULT;
671
672 if (RegValueExists(hkVerb, L"SeparatorBefore"))
673 cmdFlags |= ECF_SEPARATORBEFORE;
674 if (RegValueExists(hkVerb, L"SeparatorAfter"))
675 cmdFlags |= ECF_SEPARATORAFTER;
676
677 RegCloseKey(hkVerb);
678 }
679
680 if (((uFlags & CMF_NODEFAULT) && ntver >= _WIN32_WINNT_VISTA) ||
681 ((uFlags & CMF_DONOTPICKDEFAULT) && ntver >= _WIN32_WINNT_WIN7))
682 {
683 fState &= ~MFS_DEFAULT;
684 }
685
686 if (!hide)
687 {
688 if (cmdFlags & ECF_SEPARATORBEFORE)
689 {
690 if (InsertMenuItemAt(hMenu, *pIndexMenu, MF_SEPARATOR))
691 (*pIndexMenu)++;
692 }
693
694 UINT pos = *pIndexMenu;
695 int verbIndex = hkVerb ? FindVerbInDefaultVerbList(m_DefVerbs, info.Verb) : -1;
696 if (verbIndex >= 0)
697 {
698 if (verbIndex < iDefVerbIndex || iDefVerbIndex < 0)
699 {
700 iDefVerbIndex = verbIndex;
701 fState |= MFS_DEFAULT;
702 forceFirstPos = TRUE;
703 }
704 else
705 {
706 fState &= ~MFS_DEFAULT; // We have already set a better default
707 pos = indexDefault;
708 }
709 }
710 else if (iDefVerbIndex >= 0)
711 {
712 fState &= ~MFS_DEFAULT; // We have already set the default
713 if (forceFirstPos)
714 pos = indexDefault;
715 forceFirstPos = FALSE;
716 }
717
718 mii.fState = fState;
719 mii.wID = iIdCmdFirst + cIds;
720 if (InsertMenuItemW(hMenu, forceFirstPos ? indexFirst : pos, TRUE, &mii))
721 (*pIndexMenu)++;
722
723 if (cmdFlags & ECF_SEPARATORAFTER)
724 {
725 if (InsertMenuItemAt(hMenu, *pIndexMenu, MF_SEPARATOR))
726 (*pIndexMenu)++;
727 }
728
729 if (fState & MFS_DEFAULT)
730 indexDefault = *pIndexMenu; // This is where we want to insert "high priority" verbs
731 }
732 cIds++; // Always increment the id because it acts as the index into m_StaticEntries
733
734 if (mii.wID >= iIdCmdLast)
735 break;
736 }
737
738 return cIds;
739}
740
742 HMENU hMenu,
743 UINT indexMenu,
744 BOOL fByPosition,
745 UINT wID,
746 UINT fType,
747 LPCWSTR dwTypeData,
748 UINT fState)
749{
750 MENUITEMINFOW mii;
751 WCHAR wszText[100];
752
753 ZeroMemory(&mii, sizeof(mii));
754 mii.cbSize = sizeof(mii);
755 if (fType == MFT_SEPARATOR)
756 mii.fMask = MIIM_ID | MIIM_TYPE;
757 else if (fType == MFT_STRING)
758 {
760 if (IS_INTRESOURCE(dwTypeData))
761 {
762 if (LoadStringW(shell32_hInstance, LOWORD((ULONG_PTR)dwTypeData), wszText, _countof(wszText)))
763 mii.dwTypeData = wszText;
764 else
765 {
766 ERR("failed to load string %p\n", dwTypeData);
767 return;
768 }
769 }
770 else
771 mii.dwTypeData = (LPWSTR)dwTypeData;
772 mii.fState = fState;
773 }
774
775 mii.wID = wID;
776 mii.fType = fType;
777 InsertMenuItemW(hMenu, indexMenu, fByPosition, &mii);
778}
779
780void
782{
783 // Are we allowed to pick a default?
784 if ((uFlags & CMF_NODEFAULT) ||
785 ((uFlags & CMF_DONOTPICKDEFAULT) && RosGetProcessEffectiveVersion() >= _WIN32_WINNT_WIN7))
786 {
787 return;
788 }
789
790 // Do we already have a default?
791 if ((int)GetMenuDefaultItem(hMenu, MF_BYPOSITION, 0) != -1)
792 return;
793
794 // Does the view want to pick one?
795 INT_PTR forceDfm = 0;
796 if (SUCCEEDED(_DoCallback(DFM_GETDEFSTATICID, 0, &forceDfm)) && forceDfm)
797 {
798 for (UINT i = 0; i < _countof(g_StaticInvokeCmdMap); ++i)
799 {
800 UINT menuItemId = g_StaticInvokeCmdMap[i].IntVerb + DfltOffset - DCM_FCIDM_SHVIEW_OFFSET;
801 if (g_StaticInvokeCmdMap[i].DfmCmd == forceDfm &&
802 SetMenuDefaultItem(hMenu, menuItemId, MF_BYCOMMAND))
803 {
804 return;
805 }
806 }
807 }
808
809 // Don't want to pick something like cut or delete as the default but
810 // a static or dynamic verb is a good default.
812 SetMenuDefaultItem(hMenu, idCmdFirst, MF_BYCOMMAND);
813}
814
816WINAPI
818 HMENU hMenu,
819 UINT IndexMenu,
820 UINT idCmdFirst,
821 UINT idCmdLast,
822 UINT uFlags)
823{
824 HRESULT hr;
825 UINT idCmdNext = idCmdFirst;
826 UINT cIds = 0;
827
828 TRACE("BuildShellItemContextMenu entered\n");
829
830 /* Load static verbs and shell extensions from registry */
831 for (UINT i = 0; i < m_cKeys && !(uFlags & CMF_NOVERBS); i++)
832 {
835 }
836
837 /* Add static context menu handlers */
838 cIds = AddStaticContextMenusToMenu(hMenu, &IndexMenu, idCmdFirst, idCmdLast, uFlags);
839 m_iIdSCMFirst = 0; // FIXME: This should be = idCmdFirst?
840 m_iIdSCMLast = cIds;
841 idCmdNext = idCmdFirst + cIds;
842
843 /* Add dynamic context menu handlers */
844 cIds += AddShellExtensionsToMenu(hMenu, &IndexMenu, idCmdNext, idCmdLast, uFlags);
846 m_iIdSHELast = cIds;
847 idCmdNext = idCmdFirst + cIds;
848 TRACE("SH_LoadContextMenuHandlers first %x last %x\n", m_iIdSHEFirst, m_iIdSHELast);
849
850 /* Now let the callback add its own items */
851 QCMINFO qcminfo = {hMenu, IndexMenu, idCmdNext, idCmdLast, NULL};
853 {
854 UINT added = qcminfo.idCmdFirst - idCmdNext;
855 cIds += added;
856 IndexMenu += added;
858 m_iIdCBLast = cIds;
859 idCmdNext = idCmdFirst + cIds;
860 }
861
862 //TODO: DFM_MERGECONTEXTMENU_BOTTOM
863
864 UINT idDefaultOffset = 0;
865 BOOL isBackgroundMenu = !m_cidl;
866 if (!(uFlags & CMF_VERBSONLY) && !isBackgroundMenu)
867 {
868 /* Get the attributes of the items */
869 SFGAOF rfg = SFGAO_BROWSABLE | SFGAO_CANCOPY | SFGAO_CANLINK | SFGAO_CANMOVE | SFGAO_CANDELETE | SFGAO_CANRENAME | SFGAO_HASPROPSHEET | SFGAO_FILESYSTEM | SFGAO_FOLDER;
870 hr = m_psf->GetAttributesOf(m_cidl, m_apidl, &rfg);
872 return MAKE_HRESULT(SEVERITY_SUCCESS, 0, cIds);
873
874 /* Add the default part of the menu */
875 HMENU hmenuDefault = LoadMenuW(_AtlBaseModule.GetResourceInstance(), L"MENU_SHV_FILE");
876
877 /* Remove uneeded entries */
878 if (!(rfg & SFGAO_CANMOVE))
879 DeleteMenu(hmenuDefault, IDM_CUT, MF_BYCOMMAND);
880 if (!(rfg & SFGAO_CANCOPY))
881 DeleteMenu(hmenuDefault, IDM_COPY, MF_BYCOMMAND);
882 if (!((rfg & SFGAO_FILESYSTEM) && HasClipboardData()))
883 DeleteMenu(hmenuDefault, IDM_INSERT, MF_BYCOMMAND);
884 if (!(rfg & SFGAO_CANLINK))
885 DeleteMenu(hmenuDefault, IDM_CREATELINK, MF_BYCOMMAND);
886 if (!(rfg & SFGAO_CANDELETE))
887 DeleteMenu(hmenuDefault, IDM_DELETE, MF_BYCOMMAND);
888 if (!(rfg & SFGAO_CANRENAME) || !(uFlags & CMF_CANRENAME))
889 DeleteMenu(hmenuDefault, IDM_RENAME, MF_BYCOMMAND);
890 if (!(rfg & SFGAO_HASPROPSHEET))
891 DeleteMenu(hmenuDefault, IDM_PROPERTIES, MF_BYCOMMAND);
892
893 idDefaultOffset = idCmdNext;
894 UINT idMax = Shell_MergeMenus(hMenu, GetSubMenu(hmenuDefault, 0), IndexMenu, idCmdNext, idCmdLast, 0);
895 m_iIdDfltFirst = cIds;
896 cIds += idMax - idCmdNext;
897 m_iIdDfltLast = cIds;
898
899 DestroyMenu(hmenuDefault);
900 }
901
902 TryPickDefault(hMenu, idCmdFirst, idDefaultOffset, uFlags);
903
904 // TODO: DFM_MERGECONTEXTMENU_TOP
905
906 return MAKE_HRESULT(SEVERITY_SUCCESS, 0, cIds);
907}
908
910{
911 HRESULT hr;
912
914 hr = OleGetClipboard(&pda);
916 return hr;
917
918 FORMATETC formatetc2;
919 STGMEDIUM medium2;
921
922 DWORD dwKey= 0;
923
924 if (SUCCEEDED(pda->GetData(&formatetc2, &medium2)))
925 {
926 DWORD * pdwFlag = (DWORD*)GlobalLock(medium2.hGlobal);
927 if (pdwFlag)
928 {
929 if (*pdwFlag == DROPEFFECT_COPY)
930 dwKey = MK_CONTROL;
931 else
932 dwKey = MK_SHIFT;
933 }
934 else
935 {
936 ERR("No drop effect obtained\n");
937 }
938 GlobalUnlock(medium2.hGlobal);
939 }
940
941 if (bLink)
942 {
943 dwKey = MK_CONTROL|MK_SHIFT;
944 }
945
947 if (m_cidl)
948 hr = m_psf->GetUIObjectOf(NULL, 1, &m_apidl[0], IID_NULL_PPV_ARG(IDropTarget, &pdrop));
949 else
950 hr = m_psf->CreateViewObject(NULL, IID_PPV_ARG(IDropTarget, &pdrop));
951
953 return hr;
954
955 SHSimulateDrop(pdrop, pda, dwKey, NULL, NULL);
956
957 TRACE("CP result %x\n", hr);
958 return S_OK;
959}
960
963{
965 return E_FAIL;
966}
967
969{
970 if (!m_cidl || !m_pDataObj)
971 return E_FAIL;
972
974 HRESULT hr = m_psf->CreateViewObject(NULL, IID_PPV_ARG(IDropTarget, &pDT));
976 return hr;
977
979
980 return S_OK;
981}
982
984{
985 if (!m_cidl || !m_pDataObj)
986 return E_FAIL;
987
991 return hr;
992
993 DWORD grfKeyState = (lpcmi->fMask & CMIC_MASK_SHIFT_DOWN) ? MK_SHIFT : 0;
994 SHSimulateDrop(pDT, m_pDataObj, grfKeyState, NULL, NULL);
995
996 return S_OK;
997}
998
1000{
1001 if (!m_cidl || !m_pDataObj)
1002 return E_FAIL;
1003
1004 FORMATETC formatetc;
1006 STGMEDIUM medium = {0};
1007 medium.tymed = TYMED_HGLOBAL;
1008 medium.hGlobal = GlobalAlloc(GHND, sizeof(DWORD));
1009 DWORD* pdwFlag = (DWORD*)GlobalLock(medium.hGlobal);
1010 if (pdwFlag)
1011 *pdwFlag = bCopy ? DROPEFFECT_COPY : DROPEFFECT_MOVE;
1012 GlobalUnlock(medium.hGlobal);
1013 m_pDataObj->SetData(&formatetc, &medium, TRUE);
1014
1017 return hr;
1018
1019 return S_OK;
1020}
1021
1023{
1025 HRESULT hr;
1026
1027 if (!m_site || !m_cidl)
1028 return E_FAIL;
1029
1030 /* Get a pointer to the shell browser */
1033 return hr;
1034
1036 hr = psb->QueryActiveShellView(&lpSV);
1038 return hr;
1039
1040 SVSIF selFlags = SVSI_DESELECTOTHERS | SVSI_EDIT | SVSI_ENSUREVISIBLE | SVSI_FOCUSED | SVSI_SELECT;
1041 hr = lpSV->SelectItem(m_apidl[0], selFlags);
1043 return hr;
1044
1045 return S_OK;
1046}
1047
1048HRESULT
1051{
1053
1054 // We are asked to run the default property sheet
1055 if (hr == S_FALSE)
1056 {
1058 }
1059
1060 return hr;
1061}
1062
1063HRESULT
1065{
1066 ERR("TODO: Undo\n");
1067 return E_NOTIMPL;
1068}
1069
1070HRESULT
1072{
1073 HRESULT hr = E_FAIL;
1074 if (!m_pDataObj)
1075 {
1076 ERR("m_pDataObj is NULL\n");
1077 return hr;
1078 }
1079
1080 CComPtr<IContextMenu> pContextMenu;
1081 if (bCopy)
1082 hr = SHCoCreateInstance(NULL, &CLSID_CopyToMenu, NULL,
1083 IID_PPV_ARG(IContextMenu, &pContextMenu));
1084 else
1085 hr = SHCoCreateInstance(NULL, &CLSID_MoveToMenu, NULL,
1086 IID_PPV_ARG(IContextMenu, &pContextMenu));
1088 return hr;
1089
1091 hr = pContextMenu->QueryInterface(IID_PPV_ARG(IShellExtInit, &pInit));
1093 return hr;
1094
1095 hr = pInit->Initialize(m_pidlFolder, m_pDataObj, NULL);
1097 return hr;
1098
1099 if (bCopy)
1100 lpici->lpVerb = "copyto";
1101 else
1102 lpici->lpVerb = "moveto";
1103
1104 return pContextMenu->InvokeCommand((LPCMINVOKECOMMANDINFO)lpici);
1105}
1106
1107// This code is taken from CNewMenu and should be shared between the 2 classes
1108HRESULT
1111{
1112 WCHAR wszPath[MAX_PATH];
1113 WCHAR wszName[MAX_PATH];
1114 WCHAR wszNewFolder[25];
1115 HRESULT hr;
1116
1117 /* Get folder path */
1120 return hr;
1121
1122 if (!LoadStringW(shell32_hInstance, IDS_NEWFOLDER, wszNewFolder, _countof(wszNewFolder)))
1123 return E_FAIL;
1124
1125 /* Create the name of the new directory */
1126 if (!PathYetAnotherMakeUniqueName(wszName, wszPath, NULL, wszNewFolder))
1127 return E_FAIL;
1128
1129 /* Create the new directory and show the appropriate dialog in case of error */
1130 if (SHCreateDirectory(lpici->hwnd, wszName) != ERROR_SUCCESS)
1131 return E_FAIL;
1132
1133 /* Show and select the new item in the def view */
1134 LPITEMIDLIST pidl;
1135 PITEMID_CHILD pidlNewItem;
1137
1138 /* Notify the view object about the new item */
1140
1141 if (!m_site)
1142 return S_OK;
1143
1144 /* Get a pointer to the shell view */
1147 return S_OK;
1148
1149 /* Attempt to get the pidl of the new item */
1150 hr = SHILCreateFromPathW(wszName, &pidl, NULL);
1152 return hr;
1153
1154 pidlNewItem = ILFindLastID(pidl);
1155
1156 hr = psv->SelectItem(pidlNewItem, SVSI_DESELECTOTHERS | SVSI_EDIT | SVSI_ENSUREVISIBLE |
1157 SVSI_FOCUSED | SVSI_SELECT);
1159 return hr;
1160
1161 SHFree(pidl);
1162
1163 return S_OK;
1164}
1165
1167{
1168 POSITION it = m_DynamicEntries.GetHeadPosition();
1169 while (it != NULL)
1170 {
1172
1173 if (idCmd >= info.iIdCmdFirst + info.NumIds)
1174 continue;
1175
1176 if (idCmd < info.iIdCmdFirst || idCmd > info.iIdCmdFirst + info.NumIds)
1177 return NULL;
1178
1179 return &info;
1180 }
1181
1182 return NULL;
1183}
1184
1185BOOL
1187{
1188 WCHAR UnicodeStr[MAX_VERB];
1189
1190 /* Loop through all the static verbs looking for a match */
1191 for (UINT i = 0; i < _countof(g_StaticInvokeCmdMap); i++)
1192 {
1193 /* We can match both ANSI and unicode strings */
1194 if (IsUnicode)
1195 {
1196 /* The static verbs are ANSI, get a unicode version before doing the compare */
1197 SHAnsiToUnicode(g_StaticInvokeCmdMap[i].szStringVerb, UnicodeStr, MAX_VERB);
1198 if (!wcscmp(UnicodeStr, (LPWSTR)Verb))
1199 {
1200 /* Return the Corresponding Id */
1201 *idCmd = g_StaticInvokeCmdMap[i].IntVerb;
1202 return TRUE;
1203 }
1204 }
1205 else
1206 {
1207 if (!strcmp(g_StaticInvokeCmdMap[i].szStringVerb, (LPSTR)Verb))
1208 {
1209 *idCmd = g_StaticInvokeCmdMap[i].IntVerb;
1210 return TRUE;
1211 }
1212 }
1213 }
1214
1215 return FALSE;
1216}
1217
1218HRESULT
1221{
1222 TRACE("verb %p first %x last %x\n", lpcmi->lpVerb, m_iIdSHEFirst, m_iIdSHELast);
1223
1224 UINT idCmd = LOWORD(lpcmi->lpVerb);
1226 if (!pEntry)
1227 return E_FAIL;
1228
1229 /* invoke the dynamic context menu */
1230 lpcmi->lpVerb = MAKEINTRESOURCEA(idCmd - pEntry->iIdCmdFirst);
1231 return pEntry->pCM->InvokeCommand((LPCMINVOKECOMMANDINFO)lpcmi);
1232}
1233
1234DWORD
1236{
1238 HWND hwndTree;
1239 LPCWSTR FlagsName;
1240 WCHAR wszKey[sizeof("shell\\") + MAX_VERB];
1241 HRESULT hr;
1242 DWORD wFlags;
1243 DWORD cbVerb;
1244
1245 if (!m_site)
1246 return 0;
1247
1248 /* Get a pointer to the shell browser */
1250 if (FAILED(hr))
1251 return 0;
1252
1253 /* See if we are in Explore or Browse mode. If the browser's tree is present, we are in Explore mode.*/
1254 if (SUCCEEDED(psb->GetControlWindow(FCW_TREE, &hwndTree)) && hwndTree)
1255 FlagsName = L"ExplorerFlags";
1256 else
1257 FlagsName = L"BrowserFlags";
1258
1260 if (SUCCEEDED(psb->QueryInterface(IID_PPV_ARG(ICommDlgBrowser, &pcdb))))
1261 {
1262 if (LOBYTE(GetVersion()) < 6 || FlagsName[0] == 'E')
1263 return 0; // Don't browse in-place
1264 }
1265
1266 /* Try to get the flag from the verb */
1267 hr = StringCbPrintfW(wszKey, sizeof(wszKey), L"shell\\%s", pEntry->Verb.GetString());
1269 return 0;
1270
1271 cbVerb = sizeof(wFlags);
1272 if (RegGetValueW(pEntry->hkClass, wszKey, FlagsName, RRF_RT_REG_DWORD, NULL, &wFlags, &cbVerb) == ERROR_SUCCESS)
1273 {
1274 return wFlags;
1275 }
1276
1277 return 0;
1278}
1279
1280HRESULT
1283{
1285 HRESULT hr;
1286
1287 if (!m_site)
1288 return E_FAIL;
1289
1290 /* Get a pointer to the shell browser */
1292 if (FAILED(hr))
1293 return hr;
1294
1295 PIDLIST_ABSOLUTE pidl;
1296 hr = SHILCombine(m_pidlFolder, pidlChild, &pidl);
1298 return hr;
1299
1300 hr = psb->BrowseObject(pidl, wFlags & ~SBSP_RELATIVE);
1301 ILFree(pidl);
1302 return hr;
1303}
1304
1305HRESULT
1307{
1308 const BOOL unicode = IsUnicode(*lpcmi);
1309
1310 LPITEMIDLIST pidlFull = ILCombine(m_pidlFolder, pidl);
1311 if (pidlFull == NULL)
1312 {
1313 return E_FAIL;
1314 }
1315
1316 WCHAR wszPath[MAX_PATH];
1317 BOOL bHasPath = SHGetPathFromIDListW(pidlFull, wszPath);
1318
1319 WCHAR wszDir[MAX_PATH];
1320
1321 SHELLEXECUTEINFOW sei = { sizeof(sei) };
1322 sei.fMask = SEE_MASK_CLASSKEY | SEE_MASK_IDLIST | (CmicFlagsToSeeFlags(lpcmi->fMask) & ~SEE_MASK_INVOKEIDLIST);
1323 sei.hwnd = lpcmi->hwnd;
1324 sei.nShow = lpcmi->nShow;
1325 sei.lpVerb = pEntry->Verb;
1326 sei.lpIDList = pidlFull;
1327 sei.hkeyClass = pEntry->hkClass;
1328 sei.dwHotKey = lpcmi->dwHotKey;
1329 sei.hIcon = lpcmi->hIcon;
1330 sei.lpDirectory = wszDir;
1331
1332 if (unicode && !StrIsNullOrEmpty(lpcmi->lpDirectoryW))
1333 {
1334 sei.lpDirectory = lpcmi->lpDirectoryW;
1335 }
1336 else if (bHasPath)
1337 {
1338 wcscpy(wszDir, wszPath);
1339 PathRemoveFileSpec(wszDir);
1340 }
1341 else
1342 {
1343 if (!SHGetPathFromIDListW(m_pidlFolder, wszDir))
1344 *wszDir = UNICODE_NULL;
1345 }
1346
1347 if (bHasPath)
1348 sei.lpFile = wszPath;
1349
1350 CComHeapPtr<WCHAR> pszParamsW;
1351 if (unicode && !StrIsNullOrEmpty(lpcmi->lpParametersW))
1352 sei.lpParameters = lpcmi->lpParametersW;
1353 else if (!StrIsNullOrEmpty(lpcmi->lpParameters) && __SHCloneStrAtoW(&pszParamsW, lpcmi->lpParameters))
1354 sei.lpParameters = pszParamsW;
1355
1356 if (!sei.lpClass && (lpcmi->fMask & (CMIC_MASK_HASLINKNAME | CMIC_MASK_HASTITLE)) && unicode)
1357 sei.lpClass = lpcmi->lpTitleW; // Forward .lnk path from CShellLink::DoOpen (for consrv STARTF_TITLEISLINKNAME)
1358
1359 ShellExecuteExW(&sei);
1360 ILFree(pidlFull);
1361
1362 return S_OK;
1363}
1364
1365HRESULT
1368{
1369 INT iCmd = LOWORD(lpcmi->lpVerb);
1370 HRESULT hr;
1371 UINT i;
1372
1373 POSITION it = m_StaticEntries.FindIndex(iCmd);
1374
1375 if (it == NULL)
1376 return E_INVALIDARG;
1377
1379
1380 CRegKey VerbKey;
1381 WCHAR VerbKeyPath[sizeof("shell\\") + MAX_VERB];
1382 hr = StringCbPrintfW(VerbKeyPath, sizeof(VerbKeyPath), L"shell\\%s", pEntry->Verb.GetString());
1383 if (SUCCEEDED(hr) && m_pDataObj &&
1384 VerbKey.Open(pEntry->hkClass, VerbKeyPath, KEY_READ) == ERROR_SUCCESS)
1385 {
1386 CLSID clsid;
1387
1388 DWORD KeyState = 0;
1389 if (lpcmi->fMask & CMIC_MASK_SHIFT_DOWN)
1390 KeyState |= MK_SHIFT;
1391 if (lpcmi->fMask & CMIC_MASK_CONTROL_DOWN)
1392 KeyState |= MK_CONTROL;
1393
1394 POINTL *pPtl = NULL;
1395 C_ASSERT(sizeof(POINT) == sizeof(POINTL));
1396 if (lpcmi->fMask & CMIC_MASK_PTINVOKE)
1397 pPtl = (POINTL*)&lpcmi->ptInvoke;
1398
1400 hr = SHELL_GetRegCLSID(VerbKey, L"command", L"DelegateExecute", clsid);
1401 if (SUCCEEDED(hr))
1402 hr = CoCreateInstance(clsid, NULL, CLSCTX_ALL, IID_PPV_ARG(IExecuteCommand, &pEC));
1403 if (SUCCEEDED(hr))
1404 {
1407 return InvokeIExecuteCommandWithDataObject(pEC, pEntry->Verb.GetString(), pPB, m_pDataObj,
1408 lpcmi, static_cast<IContextMenu*>(this));
1409 }
1410
1412 hr = SHELL_GetRegCLSID(VerbKey, L"DropTarget", L"CLSID", clsid);
1413 if (SUCCEEDED(hr))
1414 hr = CoCreateInstance(clsid, NULL, CLSCTX_ALL, IID_PPV_ARG(IDropTarget, &pDT));
1415 if (SUCCEEDED(hr))
1416 {
1419 IUnknown_SetSite(pDT, static_cast<IContextMenu*>(this));
1420 IUnknown_InitializeCommand(pDT, pEntry->Verb.GetString(), pPB);
1421 hr = SHSimulateDrop(pDT, m_pDataObj, KeyState, pPtl, NULL);
1422 IUnknown_SetSite(pDT, NULL);
1423 return hr;
1424 }
1425 }
1426
1427 /* Get the browse flags to see if we need to browse */
1429
1430 for (i=0; i < m_cidl; i++)
1431 {
1432 /* Check if we need to browse */
1433 if (wFlags)
1434 {
1435 hr = TryToBrowse(lpcmi, m_apidl[i], wFlags);
1436 if (SUCCEEDED(hr))
1437 {
1438 /* In WinXP if we have browsed, we don't open any more folders.
1439 * In Win7 we browse to the first folder we find and
1440 * open new windows for each of the rest of the folders */
1442 if (ntver >= _WIN32_WINNT_VISTA)
1443 wFlags = 0; // FIXME: = SBSP_NEWBROWSER | (wFlags & ~SBSP_SAMEBROWSER);
1444 else
1445 i = m_cidl;
1446
1447 continue;
1448 }
1449 }
1450
1451 InvokePidl(lpcmi, m_apidl[i], pEntry);
1452 }
1453
1454 return S_OK;
1455}
1456
1457HRESULT
1459 LPCMINVOKECOMMANDINFOEX lpcmi, WPARAM CmdId)
1460{
1461 BOOL Unicode = IsUnicode(*lpcmi);
1462 WCHAR lParamBuf[MAX_PATH];
1463 LPARAM lParam = 0;
1464
1465 if (Unicode && lpcmi->lpParametersW)
1466 lParam = (LPARAM)lpcmi->lpParametersW;
1467 else if (lpcmi->lpParameters)
1468 lParam = SHAnsiToUnicode(lpcmi->lpParameters, lParamBuf, _countof(lParamBuf)) ? (LPARAM)lParamBuf : 0;
1469
1470 HRESULT hr;
1471#if 0 // TODO: Try DFM_INVOKECOMMANDEX first.
1472 DFMICS dfmics = { sizeof(DFMICS), lpcmi->fMask, lParam, m_iIdSCMFirst?, m_iIdDfltLast?, (LPCMINVOKECOMMANDINFO)lpcmi, m_site };
1473 hr = _DoCallback(DFM_INVOKECOMMANDEX, CmdId, &dfmics);
1474 if (hr == E_NOTIMPL)
1475#endif
1476 hr = _DoCallback(DFM_INVOKECOMMAND, CmdId, (void*)lParam);
1477 return hr;
1478}
1479
1480HRESULT
1481WINAPI
1484{
1485 CMINVOKECOMMANDINFOEX LocalInvokeInfo = {};
1487 UINT CmdId;
1488
1489 /* Take a local copy of the fixed members of the
1490 struct as we might need to modify the verb */
1491 memcpy(&LocalInvokeInfo, lpcmi, min(sizeof(LocalInvokeInfo), lpcmi->cbSize));
1492
1493 /* Check if this is a string verb */
1494 if (!IS_INTRESOURCE(LocalInvokeInfo.lpVerb))
1495 {
1496 /* Get the ID which corresponds to this verb, and update our local copy */
1497 if (MapVerbToCmdId((LPVOID)LocalInvokeInfo.lpVerb, &CmdId, FALSE))
1498 LocalInvokeInfo.lpVerb = MAKEINTRESOURCEA(CmdId);
1499 }
1500
1501 CmdId = LOWORD(LocalInvokeInfo.lpVerb);
1502
1503 if (!m_DynamicEntries.IsEmpty() && CmdId >= m_iIdSHEFirst && CmdId < m_iIdSHELast)
1504 {
1505 LocalInvokeInfo.lpVerb -= m_iIdSHEFirst;
1506 Result = InvokeShellExt(&LocalInvokeInfo);
1507 return Result;
1508 }
1509
1510 if (!m_StaticEntries.IsEmpty() && CmdId >= m_iIdSCMFirst && CmdId < m_iIdSCMLast)
1511 {
1512 LocalInvokeInfo.lpVerb -= m_iIdSCMFirst;
1513 Result = InvokeRegVerb(&LocalInvokeInfo);
1514 // TODO: if (FAILED(Result) && !(lpcmi->fMask & CMIC_MASK_FLAG_NO_UI)) SHELL_ErrorBox(m_pSite, Result);
1515 return Result;
1516 }
1517
1518 if (m_iIdCBFirst != m_iIdCBLast && CmdId >= m_iIdCBFirst && CmdId < m_iIdCBLast)
1519 {
1520 Result = _DoInvokeCommandCallback(&LocalInvokeInfo, CmdId - m_iIdCBFirst);
1521 return Result;
1522 }
1523
1524 if (m_iIdDfltFirst != m_iIdDfltLast && CmdId >= m_iIdDfltFirst && CmdId < m_iIdDfltLast)
1525 {
1526 CmdId -= m_iIdDfltFirst;
1527 /* See the definitions of IDM_CUT and co to see how this works */
1528 CmdId += DCM_FCIDM_SHVIEW_OFFSET;
1529 }
1530
1531 if (LocalInvokeInfo.cbSize >= sizeof(CMINVOKECOMMANDINFOEX) && (LocalInvokeInfo.fMask & CMIC_MASK_PTINVOKE))
1532 {
1533 if (m_pDataObj && FAILED_UNEXPECTEDLY(DataObject_SetOffset(m_pDataObj, &LocalInvokeInfo.ptInvoke)))
1534 {
1535 ERR("Unable to add OFFSET to DataObject!\n");
1536 }
1537 }
1538
1539 /* Check if this is a Id */
1540 switch (CmdId)
1541 {
1543 Result = DoPaste(&LocalInvokeInfo, FALSE);
1544 break;
1546 Result = DoPaste(&LocalInvokeInfo, TRUE);
1547 break;
1548 case FCIDM_SHVIEW_OPEN:
1550 Result = DoOpenOrExplore(&LocalInvokeInfo);
1551 break;
1552 case FCIDM_SHVIEW_COPY:
1553 case FCIDM_SHVIEW_CUT:
1554 Result = DoCopyOrCut(&LocalInvokeInfo, CmdId == FCIDM_SHVIEW_COPY);
1555 break;
1557 Result = DoCreateLink(&LocalInvokeInfo);
1558 break;
1560 Result = DoDelete(&LocalInvokeInfo);
1561 break;
1563 Result = DoRename(&LocalInvokeInfo);
1564 break;
1566 Result = DoProperties(&LocalInvokeInfo);
1567 break;
1569 Result = DoCreateNewFolder(&LocalInvokeInfo);
1570 break;
1572 Result = DoCopyToMoveToFolder(&LocalInvokeInfo, TRUE);
1573 break;
1575 Result = DoCopyToMoveToFolder(&LocalInvokeInfo, FALSE);
1576 break;
1577 case FCIDM_SHVIEW_UNDO:
1578 Result = DoUndo(&LocalInvokeInfo);
1579 break;
1580 default:
1582 ERR("Unhandled Verb %xl\n", LOWORD(LocalInvokeInfo.lpVerb));
1583 break;
1584 }
1585
1586 return Result;
1587}
1588
1589HRESULT
1590WINAPI
1592 UINT_PTR idCommand,
1593 UINT uFlags,
1594 UINT* lpReserved,
1595 LPSTR lpszName,
1596 UINT uMaxNameLen)
1597{
1598 /* We don't handle the help text yet */
1599 if (uFlags == GCS_HELPTEXTA ||
1600 uFlags == GCS_HELPTEXTW ||
1601 HIWORD(idCommand) != 0)
1602 {
1603 return E_NOTIMPL;
1604 }
1605
1606 UINT CmdId = LOWORD(idCommand);
1607
1608 if (!m_DynamicEntries.IsEmpty() && CmdId >= m_iIdSHEFirst && CmdId < m_iIdSHELast)
1609 {
1610 idCommand -= m_iIdSHEFirst;
1612 if (!pEntry)
1613 return E_FAIL;
1614
1615 idCommand -= pEntry->iIdCmdFirst;
1616 return pEntry->pCM->GetCommandString(idCommand,
1617 uFlags,
1618 lpReserved,
1619 lpszName,
1620 uMaxNameLen);
1621 }
1622
1623 if (!m_StaticEntries.IsEmpty() && CmdId >= m_iIdSCMFirst && CmdId < m_iIdSCMLast)
1624 {
1625 /* Validation just returns S_OK on a match. The id exists. */
1626 if (uFlags == GCS_VALIDATEA || uFlags == GCS_VALIDATEW)
1627 return S_OK;
1628
1629 CmdId -= m_iIdSCMFirst;
1630
1631 POSITION it = m_StaticEntries.FindIndex(CmdId);
1632
1633 if (it == NULL)
1634 return E_INVALIDARG;
1635
1637
1638 if (uFlags == GCS_VERBW)
1639 return StringCchCopyW((LPWSTR)lpszName, uMaxNameLen, pEntry->Verb);
1640
1641 if (uFlags == GCS_VERBA)
1642 {
1643 if (SHUnicodeToAnsi(pEntry->Verb, lpszName, uMaxNameLen))
1644 return S_OK;
1645 }
1646
1647 return E_INVALIDARG;
1648 }
1649
1650 //FIXME: Should we handle callbacks here?
1651 if (m_iIdDfltFirst != m_iIdDfltLast && CmdId >= m_iIdDfltFirst && CmdId < m_iIdDfltLast)
1652 {
1653 CmdId -= m_iIdDfltFirst;
1654 /* See the definitions of IDM_CUT and co to see how this works */
1655 CmdId += DCM_FCIDM_SHVIEW_OFFSET;
1656 }
1657
1658 /* Loop looking for a matching Id */
1659 for (UINT i = 0; i < _countof(g_StaticInvokeCmdMap); i++)
1660 {
1661 if (g_StaticInvokeCmdMap[i].IntVerb == CmdId)
1662 {
1663 /* Validation just returns S_OK on a match */
1664 if (uFlags == GCS_VALIDATEA || uFlags == GCS_VALIDATEW)
1665 return S_OK;
1666
1667 /* Return a copy of the ANSI verb */
1668 if (uFlags == GCS_VERBA)
1669 return StringCchCopyA(lpszName, uMaxNameLen, g_StaticInvokeCmdMap[i].szStringVerb);
1670
1671 /* Convert the ANSI verb to unicode and return that */
1672 if (uFlags == GCS_VERBW)
1673 {
1674 if (SHAnsiToUnicode(g_StaticInvokeCmdMap[i].szStringVerb, (LPWSTR)lpszName, uMaxNameLen))
1675 return S_OK;
1676 }
1677 }
1678 }
1679
1680 return E_INVALIDARG;
1681}
1682
1683HRESULT
1684WINAPI
1686 UINT uMsg,
1687 WPARAM wParam,
1688 LPARAM lParam)
1689{
1690 /* FIXME: Should we implement this as well? */
1691 return S_OK;
1692}
1693
1695{
1696 if (uMsg == WM_DRAWITEM)
1697 {
1698 DRAWITEMSTRUCT* pDrawStruct = reinterpret_cast<DRAWITEMSTRUCT*>(lParam);
1699 *CmdId = pDrawStruct->itemID;
1700 return S_OK;
1701 }
1702 else if (uMsg == WM_MEASUREITEM)
1703 {
1704 MEASUREITEMSTRUCT* pMeasureStruct = reinterpret_cast<MEASUREITEMSTRUCT*>(lParam);
1705 *CmdId = pMeasureStruct->itemID;
1706 return S_OK;
1707 }
1708
1709 return E_FAIL;
1710}
1711
1713{
1714 if (uMsg == WM_DRAWITEM)
1715 {
1716 DRAWITEMSTRUCT* pDrawStruct = reinterpret_cast<DRAWITEMSTRUCT*>(lParam);
1717 pDrawStruct->itemID = CmdId;
1718 return S_OK;
1719 }
1720 else if (uMsg == WM_MEASUREITEM)
1721 {
1722 MEASUREITEMSTRUCT* pMeasureStruct = reinterpret_cast<MEASUREITEMSTRUCT*>(lParam);
1723 pMeasureStruct->itemID = CmdId;
1724 return S_OK;
1725 }
1726
1727 return E_FAIL;
1728}
1729
1730HRESULT
1731WINAPI
1733 UINT uMsg,
1734 WPARAM wParam,
1735 LPARAM lParam,
1736 LRESULT *plResult)
1737{
1738 if (uMsg == WM_INITMENUPOPUP)
1739 {
1740 POSITION it = m_DynamicEntries.GetHeadPosition();
1741 while (it != NULL)
1742 {
1744 SHForwardContextMenuMsg(info.pCM, uMsg, wParam, lParam, plResult, TRUE);
1745 }
1746 return S_OK;
1747 }
1748
1749 UINT CmdId;
1750 HRESULT hr = SHGetMenuIdFromMenuMsg(uMsg, lParam, &CmdId);
1751 if (FAILED(hr))
1752 return S_FALSE;
1753
1754 if (CmdId < m_iIdSHEFirst || CmdId >= m_iIdSHELast)
1755 return S_FALSE;
1756
1757 CmdId -= m_iIdSHEFirst;
1759 if (pEntry)
1760 {
1761 SHSetMenuIdInMenuMsg(uMsg, lParam, CmdId - pEntry->iIdCmdFirst);
1762 SHForwardContextMenuMsg(pEntry->pCM, uMsg, wParam, lParam, plResult, TRUE);
1763 }
1764
1765 return S_OK;
1766}
1767
1768HRESULT
1769WINAPI
1771{
1772 m_site = pUnkSite;
1773 return S_OK;
1774}
1775
1776HRESULT
1777WINAPI
1779{
1780 if (!m_site)
1781 return E_FAIL;
1782
1783 return m_site->QueryInterface(riid, ppvSite);
1784}
1785
1786static
1787HRESULT
1789{
1790 return ShellObjectCreatorInit<CDefaultContextMenu>(pdcm, lpfn, riid, ppv);
1791}
1792
1793/*************************************************************************
1794 * SHCreateDefaultContextMenu [SHELL32.325] Vista API
1795 *
1796 */
1797
1798HRESULT
1799WINAPI
1801{
1802 HRESULT hr;
1803
1804 if (!ppv)
1805 return E_INVALIDARG;
1806
1809 return hr;
1810
1811 return S_OK;
1812}
1813
1814/*************************************************************************
1815 * CDefFolderMenu_Create2 [SHELL32.701]
1816 *
1817 */
1818
1819HRESULT
1820WINAPI
1822 PCIDLIST_ABSOLUTE pidlFolder,
1823 HWND hwnd,
1824 UINT cidl,
1826 IShellFolder *psf,
1827 LPFNDFMCALLBACK lpfn,
1828 UINT nKeys,
1829 const HKEY *ahkeyClsKeys,
1830 IContextMenu **ppcm)
1831{
1832 DEFCONTEXTMENU dcm;
1833 dcm.hwnd = hwnd;
1834 dcm.pcmcb = NULL;
1835 dcm.pidlFolder = pidlFolder;
1836 dcm.psf = psf;
1837 dcm.cidl = cidl;
1838 dcm.apidl = apidl;
1840 dcm.cKeys = nKeys;
1841 dcm.aKeys = ahkeyClsKeys;
1842
1845 return hr;
1846
1847 return S_OK;
1848}
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()
void WINAPI _InsertMenuItemW(HMENU hMenu, UINT indexMenu, BOOL fByPosition, UINT wID, UINT fType, LPCWSTR dwTypeData, UINT fState)
static HRESULT CDefaultContextMenu_CreateInstance(const DEFCONTEXTMENU *pdcm, LPFNDFMCALLBACK lpfn, REFIID riid, void **ppv)
HRESULT WINAPI SHCreateDefaultContextMenu(const DEFCONTEXTMENU *pdcm, REFIID riid, void **ppv)
static HRESULT SHELL_GetRegCLSID(HKEY hKey, LPCWSTR SubKey, LPCWSTR Value, CLSID &clsid)
static BOOL InsertMenuItemAt(HMENU hMenu, UINT Pos, UINT Flags)
HRESULT SHSetMenuIdInMenuMsg(UINT uMsg, LPARAM lParam, UINT CmdId)
#define DCM_FCIDM_SHVIEW_OFFSET
EXTERN_C HRESULT SHELL32_EnumDefaultVerbList(LPCWSTR List, UINT Index, LPWSTR Verb, SIZE_T cchMax)
static bool IsVerbListSeparator(WCHAR Ch)
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)
#define MAX_VERB
HRESULT SHGetMenuIdFromMenuMsg(UINT uMsg, LPARAM lParam, UINT *CmdId)
HRESULT CRecyclerDropTarget_CreateInstance(REFIID riid, LPVOID *ppvOut)
#define shell32_hInstance
UINT cchMax
int strcmp(const char *String1, const char *String2)
Definition: utclib.c:469
#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 STDMETHODCALLTYPE
Definition: bdasup.h:9
#define UNIMPLEMENTED
Definition: debug.h:118
HANDLE HKEY
Definition: registry.h:26
#define RegCloseKey(hKey)
Definition: registry.h:49
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)
virtual HRESULT STDMETHODCALLTYPE QueryService(REFGUID svc, REFIID riid, void **ppv)
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)
HRESULT DoCopyToMoveToFolder(LPCMINVOKECOMMANDINFOEX lpici, BOOL bCopy)
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 DoOpenOrExplore(LPCMINVOKECOMMANDINFOEX lpcmi)
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)
WPARAM wParam
Definition: combotst.c:138
LPARAM lParam
Definition: combotst.c:139
static UINT RosGetProcessEffectiveVersion(VOID)
Definition: compat_undoc.h:39
#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
#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
#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
LONG WINAPI RegOpenKeyW(HKEY hKey, LPCWSTR lpSubKey, PHKEY phkResult)
Definition: reg.c:3268
UINT uFlags
Definition: api.c:59
#define GetProcessHeap()
Definition: compat.h:736
#define HeapAlloc
Definition: compat.h:733
#define ERROR_NO_MORE_ITEMS
Definition: compat.h:105
#define MAX_PATH
Definition: compat.h:34
#define HeapFree(x, y, z)
Definition: compat.h:735
#define FAILED_UNEXPECTEDLY(hr)
Definition: precomp.h:121
int WINAPI lstrcmpiA(LPCSTR str1, LPCSTR str2)
Definition: locale.c:4224
HRESULT WINAPI OleSetClipboard(IDataObject *data)
Definition: clipboard.c:2199
HRESULT WINAPI OleGetClipboard(IDataObject **obj)
Definition: clipboard.c:2249
HRESULT WINAPI DECLSPEC_HOTPATCH CoCreateInstance(REFCLSID rclsid, LPUNKNOWN pUnkOuter, DWORD dwClsContext, REFIID iid, LPVOID *ppv)
Definition: compobj.c:3325
HRESULT WINAPI CLSIDFromString(LPCOLESTR idstr, LPCLSID id)
Definition: compobj.c:2338
#define RRF_RT_REG_DWORD
Definition: driver.c:578
#define RRF_RT_REG_SZ
Definition: driver.c:575
#define CmicFlagsToSeeFlags(flags)
Definition: precomp.h:159
#define VERBKEY_CCHMAX
Definition: precomp.h:131
EXTERN_C HRESULT IUnknown_InitializeCommand(_In_ IUnknown *pUnk, _In_ PCWSTR pszCommandName, _In_opt_ IPropertyBag *pPB)
Definition: utils.cpp:1294
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:1348
HRESULT SHELL32_ShowPropertiesDialog(IDataObject *pdtobj)
Definition: shlfolder.cpp:532
BOOL RegValueExists(HKEY hKey, LPCWSTR Name)
Definition: utils.h:11
void WINAPI SHFree(LPVOID pv)
Definition: shellole.c:326
HRESULT WINAPI SHCoCreateInstance(LPCWSTR aclsid, const CLSID *clsid, LPUNKNOWN pUnkOuter, REFIID refiid, LPVOID *ppv)
Definition: shellole.c:105
BOOL WINAPI PathYetAnotherMakeUniqueName(LPWSTR buffer, LPCWSTR path, LPCWSTR shortname, LPCWSTR longname)
Definition: shellpath.c:699
BOOL WINAPI SHSimulateDrop(IDropTarget *pDrop, IDataObject *pDataObj, DWORD grfKeyState, PPOINTL lpPt, DWORD *pdwEffect)
Definition: ordinal.c:1828
HRESULT WINAPI IUnknown_QueryService(IUnknown *, REFGUID, REFIID, LPVOID *)
Definition: ordinal.c:1501
HRESULT WINAPI SHCreatePropertyBagOnRegKey(HKEY hKey, LPCWSTR subkey, DWORD grfMode, REFIID riid, void **ppv)
Definition: ordinal.c:5193
HRESULT WINAPI IUnknown_SetSite(IUnknown *obj, IUnknown *site)
Definition: ordinal.c:1411
DWORD WINAPI SHAnsiToUnicode(LPCSTR lpSrcStr, LPWSTR lpDstStr, int iLen)
Definition: string.c:2667
INT WINAPI SHUnicodeToAnsi(LPCWSTR lpSrcStr, LPSTR lpDstStr, INT iLen)
Definition: string.c:2791
#define MAKE_HRESULT(sev, fac, code)
Definition: dmerror.h:30
static IShellFolder IShellItem **static IBindCtx LPITEMIDLIST SFGAOF
Definition: ebrowser.c:83
#define InitFormatEtc(fe, cf, med)
Definition: editor.h:32
#define IDS_NEWFOLDER
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
unsigned short WORD
Definition: ntddk_ex.h:93
PWDFDEVICE_INIT pInit
FxAutoRegKey hKey
PLIST_ENTRY pEntry
Definition: fxioqueue.cpp:4484
return pTarget Start()
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
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
LPVOID NTAPI GlobalLock(HGLOBAL hMem)
Definition: heapmem.c:755
BOOL NTAPI GlobalUnlock(HGLOBAL hMem)
Definition: heapmem.c:1190
HGLOBAL NTAPI GlobalAlloc(UINT uFlags, SIZE_T dwBytes)
Definition: heapmem.c:368
VOID WINAPI CoTaskMemFree(LPVOID ptr)
Definition: ifs.c:442
REFIID riid
Definition: atlbase.h:39
REFIID LPVOID * ppv
Definition: atlbase.h:39
#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
#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 memcpy(s1, s2, n)
Definition: mkisofs.h:878
const IID IID_IObjectWithSite
static HMODULE MODULEINFO DWORD cb
Definition: module.c:33
static const CLSID *static CLSID *static const GUID VARIANT VARIANT *static IServiceProvider DWORD *static HMENU
Definition: ordinal.c:63
#define min(a, b)
Definition: monoChain.cc:55
#define _In_
Definition: ms_sal.h:308
REFCLSID clsid
Definition: msctf.c:82
unsigned __int3264 UINT_PTR
Definition: mstsclib_h.h:274
unsigned int * PUINT
Definition: ndis.h:50
unsigned int UINT
Definition: ndis.h:50
#define KEY_READ
Definition: nt_native.h:1023
#define UNICODE_NULL
#define L(x)
Definition: ntvdm.h:50
#define STGM_READ
Definition: objbase.h:917
#define LOWORD(l)
Definition: pedump.c:82
short SHORT
Definition: pedump.c:59
long LONG
Definition: pedump.c:60
PITEMID_CHILD * _ILCopyaPidl(PCUITEMID_CHILD_ARRAY apidlsrc, UINT cidl)
Definition: pidl.c:2617
LPITEMIDLIST WINAPI ILClone(LPCITEMIDLIST pidl)
Definition: pidl.c:237
void WINAPI ILFree(LPITEMIDLIST pidl)
Definition: pidl.c:946
HRESULT WINAPI SHILCreateFromPathW(LPCWSTR path, LPITEMIDLIST *ppidl, DWORD *attributes)
Definition: pidl.c:401
LPITEMIDLIST WINAPI ILFindLastID(LPCITEMIDLIST pidl)
Definition: pidl.c:198
LPITEMIDLIST WINAPI ILCombine(LPCITEMIDLIST pidl1, LPCITEMIDLIST pidl2)
Definition: pidl.c:718
BOOL WINAPI SHGetPathFromIDListW(LPCITEMIDLIST pidl, LPWSTR pszPath)
Definition: pidl.c:1348
void _ILFreeaPidl(LPITEMIDLIST *apidl, UINT cidl)
Definition: pidl.c:2600
#define REFIID
Definition: guiddef.h:118
#define REFCLSID
Definition: guiddef.h:117
#define err(...)
DWORD WINAPI GetVersion()
Definition: redirtest.c:5
HRESULT WINAPI SHForwardContextMenuMsg(IUnknown *pUnk, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT *pResult, BOOL useIContextMenu2)
Definition: rosordinal.c:11
_Check_return_ _CRTIMP int __cdecl _wcsicmp(_In_z_ const wchar_t *_Str1, _In_z_ const wchar_t *_Str2)
_CRTIMP wchar_t *__cdecl wcscpy(_Out_writes_z_(_String_length_(_Source)+1) wchar_t *_Dest, _In_z_ const wchar_t *_Source)
_Check_return_ _CRTIMP int __cdecl wcscmp(_In_z_ const wchar_t *_Str1, _In_z_ const wchar_t *_Str2)
_Check_return_ _CRTIMP int __cdecl _wcsnicmp(_In_reads_or_z_(_MaxCount) const wchar_t *_Str1, _In_reads_or_z_(_MaxCount) const wchar_t *_Str2, _In_ size_t _MaxCount)
static __inline const char * wine_dbgstr_guid(const GUID *id)
Definition: debug.h:197
#define _WIN32_WINNT_WIN7
Definition: sdkddkver.h:28
#define _WIN32_WINNT_VISTA
Definition: sdkddkver.h:25
#define Ch(x, y, z)
Definition: sha2.c:141
static __inline LPWSTR __SHCloneStrAtoW(WCHAR **target, const char *source)
Definition: shell32_main.h:168
#define SEE_MASK_CLASSKEY
Definition: shellapi.h:26
#define SEE_MASK_IDLIST
Definition: shellapi.h:27
#define STATUS_SUCCESS
Definition: shellext.h:65
BOOL WINAPI DECLSPEC_HOTPATCH ShellExecuteExW(LPSHELLEXECUTEINFOW sei)
Definition: shlexec.cpp:2434
int WINAPI SHCreateDirectory(HWND hWnd, LPCWSTR path)
Definition: shlfileop.cpp:848
HRESULT hr
Definition: shlfolder.c:183
#define SID_IFolderView
#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_CMD_DELETE
Definition: shlobj.h:2608
#define CFSTR_SHELLIDLIST
Definition: shlobj.h:550
#define CFSTR_PREFERREDDROPEFFECT
Definition: shlobj.h:560
#define SHCNE_MKDIR
Definition: shlobj.h:1893
#define DFM_CMD_NEWFOLDER
Definition: shlobj.h:2613
#define DFM_CMD_COPY
Definition: shlobj.h:2610
#define DFM_CMD_PASTE
Definition: shlobj.h:2614
#define SHCNF_FLUSH
Definition: shlobj.h:1928
#define SHCNF_PATHW
Definition: shlobj.h:1925
#define DFM_CMD_PROPERTIES
Definition: shlobj.h:2612
HRESULT(CALLBACK * LPFNDFMCALLBACK)(_In_opt_ IShellFolder *, _In_opt_ HWND, _In_opt_ IDataObject *, UINT, WPARAM, LPARAM)
Definition: shlobj.h:2568
#define DFM_CMD_RENAME
Definition: shlobj.h:2620
#define DFM_CMD_LINK
Definition: shlobj.h:2611
#define PathRemoveFileSpec
Definition: shlwapi.h:1061
#define FCIDM_SHVIEW_CUT
Definition: shresdef.h:828
#define FCIDM_SHVIEW_OPEN
Definition: shresdef.h:855
#define FCIDM_SHVIEW_UNDO
Definition: shresdef.h:831
#define IDM_DELETE
Definition: shresdef.h:868
#define FCIDM_SHVIEW_COPY
Definition: shresdef.h:829
#define IDS_OPEN_VERB
Definition: shresdef.h:212
#define IDM_INSERT
Definition: shresdef.h:866
#define FCIDM_SHVIEW_INSERTLINK
Definition: shresdef.h:832
#define IDS_FIND_VERB
Definition: shresdef.h:216
#define FCIDM_SHVIEW_NEWFOLDER
Definition: shresdef.h:851
#define IDM_RENAME
Definition: shresdef.h:869
#define IDM_COPY
Definition: shresdef.h:865
#define FCIDM_SHVIEW_EXPLORE
Definition: shresdef.h:854
#define FCIDM_SHVIEW_PROPERTIES
Definition: shresdef.h:827
#define IDS_EXPLORE_VERB
Definition: shresdef.h:213
#define IDM_CUT
Definition: shresdef.h:864
#define IDM_CREATELINK
Definition: shresdef.h:867
#define IDS_PRINT_VERB
Definition: shresdef.h:217
#define FCIDM_SHVIEW_COPYTO
Definition: shresdef.h:833
#define FCIDM_SHVIEW_MOVETO
Definition: shresdef.h:834
#define FCIDM_SHVIEW_DELETE
Definition: shresdef.h:826
#define FCIDM_SHVIEW_RENAME
Definition: shresdef.h:848
#define FCIDM_SHVIEW_CREATELINK
Definition: shresdef.h:849
#define IDS_RUNAS_VERB
Definition: shresdef.h:214
#define IDS_EDIT_VERB
Definition: shresdef.h:215
#define FCIDM_SHVIEW_INSERT
Definition: shresdef.h:830
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 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:2550
IShellFolder * psf
Definition: shlobj.h:2552
IUnknown * punkAssociationInfo
Definition: shlobj.h:2555
PCUITEMID_CHILD_ARRAY apidl
Definition: shlobj.h:2554
const HKEY * aKeys
Definition: shlobj.h:2557
PCIDLIST_ABSOLUTE pidlFolder
Definition: shlobj.h:2551
CComPtr< IContextMenu > pCM
Definition: scsiwmi.h:51
UINT idCmdFirst
Definition: shlobj.h:1392
LPCWSTR lpDirectory
Definition: shellapi.h:334
LPCWSTR lpParameters
Definition: shellapi.h:333
LPWSTR dwTypeData
Definition: winuser.h:3272
int32_t INT_PTR
Definition: typedefs.h:64
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
ULONG_PTR SIZE_T
Definition: typedefs.h:80
int32_t INT
Definition: typedefs.h:58
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
#define ZeroMemory
Definition: winbase.h:1712
#define GHND
Definition: winbase.h:297
_In_ PSID _Out_writes_to_opt_ cchName LPSTR _Inout_ LPDWORD cchName
Definition: winbase.h:2767
_In_ DWORD _Out_ _In_ WORD wFlags
Definition: wincon.h:531
_In_ LONG _In_ HWND hwnd
Definition: winddi.h:4023
LONG_PTR LPARAM
Definition: windef.h:208
LONG_PTR LRESULT
Definition: windef.h:209
UINT_PTR WPARAM
Definition: windef.h:207
CONST void * LPCVOID
Definition: windef.h:191
#define WINAPI
Definition: msvc.h:6
#define S_FALSE
Definition: winerror.h:2357
#define SEVERITY_SUCCESS
Definition: winerror.h:64
#define HRESULT_FROM_WIN32(x)
Definition: winerror.h:92
#define HRESULT_CODE(hr)
Definition: winerror.h:76
#define HKEY_LOCAL_MACHINE
Definition: winreg.h:12
#define MK_SHIFT
Definition: winuser.h:2372
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:725
BOOL WINAPI SetMenuDefaultItem(_In_ HMENU, _In_ UINT, _In_ UINT)
int WINAPI LoadStringW(_In_opt_ HINSTANCE hInstance, _In_ UINT uID, _Out_writes_to_(cchBufferMax, return+1) LPWSTR lpBuffer, _In_ int cchBufferMax)
#define IS_INTRESOURCE(i)
Definition: winuser.h:580
UINT WINAPI RegisterClipboardFormatW(_In_ LPCWSTR)
BOOL WINAPI DeleteMenu(_In_ HMENU, _In_ UINT, _In_ UINT)
#define MFT_SEPARATOR
Definition: winuser.h:747
#define WM_DRAWITEM
Definition: winuser.h:1648
#define MIIM_STATE
Definition: winuser.h:724
#define MFS_DEFAULT
Definition: winuser.h:751
HMENU WINAPI GetSubMenu(_In_ HMENU, _In_ int)
#define WM_INITMENUPOPUP
Definition: winuser.h:1749
#define MK_CONTROL
Definition: winuser.h:2373
#define MF_SEPARATOR
Definition: winuser.h:137
#define MF_BYPOSITION
Definition: winuser.h:203
#define WM_MEASUREITEM
Definition: winuser.h:1649
#define MFS_ENABLED
Definition: winuser.h:753
#define MAKEINTRESOURCEA(i)
Definition: winuser.h:581
BOOL WINAPI DestroyMenu(_In_ HMENU)
#define MFT_STRING
Definition: winuser.h:749
HMENU WINAPI LoadMenuW(_In_opt_ HINSTANCE, _In_ LPCWSTR)
#define MIIM_DATA
Definition: winuser.h:729
#define MIIM_TYPE
Definition: winuser.h:728
BOOL WINAPI InsertMenuItemW(_In_ HMENU, _In_ UINT, _In_ BOOL, _In_ LPCMENUITEMINFOW)
_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
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
static void Initialize()
Definition: xlate.c:212
#define IID_PPV_ARG(Itype, ppType)
#define IID_NULL_PPV_ARG(Itype, ppType)
const char * LPCSTR
Definition: xmlstorage.h:183
char * LPSTR
Definition: xmlstorage.h:182
__wchar_t WCHAR
Definition: xmlstorage.h:180
WCHAR * LPWSTR
Definition: xmlstorage.h:184
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185