mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 01:55:19 +00:00
[SHELL32] Don't add the file to the parameters if the registry command did not ask for a file (#7139)
Bugs fixed: - fDefault detection of default verb is flawed because it checks the ici struct after conversion instead of the source sei struct. - The command to execute should not have the filename appended just because %1 nor %L did not appear in the registry command template.
This commit is contained in:
parent
8f483a76a6
commit
724b20d414
5 changed files with 61 additions and 26 deletions
|
@ -1302,8 +1302,7 @@ CDefaultContextMenu::TryToBrowse(
|
|||
HRESULT
|
||||
CDefaultContextMenu::InvokePidl(LPCMINVOKECOMMANDINFOEX lpcmi, LPCITEMIDLIST pidl, PStaticShellEntry pEntry)
|
||||
{
|
||||
BOOL unicode = lpcmi->cbSize >= FIELD_OFFSET(CMINVOKECOMMANDINFOEX, ptInvoke) &&
|
||||
(lpcmi->fMask & CMIC_MASK_UNICODE);
|
||||
const BOOL unicode = IsUnicode(*lpcmi);
|
||||
|
||||
LPITEMIDLIST pidlFull = ILCombine(m_pidlFolder, pidl);
|
||||
if (pidlFull == NULL)
|
||||
|
@ -1315,7 +1314,23 @@ CDefaultContextMenu::InvokePidl(LPCMINVOKECOMMANDINFOEX lpcmi, LPCITEMIDLIST pid
|
|||
BOOL bHasPath = SHGetPathFromIDListW(pidlFull, wszPath);
|
||||
|
||||
WCHAR wszDir[MAX_PATH];
|
||||
if (bHasPath)
|
||||
|
||||
SHELLEXECUTEINFOW sei = { sizeof(sei) };
|
||||
sei.fMask = SEE_MASK_CLASSKEY | SEE_MASK_IDLIST | (CmicFlagsToSeeFlags(lpcmi->fMask) & ~SEE_MASK_INVOKEIDLIST);
|
||||
sei.hwnd = lpcmi->hwnd;
|
||||
sei.nShow = lpcmi->nShow;
|
||||
sei.lpVerb = pEntry->Verb;
|
||||
sei.lpIDList = pidlFull;
|
||||
sei.hkeyClass = pEntry->hkClass;
|
||||
sei.dwHotKey = lpcmi->dwHotKey;
|
||||
sei.hIcon = lpcmi->hIcon;
|
||||
sei.lpDirectory = wszDir;
|
||||
|
||||
if (unicode && !StrIsNullOrEmpty(lpcmi->lpDirectoryW))
|
||||
{
|
||||
sei.lpDirectory = lpcmi->lpDirectoryW;
|
||||
}
|
||||
else if (bHasPath)
|
||||
{
|
||||
wcscpy(wszDir, wszPath);
|
||||
PathRemoveFileSpec(wszDir);
|
||||
|
@ -1326,25 +1341,16 @@ CDefaultContextMenu::InvokePidl(LPCMINVOKECOMMANDINFOEX lpcmi, LPCITEMIDLIST pid
|
|||
*wszDir = UNICODE_NULL;
|
||||
}
|
||||
|
||||
CComHeapPtr<WCHAR> pszParamsW;
|
||||
SHELLEXECUTEINFOW sei = { sizeof(sei) };
|
||||
sei.hwnd = lpcmi->hwnd;
|
||||
sei.nShow = SW_SHOWNORMAL;
|
||||
sei.lpVerb = pEntry->Verb;
|
||||
sei.lpDirectory = wszDir;
|
||||
sei.lpIDList = pidlFull;
|
||||
sei.hkeyClass = pEntry->hkClass;
|
||||
sei.fMask = SEE_MASK_CLASSKEY | SEE_MASK_IDLIST;
|
||||
if (bHasPath)
|
||||
sei.lpFile = wszPath;
|
||||
|
||||
CComHeapPtr<WCHAR> pszParamsW;
|
||||
if (unicode && !StrIsNullOrEmpty(lpcmi->lpParametersW))
|
||||
sei.lpParameters = lpcmi->lpParametersW;
|
||||
else if (!StrIsNullOrEmpty(lpcmi->lpParameters) && __SHCloneStrAtoW(&pszParamsW, lpcmi->lpParameters))
|
||||
sei.lpParameters = pszParamsW;
|
||||
|
||||
ShellExecuteExW(&sei);
|
||||
|
||||
ILFree(pidlFull);
|
||||
|
||||
return S_OK;
|
||||
|
|
|
@ -2592,8 +2592,7 @@ HRESULT STDMETHODCALLTYPE CShellLink::InvokeCommand(LPCMINVOKECOMMANDINFO lpici)
|
|||
|
||||
HRESULT CShellLink::DoOpen(LPCMINVOKECOMMANDINFO lpici)
|
||||
{
|
||||
BOOL unicode = lpici->cbSize >= FIELD_OFFSET(CMINVOKECOMMANDINFOEX, ptInvoke) &&
|
||||
(lpici->fMask & CMIC_MASK_UNICODE);
|
||||
const BOOL unicode = IsUnicode(*lpici);
|
||||
|
||||
CStringW args;
|
||||
if (m_sArgs)
|
||||
|
|
|
@ -155,6 +155,15 @@ UINT
|
|||
GetDfmCmd(_In_ IContextMenu *pCM, _In_ LPCSTR verba);
|
||||
#define SHELL_ExecuteControlPanelCPL(hwnd, cpl) SHRunControlPanel((cpl), (hwnd))
|
||||
|
||||
#define CmicFlagsToSeeFlags(flags) ((flags) & SEE_CMIC_COMMON_FLAGS)
|
||||
static inline UINT SeeFlagsToCmicFlags(UINT flags)
|
||||
{
|
||||
if (flags & SEE_MASK_CLASSNAME)
|
||||
flags &= ~(SEE_MASK_HASLINKNAME | SEE_MASK_HASTITLE);
|
||||
return flags & SEE_CMIC_COMMON_FLAGS;
|
||||
}
|
||||
|
||||
|
||||
// CStubWindow32 --- The owner window of file property sheets.
|
||||
// This window hides taskbar button of property sheet.
|
||||
class CStubWindow32 : public CWindowImpl<CStubWindow32>
|
||||
|
|
|
@ -491,7 +491,7 @@ static UINT_PTR SHELL_ExecuteW(const WCHAR *lpCmd, WCHAR *env, BOOL shWait,
|
|||
|
||||
/* make sure we don't fail the CreateProcess if the calling app passes in
|
||||
* a bad working directory */
|
||||
if (psei->lpDirectory && psei->lpDirectory[0])
|
||||
if (!StrIsNullOrEmpty(psei->lpDirectory))
|
||||
{
|
||||
DWORD attr = GetFileAttributesW(psei->lpDirectory);
|
||||
if (attr != INVALID_FILE_ATTRIBUTES && attr & FILE_ATTRIBUTE_DIRECTORY)
|
||||
|
@ -1559,9 +1559,9 @@ static HRESULT ShellExecute_ContextMenuVerb(LPSHELLEXECUTEINFOW sei)
|
|||
__SHCloneStrWtoA(&verb, sei->lpVerb);
|
||||
__SHCloneStrWtoA(¶meters, sei->lpParameters);
|
||||
|
||||
BOOL fDefault = !sei->lpVerb || !sei->lpVerb[0];
|
||||
BOOL fDefault = StrIsNullOrEmpty(sei->lpVerb);
|
||||
CMINVOKECOMMANDINFOEX ici = { sizeof(ici) };
|
||||
ici.fMask = (sei->fMask & (SEE_MASK_NO_CONSOLE | SEE_MASK_ASYNCOK | SEE_MASK_FLAG_NO_UI)) | CMIC_MASK_UNICODE;
|
||||
ici.fMask = SeeFlagsToCmicFlags(sei->fMask) | CMIC_MASK_UNICODE;
|
||||
ici.nShow = sei->nShow;
|
||||
if (!fDefault)
|
||||
{
|
||||
|
@ -1571,20 +1571,20 @@ static HRESULT ShellExecute_ContextMenuVerb(LPSHELLEXECUTEINFOW sei)
|
|||
ici.hwnd = sei->hwnd;
|
||||
ici.lpParameters = parameters;
|
||||
ici.lpParametersW = sei->lpParameters;
|
||||
if ((sei->fMask & (SEE_MASK_HASLINKNAME | SEE_MASK_CLASSNAME)) == SEE_MASK_HASLINKNAME)
|
||||
{
|
||||
ici.fMask |= CMIC_MASK_HASLINKNAME;
|
||||
ici.dwHotKey = sei->dwHotKey;
|
||||
ici.hIcon = sei->hIcon;
|
||||
if (ici.fMask & (CMIC_MASK_HASLINKNAME | CMIC_MASK_HASTITLE))
|
||||
ici.lpTitleW = sei->lpClass;
|
||||
}
|
||||
|
||||
enum { idFirst = 1, idLast = 0x7fff };
|
||||
HMENU hMenu = CreatePopupMenu();
|
||||
hr = cm->QueryContextMenu(hMenu, 0, 1, 0x7fff, fDefault ? CMF_DEFAULTONLY : 0);
|
||||
hr = cm->QueryContextMenu(hMenu, 0, idFirst, idLast, fDefault ? CMF_DEFAULTONLY : 0);
|
||||
if (!FAILED_UNEXPECTEDLY(hr))
|
||||
{
|
||||
if (fDefault)
|
||||
{
|
||||
INT uDefault = GetMenuDefaultItem(hMenu, FALSE, 0);
|
||||
uDefault = (uDefault != -1) ? uDefault - 1 : 0;
|
||||
uDefault = (uDefault != -1) ? uDefault - idFirst : 0;
|
||||
ici.lpVerb = MAKEINTRESOURCEA(uDefault);
|
||||
ici.lpVerbW = MAKEINTRESOURCEW(uDefault);
|
||||
}
|
||||
|
@ -1600,7 +1600,6 @@ static HRESULT ShellExecute_ContextMenuVerb(LPSHELLEXECUTEINFOW sei)
|
|||
}
|
||||
|
||||
|
||||
|
||||
/*************************************************************************
|
||||
* ShellExecute_FromContextMenu [Internal]
|
||||
*/
|
||||
|
@ -1676,6 +1675,8 @@ static UINT_PTR SHELL_execute_class(LPCWSTR wszApplicationName, LPSHELLEXECUTEIN
|
|||
&resultLen, (psei->lpDirectory && *psei->lpDirectory) ? psei->lpDirectory : NULL);
|
||||
if (!done && wszApplicationName[0])
|
||||
{
|
||||
#if 0 // Given HKCR\.test=SZ:"test" and HKCR\test\shell\open\command=SZ:"cmd.exe /K echo.Hello", no filename is
|
||||
// appended on Windows when there is no %1 nor %L when executed with: shlextdbg.exe /shellexec=c:\file.test /INVOKE
|
||||
strcatW(wcmd, L" ");
|
||||
if (*wszApplicationName != '"')
|
||||
{
|
||||
|
@ -1685,6 +1686,7 @@ static UINT_PTR SHELL_execute_class(LPCWSTR wszApplicationName, LPSHELLEXECUTEIN
|
|||
}
|
||||
else
|
||||
strcatW(wcmd, wszApplicationName);
|
||||
#endif
|
||||
}
|
||||
if (resultLen > ARRAY_SIZE(wcmd))
|
||||
ERR("Argify buffer not large enough... truncating\n");
|
||||
|
|
|
@ -609,6 +609,12 @@ struct CCoInit
|
|||
#define S_GREATERTHAN S_FALSE
|
||||
#define MAKE_COMPARE_HRESULT(x) ((x)>0 ? S_GREATERTHAN : ((x)<0 ? S_LESSTHAN : S_EQUAL))
|
||||
|
||||
#define SEE_CMIC_COMMON_BASICFLAGS (SEE_MASK_NOASYNC | SEE_MASK_ASYNCOK | SEE_MASK_UNICODE | \
|
||||
SEE_MASK_NO_CONSOLE | SEE_MASK_FLAG_NO_UI | SEE_MASK_FLAG_SEPVDM | \
|
||||
SEE_MASK_FLAG_LOG_USAGE | SEE_MASK_NOZONECHECKS)
|
||||
#define SEE_CMIC_COMMON_FLAGS (SEE_CMIC_COMMON_BASICFLAGS | SEE_MASK_HOTKEY | SEE_MASK_ICON | \
|
||||
SEE_MASK_HASLINKNAME | SEE_MASK_HASTITLE)
|
||||
|
||||
static inline BOOL ILIsSingle(LPCITEMIDLIST pidl)
|
||||
{
|
||||
return pidl == ILFindLastID(pidl);
|
||||
|
@ -627,6 +633,19 @@ static inline PCUIDLIST_RELATIVE HIDA_GetPIDLItem(CIDA const* pida, SIZE_T i)
|
|||
|
||||
#ifdef __cplusplus
|
||||
|
||||
#if defined(CMIC_MASK_UNICODE) && defined(SEE_MASK_UNICODE)
|
||||
static inline bool IsUnicode(const CMINVOKECOMMANDINFOEX &ici)
|
||||
{
|
||||
const UINT minsize = FIELD_OFFSET(CMINVOKECOMMANDINFOEX, ptInvoke);
|
||||
return (ici.fMask & CMIC_MASK_UNICODE) && ici.cbSize >= minsize;
|
||||
}
|
||||
|
||||
static inline bool IsUnicode(const CMINVOKECOMMANDINFO &ici)
|
||||
{
|
||||
return IsUnicode(*(CMINVOKECOMMANDINFOEX*)&ici);
|
||||
}
|
||||
#endif // CMIC_MASK_UNICODE
|
||||
|
||||
DECLSPEC_SELECTANY CLIPFORMAT g_cfHIDA = NULL;
|
||||
DECLSPEC_SELECTANY CLIPFORMAT g_cfShellIdListOffsets = NULL;
|
||||
|
||||
|
@ -784,7 +803,7 @@ DataObject_SetOffset(IDataObject* pDataObject, POINT* point)
|
|||
return DataObject_SetData(pDataObject, g_cfShellIdListOffsets, point, sizeof(point[0]));
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif // __cplusplus
|
||||
|
||||
#ifdef __cplusplus
|
||||
struct SHELL_GetSettingImpl
|
||||
|
|
Loading…
Reference in a new issue