mirror of
https://github.com/reactos/reactos.git
synced 2025-02-22 08:25:03 +00:00
[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:
parent
c1b9bb5700
commit
6f277e9766
3 changed files with 68 additions and 2 deletions
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue