[SHELL32] shlexec.cpp: Parse 'shell:' and '::{CLSID}' (#7126)

JIRA issue: CORE-14177
JIRA issue: CORE-17482
- Add SHELL_InvokePidl helper
  function.
- Call SHParseDisplayName and
  SHELL_InvokePidl in a specific
  condition.
This commit is contained in:
Katayama Hirofumi MZ 2024-07-15 21:16:04 +09:00 committed by GitHub
parent c1b9bb5700
commit 6f277e9766
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 68 additions and 2 deletions

View file

@ -11,10 +11,8 @@
WINE_DEFAULT_DEBUG_CHANNEL(dmenu);
// FIXME: 260 is correct, but should this be part of the SDK or just MAX_PATH?
#define MAX_VERB 260
#define VERBKEY_CCHMAX 64 // Note: 63+\0 seems to be the limit on XP
static HRESULT
SHELL_GetRegCLSID(HKEY hKey, LPCWSTR SubKey, LPCWSTR Value, CLSID &clsid)

View file

@ -127,6 +127,8 @@ extern const GUID SHELL32_AdvtShortcutComponent;
#define MAX_PROPERTY_SHEET_PAGE 32
#define VERBKEY_CCHMAX 64 // Note: 63+\0 seems to be the limit on XP
extern inline
BOOL
CALLBACK

View file

@ -1738,6 +1738,59 @@ static BOOL SHELL_translate_idlist(LPSHELLEXECUTEINFOW sei, LPWSTR wszParameters
return appKnownSingular;
}
static BOOL
SHELL_InvokePidl(
_In_ LPSHELLEXECUTEINFOW sei,
_In_ LPCITEMIDLIST pidl)
{
// Bind pidl
CComPtr<IShellFolder> psfFolder;
LPCITEMIDLIST pidlLast;
HRESULT hr = SHBindToParent(pidl, IID_PPV_ARG(IShellFolder, &psfFolder), &pidlLast);
if (FAILED_UNEXPECTEDLY(hr))
return FALSE;
// Get the context menu to invoke a command
CComPtr<IContextMenu> pCM;
hr = psfFolder->GetUIObjectOf(NULL, 1, &pidlLast, IID_NULL_PPV_ARG(IContextMenu, &pCM));
if (FAILED_UNEXPECTEDLY(hr))
return FALSE;
// Invoke a command
CMINVOKECOMMANDINFO ici = { sizeof(ici) };
ici.fMask = (sei->fMask & (SEE_MASK_NO_CONSOLE | SEE_MASK_ASYNCOK | SEE_MASK_FLAG_NO_UI));
ici.nShow = sei->nShow;
ici.hwnd = sei->hwnd;
char szVerb[VERBKEY_CCHMAX];
if (sei->lpVerb && sei->lpVerb[0])
{
WideCharToMultiByte(CP_ACP, 0, sei->lpVerb, -1, szVerb, _countof(szVerb), NULL, NULL);
szVerb[_countof(szVerb) - 1] = ANSI_NULL; // Avoid buffer overrun
ici.lpVerb = szVerb;
}
else // The default verb?
{
HMENU hMenu = CreatePopupMenu();
const INT idCmdFirst = 1, idCmdLast = 0x7FFF;
hr = pCM->QueryContextMenu(hMenu, 0, idCmdFirst, idCmdLast, CMF_DEFAULTONLY);
if (FAILED_UNEXPECTEDLY(hr))
{
DestroyMenu(hMenu);
return FALSE;
}
INT nDefaultID = GetMenuDefaultItem(hMenu, FALSE, 0);
DestroyMenu(hMenu);
if (nDefaultID == -1)
nDefaultID = idCmdFirst;
ici.lpVerb = MAKEINTRESOURCEA(nDefaultID - idCmdFirst);
}
hr = pCM->InvokeCommand(&ici);
return !FAILED_UNEXPECTEDLY(hr);
}
static UINT_PTR SHELL_quote_and_execute(LPCWSTR wcmd, LPCWSTR wszParameters, LPCWSTR wszKeyname, LPCWSTR wszApplicationName, LPWSTR env, LPSHELLEXECUTEINFOW psei, LPSHELLEXECUTEINFOW psei_out, SHELL_ExecuteW32 execfunc)
{
UINT_PTR retval;
@ -2031,6 +2084,19 @@ static BOOL SHELL_execute(LPSHELLEXECUTEINFOW sei, SHELL_ExecuteW32 execfunc)
return retval > 32;
}
if (!(sei_tmp.fMask & SEE_MASK_IDLIST) && // Not an ID List
(StrCmpNIW(sei_tmp.lpFile, L"shell:", 6) == 0 ||
StrCmpNW(sei_tmp.lpFile, L"::{", 3) == 0))
{
CComHeapPtr<ITEMIDLIST> pidlParsed;
HRESULT hr = SHParseDisplayName(sei_tmp.lpFile, NULL, &pidlParsed, 0, NULL);
if (SUCCEEDED(hr) && SHELL_InvokePidl(&sei_tmp, pidlParsed))
{
sei_tmp.hInstApp = (HINSTANCE)UlongToHandle(42);
return TRUE;
}
}
/* Has the IDList not yet been translated? */
if (sei_tmp.fMask & SEE_MASK_IDLIST)
{