ReactOS 0.4.15-dev-8339-g4028de8
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
15// FIXME: 260 is correct, but should this be part of the SDK or just MAX_PATH?
16#define MAX_VERB 260
17#define VERBKEY_CCHMAX 64 // Note: 63+\0 seems to be the limit on XP
18
19static HRESULT
21{
22 WCHAR buf[42];
23 DWORD cb = sizeof(buf);
26}
27
28static inline bool RegValueExists(HKEY hKey, LPCWSTR Name)
29{
31}
32
34{
35 MENUITEMINFOW mii;
36 mii.cbSize = FIELD_OFFSET(MENUITEMINFOW, hbmpItem); // USER32 version agnostic
37 mii.fMask = MIIM_TYPE;
38 mii.fType = Flags;
39 return InsertMenuItemW(hMenu, Pos, TRUE, &mii);
40}
41
42typedef struct _DynamicShellEntry_
43{
49
50typedef struct _StaticShellEntry_
51{
55
56#define DCM_FCIDM_SHVIEW_OFFSET 0x7000 // Offset from the menu ids in the menu resource to FCIDM_SHVIEW_*
57
58//
59// verbs for InvokeCommandInfo
60//
61static const struct _StaticInvokeCommandMap_
62{
67{
68 { "RunAs", 0 }, // Unimplemented
69 { "Print", 0 }, // Unimplemented
70 { "Preview", 0 }, // Unimplemented
71 { "Open", FCIDM_SHVIEW_OPEN },
72 { CMDSTR_NEWFOLDERA, FCIDM_SHVIEW_NEWFOLDER, (SHORT)DFM_CMD_NEWFOLDER },
73 { "cut", FCIDM_SHVIEW_CUT, /* ? */ },
80 { "copyto", FCIDM_SHVIEW_COPYTO },
81 { "moveto", FCIDM_SHVIEW_MOVETO },
82};
83
85{
86 for (UINT i = 0; i < _countof(g_StaticInvokeCmdMap); ++i)
87 {
88 if (!lstrcmpiA(g_StaticInvokeCmdMap[i].szStringVerb, verba))
89 return (int)g_StaticInvokeCmdMap[i].DfmCmd;
90 }
91 return 0;
92}
93
94static inline bool IsVerbListSeparator(WCHAR Ch)
95{
96 return Ch == L' ' || Ch == L','; // learn.microsoft.com/en-us/windows/win32/shell/context-menu-handlers
97}
98
100{
101 for (UINT index = 0; *List; ++index)
102 {
103 while (IsVerbListSeparator(*List))
104 List++;
106 while (*List && !IsVerbListSeparator(*List))
107 List++;
108 // "List > Start" to verify that the list item is non-empty to avoid the edge case where Verb is "" and the list contains ",,"
109 if (!_wcsnicmp(Verb, Start, List - Start) && List > Start)
110 return index;
111 }
112 return -1;
113}
114
116 public CComObjectRootEx<CComMultiThreadModelNoCS>,
117 public IContextMenu3,
118 public IObjectWithSite,
119 public IServiceProvider
120{
121 private:
134 UINT m_iIdSHEFirst; /* first used id */
135 UINT m_iIdSHELast; /* last used id */
137 UINT m_iIdSCMFirst; /* first static used id */
138 UINT m_iIdSCMLast; /* last static used id */
139 UINT m_iIdCBFirst; /* first callback used id */
140 UINT m_iIdCBLast; /* last callback used id */
141 UINT m_iIdDfltFirst; /* first default part id */
142 UINT m_iIdDfltLast; /* last default part id */
143 HWND m_hwnd; /* window passed to callback */
145
147 void AddStaticEntry(const HKEY hkeyClass, const WCHAR *szVerb, UINT uFlags);
149 void TryPickDefault(HMENU hMenu, UINT idCmdFirst, UINT DfltOffset, UINT uFlags);
153 UINT AddShellExtensionsToMenu(HMENU hMenu, UINT* pIndexMenu, UINT idCmdFirst, UINT idCmdLast, UINT uFlags);
154 UINT AddStaticContextMenusToMenu(HMENU hMenu, UINT* IndexMenu, UINT iIdCmdFirst, UINT iIdCmdLast, UINT uFlags);
171 BOOL MapVerbToCmdId(PVOID Verb, PUINT idCmd, BOOL IsUnicode);
172
173 public:
177
178 // IContextMenu
179 STDMETHOD(QueryContextMenu)(HMENU hMenu, UINT indexMenu, UINT idCmdFirst, UINT idCmdLast, UINT uFlags) override;
181 STDMETHOD(GetCommandString)(UINT_PTR idCommand, UINT uFlags, UINT *lpReserved, LPSTR lpszName, UINT uMaxNameLen) override;
182
183 // IContextMenu2
185
186 // IContextMenu3
187 STDMETHOD(HandleMenuMsg2)(UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT *plResult) override;
188
189 // IObjectWithSite
190 STDMETHOD(SetSite)(IUnknown *pUnkSite) override;
191 STDMETHOD(GetSite)(REFIID riid, void **ppvSite) override;
192
193 // IServiceProvider
195 {
196 return IUnknown_QueryService(m_site, svc, riid, ppv);
197 }
198
200 COM_INTERFACE_ENTRY_IID(IID_IContextMenu, IContextMenu)
201 COM_INTERFACE_ENTRY_IID(IID_IContextMenu2, IContextMenu2)
202 COM_INTERFACE_ENTRY_IID(IID_IContextMenu3, IContextMenu3)
204 COM_INTERFACE_ENTRY_IID(IID_IServiceProvider, IServiceProvider)
206};
207
209 m_psf(NULL),
210 m_pmcb(NULL),
211 m_pfnmcb(NULL),
212 m_cidl(0),
213 m_apidl(NULL),
214 m_pDataObj(NULL),
215 m_aKeys(NULL),
216 m_cKeys(NULL),
217 m_pidlFolder(NULL),
218 m_bGroupPolicyActive(0),
219 m_iIdSHEFirst(0),
220 m_iIdSHELast(0),
221 m_iIdSCMFirst(0),
222 m_iIdSCMLast(0),
223 m_iIdCBFirst(0),
224 m_iIdCBLast(0),
225 m_iIdDfltFirst(0),
226 m_iIdDfltLast(0),
227 m_hwnd(NULL)
228{
230}
231
233{
234 for (POSITION it = m_DynamicEntries.GetHeadPosition(); it != NULL;)
235 {
236 const DynamicShellEntry& info = m_DynamicEntries.GetNext(it);
237 IUnknown_SetSite(info.pCM.p, NULL);
238 }
239 m_DynamicEntries.RemoveAll();
240 m_StaticEntries.RemoveAll();
241
242 for (UINT i = 0; i < m_cKeys; i++)
245
246 if (m_pidlFolder)
248 _ILFreeaPidl(const_cast<PITEMID_CHILD *>(m_apidl), m_cidl);
249}
250
252{
253 TRACE("cidl %u\n", pdcm->cidl);
254
255 if (!pdcm->pcmcb && !lpfn)
256 {
257 ERR("CDefaultContextMenu needs a callback!\n");
258 return E_INVALIDARG;
259 }
260
261 m_cidl = pdcm->cidl;
263 if (m_cidl && !m_apidl)
264 return E_OUTOFMEMORY;
265 m_psf = pdcm->psf;
266 m_pmcb = pdcm->pcmcb;
267 m_pfnmcb = lpfn;
268 m_hwnd = pdcm->hwnd;
269
270 m_cKeys = pdcm->cKeys;
271 if (pdcm->cKeys)
272 {
273 m_aKeys = (HKEY*)HeapAlloc(GetProcessHeap(), 0, sizeof(HKEY) * pdcm->cKeys);
274 if (!m_aKeys)
275 return E_OUTOFMEMORY;
276 memcpy(m_aKeys, pdcm->aKeys, sizeof(HKEY) * pdcm->cKeys);
277 }
278
279 m_psf->GetUIObjectOf(pdcm->hwnd, m_cidl, m_apidl, IID_NULL_PPV_ARG(IDataObject, &m_pDataObj));
280
281 if (pdcm->pidlFolder)
282 {
284 }
285 else
286 {
288 if (SUCCEEDED(m_psf->QueryInterface(IID_PPV_ARG(IPersistFolder2, &pf))))
289 {
290 if (FAILED(pf->GetCurFolder(&m_pidlFolder)))
291 ERR("GetCurFolder failed\n");
292 }
293 TRACE("pidlFolder %p\n", m_pidlFolder);
294 }
295
296 return S_OK;
297}
298
300{
301 if (m_pmcb)
302 {
303 return m_pmcb->CallBack(m_psf, m_hwnd, m_pDataObj, uMsg, wParam, (LPARAM)lParam);
304 }
305 else if(m_pfnmcb)
306 {
308 }
309
310 return E_FAIL;
311}
312
313void CDefaultContextMenu::AddStaticEntry(const HKEY hkeyClass, const WCHAR *szVerb, UINT uFlags)
314{
315 POSITION it = m_StaticEntries.GetHeadPosition();
316 while (it != NULL)
317 {
318 const StaticShellEntry& info = m_StaticEntries.GetNext(it);
319 if (info.Verb.CompareNoCase(szVerb) == 0)
320 {
321 /* entry already exists */
322 return;
323 }
324 }
325
326 TRACE("adding verb %s\n", debugstr_w(szVerb));
327
328 if (!wcsicmp(szVerb, L"open") && !(uFlags & CMF_NODEFAULT))
329 {
330 /* open verb is always inserted in front */
331 m_StaticEntries.AddHead({ szVerb, hkeyClass });
332 }
333 else
334 {
335 m_StaticEntries.AddTail({ szVerb, hkeyClass });
336 }
337}
338
340{
341 WCHAR wszName[VERBKEY_CCHMAX];
342 DWORD cchName, dwIndex = 0;
343 HKEY hShellKey;
344
345 LRESULT lres = RegOpenKeyExW(hKey, L"shell", 0, KEY_READ, &hShellKey);
346 if (lres != STATUS_SUCCESS)
347 return;
348
349 if (!*m_DefVerbs)
350 {
351 DWORD cb = sizeof(m_DefVerbs);
353 }
354
355 while(TRUE)
356 {
357 cchName = _countof(wszName);
358 if (RegEnumKeyExW(hShellKey, dwIndex++, wszName, &cchName, NULL, NULL, NULL, NULL) != ERROR_SUCCESS)
359 break;
360
361 AddStaticEntry(hKey, wszName, uFlags);
362 }
363
364 RegCloseKey(hShellKey);
365}
366
367static
368BOOL
370{
371 BOOL bRet = FALSE;
372 CComPtr<IDataObject> pDataObj;
373
374 if (SUCCEEDED(OleGetClipboard(&pDataObj)))
375 {
376 FORMATETC formatetc;
377
378 TRACE("pDataObj=%p\n", pDataObj.p);
379
380 /* Set the FORMATETC structure*/
381 InitFormatEtc(formatetc, RegisterClipboardFormatW(CFSTR_SHELLIDLIST), TYMED_HGLOBAL);
382 bRet = SUCCEEDED(pDataObj->QueryGetData(&formatetc));
383 }
384
385 return bRet;
386}
387
388BOOL
390{
391 POSITION it = m_DynamicEntries.GetHeadPosition();
392 while (it != NULL)
393 {
394 const DynamicShellEntry& info = m_DynamicEntries.GetNext(it);
395 if (info.ClassID == clsid)
396 return TRUE;
397 }
398
399 return FALSE;
400}
401
404{
405 HRESULT hr;
406 TRACE("LoadDynamicContextMenuHandler entered with This %p hKey %p pclsid %s\n", this, hKey, wine_dbgstr_guid(&clsid));
407
409 return S_OK;
410
413 if (FAILED(hr))
414 {
415 ERR("SHCoCreateInstance(IContextMenu) failed.clsid %s hr 0x%x\n", wine_dbgstr_guid(&clsid), hr);
416 return hr;
417 }
418
419 CComPtr<IShellExtInit> pExtInit;
420 hr = pcm->QueryInterface(IID_PPV_ARG(IShellExtInit, &pExtInit));
421 if (FAILED(hr))
422 {
423 ERR("IContextMenu->QueryInterface(IShellExtInit) failed.clsid %s hr 0x%x\n", wine_dbgstr_guid(&clsid), hr);
424 return hr;
425 }
426
427 hr = pExtInit->Initialize(m_pDataObj ? NULL : m_pidlFolder, m_pDataObj, hKey);
428 if (FAILED(hr))
429 {
430 WARN("IShellExtInit::Initialize failed.clsid %s hr 0x%x\n", wine_dbgstr_guid(&clsid), hr);
431 return hr;
432 }
433
434 if (m_site)
436
437 m_DynamicEntries.AddTail({ 0, 0, clsid, pcm });
438
439 return S_OK;
440}
441
442BOOL
444{
445 WCHAR wszName[MAX_PATH], wszBuf[MAX_PATH], *pwszClsid;
447 HRESULT hr;
448 HKEY hKey;
449
450 if (RegOpenKeyExW(hRootKey, L"shellex\\ContextMenuHandlers", 0, KEY_READ, &hKey) != ERROR_SUCCESS)
451 {
452 TRACE("RegOpenKeyExW failed\n");
453 return FALSE;
454 }
455
456 DWORD dwIndex = 0;
457 while (TRUE)
458 {
459 cchName = _countof(wszName);
460 if (RegEnumKeyExW(hKey, dwIndex++, wszName, &cchName, NULL, NULL, NULL, NULL) != ERROR_SUCCESS)
461 break;
462
463 /* Key name or key value is CLSID */
464 CLSID clsid;
465 hr = CLSIDFromString(wszName, &clsid);
466 if (hr == S_OK)
467 pwszClsid = wszName;
468 else
469 {
470 DWORD cchBuf = _countof(wszBuf);
471 if (RegGetValueW(hKey, wszName, NULL, RRF_RT_REG_SZ, NULL, wszBuf, &cchBuf) == ERROR_SUCCESS)
472 hr = CLSIDFromString(wszBuf, &clsid);
473 pwszClsid = wszBuf;
474 }
475
476 if (FAILED(hr))
477 {
478 ERR("CLSIDFromString failed for clsid %S hr 0x%x\n", pwszClsid, hr);
479 continue;
480 }
481
483 {
485 L"Software\\Microsoft\\Windows\\CurrentVersion\\Shell Extensions\\Approved",
486 pwszClsid,
488 NULL,
489 NULL,
491 {
492 ERR("Shell extension %s not approved!\n", pwszClsid);
493 continue;
494 }
495 }
496
498 if (FAILED(hr))
499 WARN("Failed to get context menu entires from shell extension! clsid: %S\n", pwszClsid);
500 }
501
503 return TRUE;
504}
505
506UINT
508{
509 UINT cIds = 0;
510
511 if (m_DynamicEntries.IsEmpty())
512 return cIds;
513
514 POSITION it = m_DynamicEntries.GetHeadPosition();
515 while (it != NULL)
516 {
518
519 HRESULT hr = info.pCM->QueryContextMenu(hMenu, *pIndexMenu, idCmdFirst + cIds, idCmdLast, uFlags);
520 if (SUCCEEDED(hr))
521 {
522 info.iIdCmdFirst = cIds;
523 info.NumIds = HRESULT_CODE(hr);
524 (*pIndexMenu) += info.NumIds;
525
526 cIds += info.NumIds;
527 if (idCmdFirst + cIds >= idCmdLast)
528 break;
529 }
530 TRACE("pEntry hr %x contextmenu %p cmdfirst %x num ids %x\n", hr, info.pCM.p, info.iIdCmdFirst, info.NumIds);
531 }
532 return cIds;
533}
534
535UINT
537 HMENU hMenu,
538 UINT* pIndexMenu,
539 UINT iIdCmdFirst,
540 UINT iIdCmdLast,
541 UINT uFlags)
542{
544 MENUITEMINFOW mii = { sizeof(mii) };
545 UINT idResource;
546 WCHAR wszDispVerb[80]; // The limit on XP. If the friendly string is longer, it falls back to the verb key.
547 UINT fState;
548 UINT cIds = 0, indexFirst = *pIndexMenu, indexDefault;
549 int iDefVerbIndex = -1;
550
552 mii.fType = MFT_STRING;
553
554 POSITION it = m_StaticEntries.GetHeadPosition();
555 bool first = true;
556 while (it != NULL)
557 {
559 BOOL forceFirstPos = FALSE;
560
561 fState = MFS_ENABLED;
562
563 /* set first entry as default */
564 if (first)
565 {
566 fState |= MFS_DEFAULT;
567 first = false;
568 }
569
570 if (info.Verb.CompareNoCase(L"open") == 0)
571 {
572 idResource = IDS_OPEN_VERB;
573 fState |= MFS_DEFAULT; /* override default when open verb is found */
574 forceFirstPos++;
575 }
576 else if (info.Verb.CompareNoCase(L"explore") == 0)
577 {
578 idResource = IDS_EXPLORE_VERB;
579 if (uFlags & CMF_EXPLORE)
580 {
581 fState |= MFS_DEFAULT;
582 forceFirstPos++;
583 }
584 }
585 else if (info.Verb.CompareNoCase(L"runas") == 0)
586 idResource = IDS_RUNAS_VERB;
587 else if (info.Verb.CompareNoCase(L"edit") == 0)
588 idResource = IDS_EDIT_VERB;
589 else if (info.Verb.CompareNoCase(L"find") == 0)
590 idResource = IDS_FIND_VERB;
591 else if (info.Verb.CompareNoCase(L"print") == 0)
592 idResource = IDS_PRINT_VERB;
593 else if (info.Verb.CompareNoCase(L"printto") == 0)
594 continue;
595 else
596 idResource = 0;
597
598 /* By default use verb for menu item name */
599 mii.dwTypeData = (LPWSTR)info.Verb.GetString();
600
601 WCHAR wszKey[sizeof("shell\\") + MAX_VERB];
602 HRESULT hr;
603 hr = StringCbPrintfW(wszKey, sizeof(wszKey), L"shell\\%s", info.Verb.GetString());
605 {
606 continue;
607 }
608
609 UINT cmdFlags = 0;
610 bool hide = false;
611 HKEY hkVerb;
612 if (idResource > 0)
613 {
614 if (!(uFlags & CMF_OPTIMIZEFORINVOKE))
615 {
616 if (LoadStringW(shell32_hInstance, idResource, wszDispVerb, _countof(wszDispVerb)))
617 mii.dwTypeData = wszDispVerb; /* use translated verb */
618 else
619 ERR("Failed to load string\n");
620 }
621
622 if (RegOpenKeyW(info.hkClass, wszKey, &hkVerb) != ERROR_SUCCESS)
623 hkVerb = NULL;
624 }
625 else
626 {
627 if (RegOpenKeyW(info.hkClass, wszKey, &hkVerb) == ERROR_SUCCESS)
628 {
629 if (!(uFlags & CMF_OPTIMIZEFORINVOKE))
630 {
631 DWORD cbVerb = sizeof(wszDispVerb);
632 LONG res = RegLoadMUIStringW(hkVerb, L"MUIVerb", wszDispVerb, cbVerb, NULL, 0, NULL);
633 if (res || !*wszDispVerb)
634 res = RegLoadMUIStringW(hkVerb, NULL, wszDispVerb, cbVerb, NULL, 0, NULL);
635
636 if (res == ERROR_SUCCESS && *wszDispVerb)
637 {
638 /* use description for the menu entry */
639 mii.dwTypeData = wszDispVerb;
640 }
641 }
642 }
643 else
644 {
645 hkVerb = NULL;
646 }
647 }
648
649 if (hkVerb)
650 {
651 if (!(uFlags & CMF_EXTENDEDVERBS))
652 hide = RegValueExists(hkVerb, L"Extended");
653
654 if (!hide)
655 hide = RegValueExists(hkVerb, L"ProgrammaticAccessOnly");
656
657 if (!hide && !(uFlags & CMF_DISABLEDVERBS))
658 hide = RegValueExists(hkVerb, L"LegacyDisable");
659
660 if (RegValueExists(hkVerb, L"NeverDefault"))
661 fState &= ~MFS_DEFAULT;
662
663 if (RegValueExists(hkVerb, L"SeparatorBefore"))
664 cmdFlags |= ECF_SEPARATORBEFORE;
665 if (RegValueExists(hkVerb, L"SeparatorAfter"))
666 cmdFlags |= ECF_SEPARATORAFTER;
667
668 RegCloseKey(hkVerb);
669 }
670
671 if (((uFlags & CMF_NODEFAULT) && ntver >= _WIN32_WINNT_VISTA) ||
672 ((uFlags & CMF_DONOTPICKDEFAULT) && ntver >= _WIN32_WINNT_WIN7))
673 {
674 fState &= ~MFS_DEFAULT;
675 }
676
677 if (!hide)
678 {
679 if (cmdFlags & ECF_SEPARATORBEFORE)
680 {
681 if (InsertMenuItemAt(hMenu, *pIndexMenu, MF_SEPARATOR))
682 (*pIndexMenu)++;
683 }
684
685 UINT pos = *pIndexMenu;
686 int verbIndex = hkVerb ? FindVerbInDefaultVerbList(m_DefVerbs, info.Verb) : -1;
687 if (verbIndex >= 0)
688 {
689 if (verbIndex < iDefVerbIndex || iDefVerbIndex < 0)
690 {
691 iDefVerbIndex = verbIndex;
692 fState |= MFS_DEFAULT;
693 forceFirstPos = TRUE;
694 }
695 else
696 {
697 fState &= ~MFS_DEFAULT; // We have already set a better default
698 pos = indexDefault;
699 }
700 }
701 else if (iDefVerbIndex >= 0)
702 {
703 fState &= ~MFS_DEFAULT; // We have already set the default
704 if (forceFirstPos)
705 pos = indexDefault;
706 forceFirstPos = FALSE;
707 }
708
709 mii.fState = fState;
710 mii.wID = iIdCmdFirst + cIds;
711 if (InsertMenuItemW(hMenu, forceFirstPos ? indexFirst : pos, TRUE, &mii))
712 (*pIndexMenu)++;
713
714 if (cmdFlags & ECF_SEPARATORAFTER)
715 {
716 if (InsertMenuItemAt(hMenu, *pIndexMenu, MF_SEPARATOR))
717 (*pIndexMenu)++;
718 }
719
720 if (fState & MFS_DEFAULT)
721 indexDefault = *pIndexMenu; // This is where we want to insert "high priority" verbs
722 }
723 cIds++; // Always increment the id because it acts as the index into m_StaticEntries
724
725 if (mii.wID >= iIdCmdLast)
726 break;
727 }
728
729 return cIds;
730}
731
733 HMENU hMenu,
734 UINT indexMenu,
735 BOOL fByPosition,
736 UINT wID,
737 UINT fType,
738 LPCWSTR dwTypeData,
739 UINT fState)
740{
741 MENUITEMINFOW mii;
742 WCHAR wszText[100];
743
744 ZeroMemory(&mii, sizeof(mii));
745 mii.cbSize = sizeof(mii);
746 if (fType == MFT_SEPARATOR)
747 mii.fMask = MIIM_ID | MIIM_TYPE;
748 else if (fType == MFT_STRING)
749 {
751 if (IS_INTRESOURCE(dwTypeData))
752 {
753 if (LoadStringW(shell32_hInstance, LOWORD((ULONG_PTR)dwTypeData), wszText, _countof(wszText)))
754 mii.dwTypeData = wszText;
755 else
756 {
757 ERR("failed to load string %p\n", dwTypeData);
758 return;
759 }
760 }
761 else
762 mii.dwTypeData = (LPWSTR)dwTypeData;
763 mii.fState = fState;
764 }
765
766 mii.wID = wID;
767 mii.fType = fType;
768 InsertMenuItemW(hMenu, indexMenu, fByPosition, &mii);
769}
770
771void
773{
774 // Are we allowed to pick a default?
775 if ((uFlags & CMF_NODEFAULT) ||
776 ((uFlags & CMF_DONOTPICKDEFAULT) && RosGetProcessEffectiveVersion() >= _WIN32_WINNT_WIN7))
777 {
778 return;
779 }
780
781 // Do we already have a default?
782 if ((int)GetMenuDefaultItem(hMenu, MF_BYPOSITION, 0) != -1)
783 return;
784
785 // Does the view want to pick one?
786 INT_PTR forceDfm = 0;
787 if (SUCCEEDED(_DoCallback(DFM_GETDEFSTATICID, 0, &forceDfm)) && forceDfm)
788 {
789 for (UINT i = 0; i < _countof(g_StaticInvokeCmdMap); ++i)
790 {
791 UINT menuItemId = g_StaticInvokeCmdMap[i].IntVerb + DfltOffset - DCM_FCIDM_SHVIEW_OFFSET;
792 if (g_StaticInvokeCmdMap[i].DfmCmd == forceDfm &&
793 SetMenuDefaultItem(hMenu, menuItemId, MF_BYCOMMAND))
794 {
795 return;
796 }
797 }
798 }
799
800 // Don't want to pick something like cut or delete as the default but
801 // a static or dynamic verb is a good default.
803 SetMenuDefaultItem(hMenu, idCmdFirst, MF_BYCOMMAND);
804}
805
807WINAPI
809 HMENU hMenu,
810 UINT IndexMenu,
811 UINT idCmdFirst,
812 UINT idCmdLast,
813 UINT uFlags)
814{
815 HRESULT hr;
816 UINT idCmdNext = idCmdFirst;
817 UINT cIds = 0;
818
819 TRACE("BuildShellItemContextMenu entered\n");
820
821 /* Load static verbs and shell extensions from registry */
822 for (UINT i = 0; i < m_cKeys && !(uFlags & CMF_NOVERBS); i++)
823 {
826 }
827
828 /* Add static context menu handlers */
829 cIds = AddStaticContextMenusToMenu(hMenu, &IndexMenu, idCmdFirst, idCmdLast, uFlags);
830 m_iIdSCMFirst = 0; // FIXME: This should be = idCmdFirst?
831 m_iIdSCMLast = cIds;
832 idCmdNext = idCmdFirst + cIds;
833
834 /* Add dynamic context menu handlers */
835 cIds += AddShellExtensionsToMenu(hMenu, &IndexMenu, idCmdNext, idCmdLast, uFlags);
837 m_iIdSHELast = cIds;
838 idCmdNext = idCmdFirst + cIds;
839 TRACE("SH_LoadContextMenuHandlers first %x last %x\n", m_iIdSHEFirst, m_iIdSHELast);
840
841 /* Now let the callback add its own items */
842 QCMINFO qcminfo = {hMenu, IndexMenu, idCmdNext, idCmdLast, NULL};
844 {
845 UINT added = qcminfo.idCmdFirst - idCmdNext;
846 cIds += added;
847 IndexMenu += added;
849 m_iIdCBLast = cIds;
850 idCmdNext = idCmdFirst + cIds;
851 }
852
853 //TODO: DFM_MERGECONTEXTMENU_BOTTOM
854
855 UINT idDefaultOffset = 0;
856 BOOL isBackgroundMenu = !m_cidl;
857 if (!(uFlags & CMF_VERBSONLY) && !isBackgroundMenu)
858 {
859 /* Get the attributes of the items */
860 SFGAOF rfg = SFGAO_BROWSABLE | SFGAO_CANCOPY | SFGAO_CANLINK | SFGAO_CANMOVE | SFGAO_CANDELETE | SFGAO_CANRENAME | SFGAO_HASPROPSHEET | SFGAO_FILESYSTEM | SFGAO_FOLDER;
861 hr = m_psf->GetAttributesOf(m_cidl, m_apidl, &rfg);
863 return MAKE_HRESULT(SEVERITY_SUCCESS, 0, cIds);
864
865 /* Add the default part of the menu */
866 HMENU hmenuDefault = LoadMenu(_AtlBaseModule.GetResourceInstance(), L"MENU_SHV_FILE");
867
868 /* Remove uneeded entries */
869 if (!(rfg & SFGAO_CANMOVE))
870 DeleteMenu(hmenuDefault, IDM_CUT, MF_BYCOMMAND);
871 if (!(rfg & SFGAO_CANCOPY))
872 DeleteMenu(hmenuDefault, IDM_COPY, MF_BYCOMMAND);
873 if (!((rfg & SFGAO_FILESYSTEM) && HasClipboardData()))
874 DeleteMenu(hmenuDefault, IDM_INSERT, MF_BYCOMMAND);
875 if (!(rfg & SFGAO_CANLINK))
876 DeleteMenu(hmenuDefault, IDM_CREATELINK, MF_BYCOMMAND);
877 if (!(rfg & SFGAO_CANDELETE))
878 DeleteMenu(hmenuDefault, IDM_DELETE, MF_BYCOMMAND);
879 if (!(rfg & SFGAO_CANRENAME) || !(uFlags & CMF_CANRENAME))
880 DeleteMenu(hmenuDefault, IDM_RENAME, MF_BYCOMMAND);
881 if (!(rfg & SFGAO_HASPROPSHEET))
882 DeleteMenu(hmenuDefault, IDM_PROPERTIES, MF_BYCOMMAND);
883
884 idDefaultOffset = idCmdNext;
885 UINT idMax = Shell_MergeMenus(hMenu, GetSubMenu(hmenuDefault, 0), IndexMenu, idCmdNext, idCmdLast, 0);
886 m_iIdDfltFirst = cIds;
887 cIds += idMax - idCmdNext;
888 m_iIdDfltLast = cIds;
889
890 DestroyMenu(hmenuDefault);
891 }
892
893 TryPickDefault(hMenu, idCmdFirst, idDefaultOffset, uFlags);
894
895 // TODO: DFM_MERGECONTEXTMENU_TOP
896
897 return MAKE_HRESULT(SEVERITY_SUCCESS, 0, cIds);
898}
899
901{
902 HRESULT hr;
903
905 hr = OleGetClipboard(&pda);
907 return hr;
908
909 FORMATETC formatetc2;
910 STGMEDIUM medium2;
912
913 DWORD dwKey= 0;
914
915 if (SUCCEEDED(pda->GetData(&formatetc2, &medium2)))
916 {
917 DWORD * pdwFlag = (DWORD*)GlobalLock(medium2.hGlobal);
918 if (pdwFlag)
919 {
920 if (*pdwFlag == DROPEFFECT_COPY)
921 dwKey = MK_CONTROL;
922 else
923 dwKey = MK_SHIFT;
924 }
925 else
926 {
927 ERR("No drop effect obtained\n");
928 }
929 GlobalUnlock(medium2.hGlobal);
930 }
931
932 if (bLink)
933 {
934 dwKey = MK_CONTROL|MK_SHIFT;
935 }
936
938 if (m_cidl)
939 hr = m_psf->GetUIObjectOf(NULL, 1, &m_apidl[0], IID_NULL_PPV_ARG(IDropTarget, &pdrop));
940 else
941 hr = m_psf->CreateViewObject(NULL, IID_PPV_ARG(IDropTarget, &pdrop));
942
944 return hr;
945
946 SHSimulateDrop(pdrop, pda, dwKey, NULL, NULL);
947
948 TRACE("CP result %x\n", hr);
949 return S_OK;
950}
951
954{
956 return E_FAIL;
957}
958
960{
961 if (!m_cidl || !m_pDataObj)
962 return E_FAIL;
963
965 HRESULT hr = m_psf->CreateViewObject(NULL, IID_PPV_ARG(IDropTarget, &pDT));
967 return hr;
968
970
971 return S_OK;
972}
973
975{
976 if (!m_cidl || !m_pDataObj)
977 return E_FAIL;
978
982 return hr;
983
984 DWORD grfKeyState = (lpcmi->fMask & CMIC_MASK_SHIFT_DOWN) ? MK_SHIFT : 0;
985 SHSimulateDrop(pDT, m_pDataObj, grfKeyState, NULL, NULL);
986
987 return S_OK;
988}
989
991{
992 if (!m_cidl || !m_pDataObj)
993 return E_FAIL;
994
995 FORMATETC formatetc;
997 STGMEDIUM medium = {0};
998 medium.tymed = TYMED_HGLOBAL;
999 medium.hGlobal = GlobalAlloc(GHND, sizeof(DWORD));
1000 DWORD* pdwFlag = (DWORD*)GlobalLock(medium.hGlobal);
1001 if (pdwFlag)
1002 *pdwFlag = bCopy ? DROPEFFECT_COPY : DROPEFFECT_MOVE;
1003 GlobalUnlock(medium.hGlobal);
1004 m_pDataObj->SetData(&formatetc, &medium, TRUE);
1005
1008 return hr;
1009
1010 return S_OK;
1011}
1012
1014{
1016 HRESULT hr;
1017
1018 if (!m_site || !m_cidl)
1019 return E_FAIL;
1020
1021 /* Get a pointer to the shell browser */
1024 return hr;
1025
1027 hr = psb->QueryActiveShellView(&lpSV);
1029 return hr;
1030
1031 SVSIF selFlags = SVSI_DESELECTOTHERS | SVSI_EDIT | SVSI_ENSUREVISIBLE | SVSI_FOCUSED | SVSI_SELECT;
1032 hr = lpSV->SelectItem(m_apidl[0], selFlags);
1034 return hr;
1035
1036 return S_OK;
1037}
1038
1039HRESULT
1042{
1044
1045 // We are asked to run the default property sheet
1046 if (hr == S_FALSE)
1047 {
1049 }
1050
1051 return hr;
1052}
1053
1054HRESULT
1056{
1057 ERR("TODO: Undo\n");
1058 return E_NOTIMPL;
1059}
1060
1061HRESULT
1063{
1064 HRESULT hr = E_FAIL;
1065 if (!m_pDataObj)
1066 {
1067 ERR("m_pDataObj is NULL\n");
1068 return hr;
1069 }
1070
1071 CComPtr<IContextMenu> pContextMenu;
1072 if (bCopy)
1073 hr = SHCoCreateInstance(NULL, &CLSID_CopyToMenu, NULL,
1074 IID_PPV_ARG(IContextMenu, &pContextMenu));
1075 else
1076 hr = SHCoCreateInstance(NULL, &CLSID_MoveToMenu, NULL,
1077 IID_PPV_ARG(IContextMenu, &pContextMenu));
1079 return hr;
1080
1082 hr = pContextMenu->QueryInterface(IID_PPV_ARG(IShellExtInit, &pInit));
1084 return hr;
1085
1086 hr = pInit->Initialize(m_pidlFolder, m_pDataObj, NULL);
1088 return hr;
1089
1090 if (bCopy)
1091 lpici->lpVerb = "copyto";
1092 else
1093 lpici->lpVerb = "moveto";
1094
1095 return pContextMenu->InvokeCommand((LPCMINVOKECOMMANDINFO)lpici);
1096}
1097
1098// This code is taken from CNewMenu and should be shared between the 2 classes
1099HRESULT
1102{
1103 WCHAR wszPath[MAX_PATH];
1104 WCHAR wszName[MAX_PATH];
1105 WCHAR wszNewFolder[25];
1106 HRESULT hr;
1107
1108 /* Get folder path */
1111 return hr;
1112
1113 if (!LoadStringW(shell32_hInstance, IDS_NEWFOLDER, wszNewFolder, _countof(wszNewFolder)))
1114 return E_FAIL;
1115
1116 /* Create the name of the new directory */
1117 if (!PathYetAnotherMakeUniqueName(wszName, wszPath, NULL, wszNewFolder))
1118 return E_FAIL;
1119
1120 /* Create the new directory and show the appropriate dialog in case of error */
1121 if (SHCreateDirectory(lpici->hwnd, wszName) != ERROR_SUCCESS)
1122 return E_FAIL;
1123
1124 /* Show and select the new item in the def view */
1125 LPITEMIDLIST pidl;
1126 PITEMID_CHILD pidlNewItem;
1128
1129 /* Notify the view object about the new item */
1131
1132 if (!m_site)
1133 return S_OK;
1134
1135 /* Get a pointer to the shell view */
1138 return S_OK;
1139
1140 /* Attempt to get the pidl of the new item */
1141 hr = SHILCreateFromPathW(wszName, &pidl, NULL);
1143 return hr;
1144
1145 pidlNewItem = ILFindLastID(pidl);
1146
1147 hr = psv->SelectItem(pidlNewItem, SVSI_DESELECTOTHERS | SVSI_EDIT | SVSI_ENSUREVISIBLE |
1148 SVSI_FOCUSED | SVSI_SELECT);
1150 return hr;
1151
1152 SHFree(pidl);
1153
1154 return S_OK;
1155}
1156
1158{
1159 POSITION it = m_DynamicEntries.GetHeadPosition();
1160 while (it != NULL)
1161 {
1163
1164 if (idCmd >= info.iIdCmdFirst + info.NumIds)
1165 continue;
1166
1167 if (idCmd < info.iIdCmdFirst || idCmd > info.iIdCmdFirst + info.NumIds)
1168 return NULL;
1169
1170 return &info;
1171 }
1172
1173 return NULL;
1174}
1175
1176BOOL
1178{
1179 WCHAR UnicodeStr[MAX_VERB];
1180
1181 /* Loop through all the static verbs looking for a match */
1182 for (UINT i = 0; i < _countof(g_StaticInvokeCmdMap); i++)
1183 {
1184 /* We can match both ANSI and unicode strings */
1185 if (IsUnicode)
1186 {
1187 /* The static verbs are ANSI, get a unicode version before doing the compare */
1188 SHAnsiToUnicode(g_StaticInvokeCmdMap[i].szStringVerb, UnicodeStr, MAX_VERB);
1189 if (!wcscmp(UnicodeStr, (LPWSTR)Verb))
1190 {
1191 /* Return the Corresponding Id */
1192 *idCmd = g_StaticInvokeCmdMap[i].IntVerb;
1193 return TRUE;
1194 }
1195 }
1196 else
1197 {
1198 if (!strcmp(g_StaticInvokeCmdMap[i].szStringVerb, (LPSTR)Verb))
1199 {
1200 *idCmd = g_StaticInvokeCmdMap[i].IntVerb;
1201 return TRUE;
1202 }
1203 }
1204 }
1205
1206 return FALSE;
1207}
1208
1209HRESULT
1212{
1213 TRACE("verb %p first %x last %x\n", lpcmi->lpVerb, m_iIdSHEFirst, m_iIdSHELast);
1214
1215 UINT idCmd = LOWORD(lpcmi->lpVerb);
1217 if (!pEntry)
1218 return E_FAIL;
1219
1220 /* invoke the dynamic context menu */
1221 lpcmi->lpVerb = MAKEINTRESOURCEA(idCmd - pEntry->iIdCmdFirst);
1222 return pEntry->pCM->InvokeCommand((LPCMINVOKECOMMANDINFO)lpcmi);
1223}
1224
1225DWORD
1227{
1229 HWND hwndTree;
1230 LPCWSTR FlagsName;
1231 WCHAR wszKey[sizeof("shell\\") + MAX_VERB];
1232 HRESULT hr;
1233 DWORD wFlags;
1234 DWORD cbVerb;
1235
1236 if (!m_site)
1237 return 0;
1238
1239 /* Get a pointer to the shell browser */
1241 if (FAILED(hr))
1242 return 0;
1243
1244 /* See if we are in Explore or Browse mode. If the browser's tree is present, we are in Explore mode.*/
1245 if (SUCCEEDED(psb->GetControlWindow(FCW_TREE, &hwndTree)) && hwndTree)
1246 FlagsName = L"ExplorerFlags";
1247 else
1248 FlagsName = L"BrowserFlags";
1249
1250 /* Try to get the flag from the verb */
1251 hr = StringCbPrintfW(wszKey, sizeof(wszKey), L"shell\\%s", pEntry->Verb.GetString());
1253 return 0;
1254
1255 cbVerb = sizeof(wFlags);
1256 if (RegGetValueW(pEntry->hkClass, wszKey, FlagsName, RRF_RT_REG_DWORD, NULL, &wFlags, &cbVerb) == ERROR_SUCCESS)
1257 {
1258 return wFlags;
1259 }
1260
1261 return 0;
1262}
1263
1264HRESULT
1267{
1269 HRESULT hr;
1270
1271 if (!m_site)
1272 return E_FAIL;
1273
1274 /* Get a pointer to the shell browser */
1276 if (FAILED(hr))
1277 return hr;
1278
1279 PIDLIST_ABSOLUTE pidl;
1280 hr = SHILCombine(m_pidlFolder, pidlChild, &pidl);
1282 return hr;
1283
1284 hr = psb->BrowseObject(pidl, wFlags & ~SBSP_RELATIVE);
1285 ILFree(pidl);
1286 return hr;
1287}
1288
1289HRESULT
1291{
1292 LPITEMIDLIST pidlFull = ILCombine(m_pidlFolder, pidl);
1293 if (pidlFull == NULL)
1294 {
1295 return E_FAIL;
1296 }
1297
1298 WCHAR wszPath[MAX_PATH];
1299 BOOL bHasPath = SHGetPathFromIDListW(pidlFull, wszPath);
1300
1301 WCHAR wszDir[MAX_PATH];
1302 if (bHasPath)
1303 {
1304 wcscpy(wszDir, wszPath);
1305 PathRemoveFileSpec(wszDir);
1306 }
1307 else
1308 {
1309 if (!SHGetPathFromIDListW(m_pidlFolder, wszDir))
1310 *wszDir = UNICODE_NULL;
1311 }
1312
1314 ZeroMemory(&sei, sizeof(sei));
1315 sei.cbSize = sizeof(sei);
1316 sei.hwnd = lpcmi->hwnd;
1317 sei.nShow = SW_SHOWNORMAL;
1318 sei.lpVerb = pEntry->Verb;
1319 sei.lpDirectory = wszDir;
1320 sei.lpIDList = pidlFull;
1321 sei.hkeyClass = pEntry->hkClass;
1323 if (bHasPath)
1324 {
1325 sei.lpFile = wszPath;
1326 }
1327
1328 ShellExecuteExW(&sei);
1329
1330 ILFree(pidlFull);
1331
1332 return S_OK;
1333}
1334
1335HRESULT
1338{
1339 INT iCmd = LOWORD(lpcmi->lpVerb);
1340 HRESULT hr;
1341 UINT i;
1342
1343 POSITION it = m_StaticEntries.FindIndex(iCmd);
1344
1345 if (it == NULL)
1346 return E_INVALIDARG;
1347
1349
1350 CRegKey VerbKey;
1351 WCHAR VerbKeyPath[sizeof("shell\\") + MAX_VERB];
1352 hr = StringCbPrintfW(VerbKeyPath, sizeof(VerbKeyPath), L"shell\\%s", pEntry->Verb.GetString());
1353 if (SUCCEEDED(hr) && m_pDataObj &&
1354 VerbKey.Open(pEntry->hkClass, VerbKeyPath, KEY_READ) == ERROR_SUCCESS)
1355 {
1356 CLSID clsid;
1357
1358 DWORD KeyState = 0;
1359 if (lpcmi->fMask & CMIC_MASK_SHIFT_DOWN)
1360 KeyState |= MK_SHIFT;
1361 if (lpcmi->fMask & CMIC_MASK_CONTROL_DOWN)
1362 KeyState |= MK_CONTROL;
1363
1364 POINTL *pPtl = NULL;
1365 C_ASSERT(sizeof(POINT) == sizeof(POINTL));
1366 if (lpcmi->fMask & CMIC_MASK_PTINVOKE)
1367 pPtl = (POINTL*)&lpcmi->ptInvoke;
1368
1370 hr = SHELL_GetRegCLSID(VerbKey, L"command", L"DelegateExecute", clsid);
1371 if (SUCCEEDED(hr))
1372 hr = CoCreateInstance(clsid, NULL, CLSCTX_ALL, IID_PPV_ARG(IExecuteCommand, &pEC));
1373 if (SUCCEEDED(hr))
1374 {
1377 return InvokeIExecuteCommandWithDataObject(pEC, pEntry->Verb.GetString(), pPB, m_pDataObj,
1378 lpcmi, static_cast<IContextMenu*>(this));
1379 }
1380
1382 hr = SHELL_GetRegCLSID(VerbKey, L"DropTarget", L"CLSID", clsid);
1383 if (SUCCEEDED(hr))
1384 hr = CoCreateInstance(clsid, NULL, CLSCTX_ALL, IID_PPV_ARG(IDropTarget, &pDT));
1385 if (SUCCEEDED(hr))
1386 {
1389 IUnknown_SetSite(pDT, static_cast<IContextMenu*>(this));
1390 IUnknown_InitializeCommand(pDT, pEntry->Verb.GetString(), pPB);
1391 hr = SHSimulateDrop(pDT, m_pDataObj, KeyState, pPtl, NULL);
1392 IUnknown_SetSite(pDT, NULL);
1393 return hr;
1394 }
1395 }
1396
1397 /* Get the browse flags to see if we need to browse */
1399
1400 for (i=0; i < m_cidl; i++)
1401 {
1402 /* Check if we need to browse */
1403 if (wFlags)
1404 {
1405 hr = TryToBrowse(lpcmi, m_apidl[i], wFlags);
1406 if (SUCCEEDED(hr))
1407 {
1408 /* In WinXP if we have browsed, we don't open any more folders.
1409 * In Win7 we browse to the first folder we find and
1410 * open new windows for each of the rest of the folders */
1412 if (ntver >= _WIN32_WINNT_VISTA)
1413 wFlags = 0; // FIXME: = SBSP_NEWBROWSER | (wFlags & ~SBSP_SAMEBROWSER);
1414 else
1415 i = m_cidl;
1416
1417 continue;
1418 }
1419 }
1420
1421 InvokePidl(lpcmi, m_apidl[i], pEntry);
1422 }
1423
1424 return S_OK;
1425}
1426
1427HRESULT
1428WINAPI
1431{
1432 CMINVOKECOMMANDINFOEX LocalInvokeInfo = {};
1434 UINT CmdId;
1435
1436 /* Take a local copy of the fixed members of the
1437 struct as we might need to modify the verb */
1438 memcpy(&LocalInvokeInfo, lpcmi, min(sizeof(LocalInvokeInfo), lpcmi->cbSize));
1439
1440 /* Check if this is a string verb */
1441 if (!IS_INTRESOURCE(LocalInvokeInfo.lpVerb))
1442 {
1443 /* Get the ID which corresponds to this verb, and update our local copy */
1444 if (MapVerbToCmdId((LPVOID)LocalInvokeInfo.lpVerb, &CmdId, FALSE))
1445 LocalInvokeInfo.lpVerb = MAKEINTRESOURCEA(CmdId);
1446 }
1447
1448 CmdId = LOWORD(LocalInvokeInfo.lpVerb);
1449
1450 if (!m_DynamicEntries.IsEmpty() && CmdId >= m_iIdSHEFirst && CmdId < m_iIdSHELast)
1451 {
1452 LocalInvokeInfo.lpVerb -= m_iIdSHEFirst;
1453 Result = InvokeShellExt(&LocalInvokeInfo);
1454 return Result;
1455 }
1456
1457 if (!m_StaticEntries.IsEmpty() && CmdId >= m_iIdSCMFirst && CmdId < m_iIdSCMLast)
1458 {
1459 LocalInvokeInfo.lpVerb -= m_iIdSCMFirst;
1460 Result = InvokeRegVerb(&LocalInvokeInfo);
1461 // TODO: if (FAILED(Result) && !(lpcmi->fMask & CMIC_MASK_FLAG_NO_UI)) SHELL_ErrorBox(m_pSite, Result);
1462 return Result;
1463 }
1464
1465 if (m_iIdCBFirst != m_iIdCBLast && CmdId >= m_iIdCBFirst && CmdId < m_iIdCBLast)
1466 {
1468 return Result;
1469 }
1470
1471 if (m_iIdDfltFirst != m_iIdDfltLast && CmdId >= m_iIdDfltFirst && CmdId < m_iIdDfltLast)
1472 {
1473 CmdId -= m_iIdDfltFirst;
1474 /* See the definitions of IDM_CUT and co to see how this works */
1475 CmdId += DCM_FCIDM_SHVIEW_OFFSET;
1476 }
1477
1478 if (LocalInvokeInfo.cbSize >= sizeof(CMINVOKECOMMANDINFOEX) && (LocalInvokeInfo.fMask & CMIC_MASK_PTINVOKE))
1479 {
1480 if (m_pDataObj && FAILED_UNEXPECTEDLY(DataObject_SetOffset(m_pDataObj, &LocalInvokeInfo.ptInvoke)))
1481 {
1482 ERR("Unable to add OFFSET to DataObject!\n");
1483 }
1484 }
1485
1486 /* Check if this is a Id */
1487 switch (CmdId)
1488 {
1490 Result = DoPaste(&LocalInvokeInfo, FALSE);
1491 break;
1493 Result = DoPaste(&LocalInvokeInfo, TRUE);
1494 break;
1495 case FCIDM_SHVIEW_OPEN:
1497 Result = DoOpenOrExplore(&LocalInvokeInfo);
1498 break;
1499 case FCIDM_SHVIEW_COPY:
1500 case FCIDM_SHVIEW_CUT:
1501 Result = DoCopyOrCut(&LocalInvokeInfo, CmdId == FCIDM_SHVIEW_COPY);
1502 break;
1504 Result = DoCreateLink(&LocalInvokeInfo);
1505 break;
1507 Result = DoDelete(&LocalInvokeInfo);
1508 break;
1510 Result = DoRename(&LocalInvokeInfo);
1511 break;
1513 Result = DoProperties(&LocalInvokeInfo);
1514 break;
1516 Result = DoCreateNewFolder(&LocalInvokeInfo);
1517 break;
1519 Result = DoCopyToMoveToFolder(&LocalInvokeInfo, TRUE);
1520 break;
1522 Result = DoCopyToMoveToFolder(&LocalInvokeInfo, FALSE);
1523 break;
1524 case FCIDM_SHVIEW_UNDO:
1525 Result = DoUndo(&LocalInvokeInfo);
1526 break;
1527 default:
1529 ERR("Unhandled Verb %xl\n", LOWORD(LocalInvokeInfo.lpVerb));
1530 break;
1531 }
1532
1533 return Result;
1534}
1535
1536HRESULT
1537WINAPI
1539 UINT_PTR idCommand,
1540 UINT uFlags,
1541 UINT* lpReserved,
1542 LPSTR lpszName,
1543 UINT uMaxNameLen)
1544{
1545 /* We don't handle the help text yet */
1546 if (uFlags == GCS_HELPTEXTA ||
1547 uFlags == GCS_HELPTEXTW ||
1548 HIWORD(idCommand) != 0)
1549 {
1550 return E_NOTIMPL;
1551 }
1552
1553 UINT CmdId = LOWORD(idCommand);
1554
1555 if (!m_DynamicEntries.IsEmpty() && CmdId >= m_iIdSHEFirst && CmdId < m_iIdSHELast)
1556 {
1557 idCommand -= m_iIdSHEFirst;
1559 if (!pEntry)
1560 return E_FAIL;
1561
1562 idCommand -= pEntry->iIdCmdFirst;
1563 return pEntry->pCM->GetCommandString(idCommand,
1564 uFlags,
1565 lpReserved,
1566 lpszName,
1567 uMaxNameLen);
1568 }
1569
1570 if (!m_StaticEntries.IsEmpty() && CmdId >= m_iIdSCMFirst && CmdId < m_iIdSCMLast)
1571 {
1572 /* Validation just returns S_OK on a match. The id exists. */
1573 if (uFlags == GCS_VALIDATEA || uFlags == GCS_VALIDATEW)
1574 return S_OK;
1575
1576 CmdId -= m_iIdSCMFirst;
1577
1578 POSITION it = m_StaticEntries.FindIndex(CmdId);
1579
1580 if (it == NULL)
1581 return E_INVALIDARG;
1582
1584
1585 if (uFlags == GCS_VERBW)
1586 return StringCchCopyW((LPWSTR)lpszName, uMaxNameLen, pEntry->Verb);
1587
1588 if (uFlags == GCS_VERBA)
1589 {
1590 if (SHUnicodeToAnsi(pEntry->Verb, lpszName, uMaxNameLen))
1591 return S_OK;
1592 }
1593
1594 return E_INVALIDARG;
1595 }
1596
1597 //FIXME: Should we handle callbacks here?
1598 if (m_iIdDfltFirst != m_iIdDfltLast && CmdId >= m_iIdDfltFirst && CmdId < m_iIdDfltLast)
1599 {
1600 CmdId -= m_iIdDfltFirst;
1601 /* See the definitions of IDM_CUT and co to see how this works */
1602 CmdId += DCM_FCIDM_SHVIEW_OFFSET;
1603 }
1604
1605 /* Loop looking for a matching Id */
1606 for (UINT i = 0; i < _countof(g_StaticInvokeCmdMap); i++)
1607 {
1608 if (g_StaticInvokeCmdMap[i].IntVerb == CmdId)
1609 {
1610 /* Validation just returns S_OK on a match */
1611 if (uFlags == GCS_VALIDATEA || uFlags == GCS_VALIDATEW)
1612 return S_OK;
1613
1614 /* Return a copy of the ANSI verb */
1615 if (uFlags == GCS_VERBA)
1616 return StringCchCopyA(lpszName, uMaxNameLen, g_StaticInvokeCmdMap[i].szStringVerb);
1617
1618 /* Convert the ANSI verb to unicode and return that */
1619 if (uFlags == GCS_VERBW)
1620 {
1621 if (SHAnsiToUnicode(g_StaticInvokeCmdMap[i].szStringVerb, (LPWSTR)lpszName, uMaxNameLen))
1622 return S_OK;
1623 }
1624 }
1625 }
1626
1627 return E_INVALIDARG;
1628}
1629
1630HRESULT
1631WINAPI
1633 UINT uMsg,
1634 WPARAM wParam,
1635 LPARAM lParam)
1636{
1637 /* FIXME: Should we implement this as well? */
1638 return S_OK;
1639}
1640
1642{
1643 if (uMsg == WM_DRAWITEM)
1644 {
1645 DRAWITEMSTRUCT* pDrawStruct = reinterpret_cast<DRAWITEMSTRUCT*>(lParam);
1646 *CmdId = pDrawStruct->itemID;
1647 return S_OK;
1648 }
1649 else if (uMsg == WM_MEASUREITEM)
1650 {
1651 MEASUREITEMSTRUCT* pMeasureStruct = reinterpret_cast<MEASUREITEMSTRUCT*>(lParam);
1652 *CmdId = pMeasureStruct->itemID;
1653 return S_OK;
1654 }
1655
1656 return E_FAIL;
1657}
1658
1660{
1661 if (uMsg == WM_DRAWITEM)
1662 {
1663 DRAWITEMSTRUCT* pDrawStruct = reinterpret_cast<DRAWITEMSTRUCT*>(lParam);
1664 pDrawStruct->itemID = CmdId;
1665 return S_OK;
1666 }
1667 else if (uMsg == WM_MEASUREITEM)
1668 {
1669 MEASUREITEMSTRUCT* pMeasureStruct = reinterpret_cast<MEASUREITEMSTRUCT*>(lParam);
1670 pMeasureStruct->itemID = CmdId;
1671 return S_OK;
1672 }
1673
1674 return E_FAIL;
1675}
1676
1677HRESULT
1678WINAPI
1680 UINT uMsg,
1681 WPARAM wParam,
1682 LPARAM lParam,
1683 LRESULT *plResult)
1684{
1685 if (uMsg == WM_INITMENUPOPUP)
1686 {
1687 POSITION it = m_DynamicEntries.GetHeadPosition();
1688 while (it != NULL)
1689 {
1691 SHForwardContextMenuMsg(info.pCM, uMsg, wParam, lParam, plResult, TRUE);
1692 }
1693 return S_OK;
1694 }
1695
1696 UINT CmdId;
1697 HRESULT hr = SHGetMenuIdFromMenuMsg(uMsg, lParam, &CmdId);
1698 if (FAILED(hr))
1699 return S_FALSE;
1700
1701 if (CmdId < m_iIdSHEFirst || CmdId >= m_iIdSHELast)
1702 return S_FALSE;
1703
1704 CmdId -= m_iIdSHEFirst;
1706 if (pEntry)
1707 {
1708 SHSetMenuIdInMenuMsg(uMsg, lParam, CmdId - pEntry->iIdCmdFirst);
1709 SHForwardContextMenuMsg(pEntry->pCM, uMsg, wParam, lParam, plResult, TRUE);
1710 }
1711
1712 return S_OK;
1713}
1714
1715HRESULT
1716WINAPI
1718{
1719 m_site = pUnkSite;
1720 return S_OK;
1721}
1722
1723HRESULT
1724WINAPI
1726{
1727 if (!m_site)
1728 return E_FAIL;
1729
1730 return m_site->QueryInterface(riid, ppvSite);
1731}
1732
1733static
1734HRESULT
1736{
1737 return ShellObjectCreatorInit<CDefaultContextMenu>(pdcm, lpfn, riid, ppv);
1738}
1739
1740/*************************************************************************
1741 * SHCreateDefaultContextMenu [SHELL32.325] Vista API
1742 *
1743 */
1744
1745HRESULT
1746WINAPI
1748{
1749 HRESULT hr;
1750
1751 if (!ppv)
1752 return E_INVALIDARG;
1753
1756 return hr;
1757
1758 return S_OK;
1759}
1760
1761/*************************************************************************
1762 * CDefFolderMenu_Create2 [SHELL32.701]
1763 *
1764 */
1765
1766HRESULT
1767WINAPI
1769 PCIDLIST_ABSOLUTE pidlFolder,
1770 HWND hwnd,
1771 UINT cidl,
1773 IShellFolder *psf,
1774 LPFNDFMCALLBACK lpfn,
1775 UINT nKeys,
1776 const HKEY *ahkeyClsKeys,
1777 IContextMenu **ppcm)
1778{
1779 DEFCONTEXTMENU dcm;
1780 dcm.hwnd = hwnd;
1781 dcm.pcmcb = NULL;
1782 dcm.pidlFolder = pidlFolder;
1783 dcm.psf = psf;
1784 dcm.cidl = cidl;
1785 dcm.apidl = apidl;
1787 dcm.cKeys = nKeys;
1788 dcm.aKeys = ahkeyClsKeys;
1789
1792 return hr;
1793
1794 return S_OK;
1795}
static bool RegValueExists(HKEY hKey, LPCWSTR Name)
static const struct _StaticInvokeCommandMap_ g_StaticInvokeCmdMap[]
struct _DynamicShellEntry_ * PDynamicShellEntry
struct _DynamicShellEntry_ DynamicShellEntry
#define VERBKEY_CCHMAX
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
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
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 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)
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_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
LONG WINAPI RegQueryValueExW(_In_ HKEY hkeyorg, _In_ LPCWSTR name, _In_ LPDWORD reserved, _In_ LPDWORD type, _In_ LPBYTE data, _In_ LPDWORD count)
Definition: reg.c:4103
UINT uFlags
Definition: api.c:59
#define GetProcessHeap()
Definition: compat.h:736
#define HeapAlloc
Definition: compat.h:733
#define MAX_PATH
Definition: compat.h:34
#define HeapFree(x, y, z)
Definition: compat.h:735
#define wcsicmp
Definition: compat.h:15
#define FAILED_UNEXPECTEDLY(hr)
Definition: precomp.h:121
int WINAPI lstrcmpiA(LPCSTR str1, LPCSTR str2)
Definition: locale.c:4223
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
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:504
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:1824
HRESULT WINAPI IUnknown_QueryService(IUnknown *, REFGUID, REFIID, LPVOID *)
Definition: ordinal.c:1497
HRESULT WINAPI SHCreatePropertyBagOnRegKey(HKEY hKey, LPCWSTR subkey, DWORD grfMode, REFIID riid, void **ppv)
Definition: ordinal.c:5177
HRESULT WINAPI IUnknown_SetSite(IUnknown *obj, IUnknown *site)
Definition: ordinal.c:1407
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 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
#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:2611
LPITEMIDLIST WINAPI ILClone(LPCITEMIDLIST pidl)
Definition: pidl.c:237
void WINAPI ILFree(LPITEMIDLIST pidl)
Definition: pidl.c:940
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:712
BOOL WINAPI SHGetPathFromIDListW(LPCITEMIDLIST pidl, LPWSTR pszPath)
Definition: pidl.c:1342
void _ILFreeaPidl(LPITEMIDLIST *apidl, UINT cidl)
Definition: pidl.c:2594
#define REFIID
Definition: guiddef.h:118
#define REFCLSID
Definition: guiddef.h:117
#define err(...)
HRESULT WINAPI SHForwardContextMenuMsg(IUnknown *pUnk, UINT uMsg, WPARAM wParam, LPARAM lParam, LRESULT *pResult, BOOL useIContextMenu2)
Definition: rosordinal.c:11
_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
#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:2362
int WINAPI SHCreateDirectory(HWND hWnd, LPCWSTR path)
Definition: shlfileop.cpp:847
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:2607
#define CFSTR_SHELLIDLIST
Definition: shlobj.h:550
#define CFSTR_PREFERREDDROPEFFECT
Definition: shlobj.h:560
#define SHCNE_MKDIR
Definition: shlobj.h:1892
#define DFM_CMD_NEWFOLDER
Definition: shlobj.h:2612
#define DFM_CMD_COPY
Definition: shlobj.h:2609
#define DFM_CMD_PASTE
Definition: shlobj.h:2613
#define SHCNF_FLUSH
Definition: shlobj.h:1927
#define SHCNF_PATHW
Definition: shlobj.h:1924
#define DFM_CMD_PROPERTIES
Definition: shlobj.h:2611
HRESULT(CALLBACK * LPFNDFMCALLBACK)(_In_opt_ IShellFolder *, _In_opt_ HWND, _In_opt_ IDataObject *, UINT, WPARAM, LPARAM)
Definition: shlobj.h:2567
#define DFM_CMD_RENAME
Definition: shlobj.h:2619
#define DFM_CMD_LINK
Definition: shlobj.h:2610
#define PathRemoveFileSpec
Definition: shlwapi.h:1035
#define FCIDM_SHVIEW_CUT
Definition: shresdef.h:831
#define FCIDM_SHVIEW_OPEN
Definition: shresdef.h:858
#define FCIDM_SHVIEW_UNDO
Definition: shresdef.h:834
#define IDM_DELETE
Definition: shresdef.h:871
#define FCIDM_SHVIEW_COPY
Definition: shresdef.h:832
#define IDS_OPEN_VERB
Definition: shresdef.h:215
#define IDM_INSERT
Definition: shresdef.h:869
#define FCIDM_SHVIEW_INSERTLINK
Definition: shresdef.h:835
#define IDS_FIND_VERB
Definition: shresdef.h:219
#define FCIDM_SHVIEW_NEWFOLDER
Definition: shresdef.h:854
#define IDM_RENAME
Definition: shresdef.h:872
#define IDM_COPY
Definition: shresdef.h:868
#define FCIDM_SHVIEW_EXPLORE
Definition: shresdef.h:857
#define FCIDM_SHVIEW_PROPERTIES
Definition: shresdef.h:830
#define IDS_EXPLORE_VERB
Definition: shresdef.h:216
#define IDM_CUT
Definition: shresdef.h:867
#define IDM_CREATELINK
Definition: shresdef.h:870
#define IDS_PRINT_VERB
Definition: shresdef.h:220
#define FCIDM_SHVIEW_COPYTO
Definition: shresdef.h:836
#define FCIDM_SHVIEW_MOVETO
Definition: shresdef.h:837
#define FCIDM_SHVIEW_DELETE
Definition: shresdef.h:829
#define FCIDM_SHVIEW_RENAME
Definition: shresdef.h:851
#define FCIDM_SHVIEW_CREATELINK
Definition: shresdef.h:852
#define IDS_RUNAS_VERB
Definition: shresdef.h:217
#define IDS_EDIT_VERB
Definition: shresdef.h:218
#define FCIDM_SHVIEW_INSERT
Definition: shresdef.h:833
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
IContextMenuCB * pcmcb
Definition: shlobj.h:2549
IShellFolder * psf
Definition: shlobj.h:2551
IUnknown * punkAssociationInfo
Definition: shlobj.h:2554
PCUITEMID_CHILD_ARRAY apidl
Definition: shlobj.h:2553
const HKEY * aKeys
Definition: shlobj.h:2556
PCIDLIST_ABSOLUTE pidlFolder
Definition: shlobj.h:2550
CComPtr< IContextMenu > pCM
Definition: scsiwmi.h:51
UINT idCmdFirst
Definition: shlobj.h:1391
LPCWSTR lpDirectory
Definition: shellapi.h:334
LPWSTR dwTypeData
Definition: winuser.h:3269
int32_t INT_PTR
Definition: typedefs.h:64
#define FIELD_OFFSET(t, f)
Definition: typedefs.h:255
int32_t INT
Definition: typedefs.h:58
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define HIWORD(l)
Definition: typedefs.h:247
_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 SW_SHOWNORMAL
Definition: winuser.h:770
#define MK_SHIFT
Definition: winuser.h:2369
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:722
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:744
#define WM_DRAWITEM
Definition: winuser.h:1645
#define MIIM_STATE
Definition: winuser.h:721
#define MFS_DEFAULT
Definition: winuser.h:748
HMENU WINAPI GetSubMenu(_In_ HMENU, _In_ int)
#define WM_INITMENUPOPUP
Definition: winuser.h:1746
#define MK_CONTROL
Definition: winuser.h:2370
#define MF_SEPARATOR
Definition: winuser.h:137
#define MF_BYPOSITION
Definition: winuser.h:203
#define LoadMenu
Definition: winuser.h:5826
#define WM_MEASUREITEM
Definition: winuser.h:1646
#define MFS_ENABLED
Definition: winuser.h:750
#define MAKEINTRESOURCEA(i)
Definition: winuser.h:581
BOOL WINAPI DestroyMenu(_In_ HMENU)
#define MFT_STRING
Definition: winuser.h:746
#define MIIM_DATA
Definition: winuser.h:726
#define MIIM_TYPE
Definition: winuser.h:725
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