mirror of
https://github.com/reactos/reactos.git
synced 2025-02-28 19:32:59 +00:00
[SHELL32] OpenWith should use dll path instead when the command starts with rundll32 (#7712)
CORE-16980
This commit is contained in:
parent
396249d9e0
commit
a1157f86f2
3 changed files with 71 additions and 17 deletions
|
@ -31,6 +31,56 @@ WINE_DEFAULT_DEBUG_CHANNEL(shell);
|
|||
|
||||
EXTERN_C BOOL PathIsExeW(LPCWSTR lpszPath);
|
||||
|
||||
static SIZE_T PathGetAppFromCommandLine(LPCWSTR pszIn, LPWSTR pszOut, SIZE_T cchMax)
|
||||
{
|
||||
SIZE_T count = 0;
|
||||
WCHAR stop = ' ';
|
||||
if (pszIn[0] == '"')
|
||||
stop = *(pszIn++);
|
||||
|
||||
for (LPCWSTR pwszSrc = pszIn; *pwszSrc && *pwszSrc != stop; ++pwszSrc)
|
||||
{
|
||||
if (++count >= cchMax)
|
||||
return 0;
|
||||
*(pszOut++) = *pwszSrc;
|
||||
}
|
||||
*pszOut = UNICODE_NULL;
|
||||
return count;
|
||||
}
|
||||
|
||||
HRESULT SHELL32_GetDllFromRundll32CommandLine(LPCWSTR pszCmd, LPWSTR pszOut, SIZE_T cchMax)
|
||||
{
|
||||
WCHAR szDll[MAX_PATH + 100];
|
||||
if (!PathGetAppFromCommandLine(pszCmd, szDll, _countof(szDll)))
|
||||
return HRESULT_FROM_WIN32(ERROR_BUFFER_OVERFLOW);
|
||||
|
||||
PWSTR pszName = PathFindFileNameW(szDll);
|
||||
if (_wcsicmp(pszName, L"rundll32") && _wcsicmp(pszName, L"rundll32.exe"))
|
||||
return E_UNEXPECTED;
|
||||
|
||||
PCWSTR pszDllStart = pszCmd + (pszName - szDll) + lstrlenW(pszName);
|
||||
|
||||
if (*pszDllStart == '\"')
|
||||
++pszDllStart; // Skip possible end quote of ..\rundll32.exe" foo.dll,func
|
||||
while (*pszDllStart <= ' ' && *pszDllStart)
|
||||
++pszDllStart;
|
||||
if (PathGetAppFromCommandLine(pszDllStart, szDll, _countof(szDll)))
|
||||
{
|
||||
BOOL quoted = *pszDllStart == '\"';
|
||||
PWSTR pszComma = szDll + lstrlenW(szDll);
|
||||
while (!quoted && pszComma > szDll && *pszComma != ',' && *pszComma != '\\' && *pszComma != '/')
|
||||
--pszComma;
|
||||
SIZE_T cch = pszComma - szDll;
|
||||
if (cch <= cchMax && (quoted || *pszComma == ','))
|
||||
{
|
||||
*pszComma = UNICODE_NULL;
|
||||
lstrcpynW(pszOut, szDll, cchMax);
|
||||
return S_OK;
|
||||
}
|
||||
}
|
||||
return HRESULT_FROM_WIN32(ERROR_BUFFER_OVERFLOW);
|
||||
}
|
||||
|
||||
class COpenWithList
|
||||
{
|
||||
public:
|
||||
|
@ -396,26 +446,23 @@ BOOL COpenWithList::LoadInfo(COpenWithList::SApp *pApp)
|
|||
|
||||
BOOL COpenWithList::GetPathFromCmd(LPWSTR pwszAppPath, LPCWSTR pwszCmd)
|
||||
{
|
||||
WCHAR wszBuf[MAX_PATH], *pwszDest = wszBuf;
|
||||
WCHAR wszBuf[MAX_PATH];
|
||||
|
||||
/* Remove arguments */
|
||||
if (pwszCmd[0] == '"')
|
||||
{
|
||||
for(LPCWSTR pwszSrc = pwszCmd + 1; *pwszSrc && *pwszSrc != '"'; ++pwszSrc)
|
||||
*(pwszDest++) = *pwszSrc;
|
||||
}
|
||||
else
|
||||
{
|
||||
for(LPCWSTR pwszSrc = pwszCmd; *pwszSrc && *pwszSrc != ' '; ++pwszSrc)
|
||||
*(pwszDest++) = *pwszSrc;
|
||||
}
|
||||
if (!PathGetAppFromCommandLine(pwszCmd, wszBuf, _countof(wszBuf)))
|
||||
return FALSE;
|
||||
|
||||
*pwszDest = 0;
|
||||
/* Replace rundll32.exe with the dll path */
|
||||
SHELL32_GetDllFromRundll32CommandLine(pwszCmd, wszBuf, _countof(wszBuf));
|
||||
|
||||
/* Expand evn vers and optionally search for path */
|
||||
/* Expand env. vars and optionally search for path */
|
||||
ExpandEnvironmentStrings(wszBuf, pwszAppPath, MAX_PATH);
|
||||
if (!PathFileExists(pwszAppPath))
|
||||
return SearchPath(NULL, pwszAppPath, NULL, MAX_PATH, pwszAppPath, NULL);
|
||||
{
|
||||
UINT cch = SearchPathW(NULL, pwszAppPath, NULL, MAX_PATH, pwszAppPath, NULL);
|
||||
if (!cch || cch >= MAX_PATH)
|
||||
return FALSE;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
@ -644,7 +691,7 @@ VOID COpenWithList::LoadRecommendedFromHKCU(LPCWSTR pwszExt)
|
|||
LoadMRUList(hKey);
|
||||
LoadProgIdList(hKey, pwszExt);
|
||||
|
||||
/* Handle "Aplication" value */
|
||||
/* Handle "Application" value */
|
||||
DWORD cbBuf = sizeof(wszBuf);
|
||||
if (RegGetValueW(hKey, NULL, L"Application", RRF_RT_REG_SZ, NULL, wszBuf, &cbBuf) == ERROR_SUCCESS)
|
||||
{
|
||||
|
|
|
@ -299,17 +299,23 @@ CFileDefExt::InitOpensWithField(HWND hwndDlg)
|
|||
BOOL bUnknownApp = TRUE;
|
||||
LPCWSTR pwszExt = PathFindExtensionW(m_wszPath);
|
||||
|
||||
// TODO: Use ASSOCSTR_EXECUTABLE with ASSOCF_REMAPRUNDLL | ASSOCF_IGNOREBASECLASS
|
||||
if (RegGetValueW(HKEY_CLASSES_ROOT, pwszExt, L"", RRF_RT_REG_SZ, NULL, wszBuf, &dwSize) == ERROR_SUCCESS)
|
||||
{
|
||||
bUnknownApp = FALSE;
|
||||
StringCbCatW(wszBuf, sizeof(wszBuf), L"\\shell\\open\\command");
|
||||
dwSize = sizeof(wszPath);
|
||||
// FIXME: Missing FileExt check, see COpenWithList::SetDefaultHandler for details
|
||||
// FIXME: Use HCR_GetDefaultVerbW to find the default verb
|
||||
if (RegGetValueW(HKEY_CLASSES_ROOT, wszBuf, L"", RRF_RT_REG_SZ, NULL, wszPath, &dwSize) == ERROR_SUCCESS)
|
||||
{
|
||||
/* Get path from command line */
|
||||
ExpandEnvironmentStringsW(wszPath, wszBuf, _countof(wszBuf));
|
||||
PathRemoveArgs(wszBuf);
|
||||
PathUnquoteSpacesW(wszBuf);
|
||||
if (SHELL32_GetDllFromRundll32CommandLine(wszBuf, wszBuf, _countof(wszBuf)) != S_OK)
|
||||
{
|
||||
PathRemoveArgs(wszBuf);
|
||||
PathUnquoteSpacesW(wszBuf);
|
||||
}
|
||||
PathSearchAndQualify(wszBuf, wszPath, _countof(wszPath));
|
||||
|
||||
HICON hIcon;
|
||||
|
|
|
@ -293,6 +293,7 @@ BindCtx_RegisterObjectParam(
|
|||
BOOL PathIsDotOrDotDotW(_In_ LPCWSTR pszPath);
|
||||
BOOL PathIsValidElement(_In_ LPCWSTR pszPath);
|
||||
BOOL PathIsDosDevice(_In_ LPCWSTR pszName);
|
||||
HRESULT SHELL32_GetDllFromRundll32CommandLine(LPCWSTR pszCmd, LPWSTR pszOut, SIZE_T cchMax);
|
||||
HRESULT SHILAppend(_Inout_ LPITEMIDLIST pidl, _Inout_ LPITEMIDLIST *ppidl);
|
||||
|
||||
PIDLIST_ABSOLUTE SHELL_CIDA_ILCloneFull(_In_ const CIDA *pCIDA, _In_ UINT Index);
|
||||
|
|
Loading…
Reference in a new issue