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);
|
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
|
class COpenWithList
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -396,26 +446,23 @@ BOOL COpenWithList::LoadInfo(COpenWithList::SApp *pApp)
|
||||||
|
|
||||||
BOOL COpenWithList::GetPathFromCmd(LPWSTR pwszAppPath, LPCWSTR pwszCmd)
|
BOOL COpenWithList::GetPathFromCmd(LPWSTR pwszAppPath, LPCWSTR pwszCmd)
|
||||||
{
|
{
|
||||||
WCHAR wszBuf[MAX_PATH], *pwszDest = wszBuf;
|
WCHAR wszBuf[MAX_PATH];
|
||||||
|
|
||||||
/* Remove arguments */
|
/* Remove arguments */
|
||||||
if (pwszCmd[0] == '"')
|
if (!PathGetAppFromCommandLine(pwszCmd, wszBuf, _countof(wszBuf)))
|
||||||
{
|
return FALSE;
|
||||||
for(LPCWSTR pwszSrc = pwszCmd + 1; *pwszSrc && *pwszSrc != '"'; ++pwszSrc)
|
|
||||||
*(pwszDest++) = *pwszSrc;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
for(LPCWSTR pwszSrc = pwszCmd; *pwszSrc && *pwszSrc != ' '; ++pwszSrc)
|
|
||||||
*(pwszDest++) = *pwszSrc;
|
|
||||||
}
|
|
||||||
|
|
||||||
*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);
|
ExpandEnvironmentStrings(wszBuf, pwszAppPath, MAX_PATH);
|
||||||
if (!PathFileExists(pwszAppPath))
|
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;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -644,7 +691,7 @@ VOID COpenWithList::LoadRecommendedFromHKCU(LPCWSTR pwszExt)
|
||||||
LoadMRUList(hKey);
|
LoadMRUList(hKey);
|
||||||
LoadProgIdList(hKey, pwszExt);
|
LoadProgIdList(hKey, pwszExt);
|
||||||
|
|
||||||
/* Handle "Aplication" value */
|
/* Handle "Application" value */
|
||||||
DWORD cbBuf = sizeof(wszBuf);
|
DWORD cbBuf = sizeof(wszBuf);
|
||||||
if (RegGetValueW(hKey, NULL, L"Application", RRF_RT_REG_SZ, NULL, wszBuf, &cbBuf) == ERROR_SUCCESS)
|
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;
|
BOOL bUnknownApp = TRUE;
|
||||||
LPCWSTR pwszExt = PathFindExtensionW(m_wszPath);
|
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)
|
if (RegGetValueW(HKEY_CLASSES_ROOT, pwszExt, L"", RRF_RT_REG_SZ, NULL, wszBuf, &dwSize) == ERROR_SUCCESS)
|
||||||
{
|
{
|
||||||
bUnknownApp = FALSE;
|
bUnknownApp = FALSE;
|
||||||
StringCbCatW(wszBuf, sizeof(wszBuf), L"\\shell\\open\\command");
|
StringCbCatW(wszBuf, sizeof(wszBuf), L"\\shell\\open\\command");
|
||||||
dwSize = sizeof(wszPath);
|
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)
|
if (RegGetValueW(HKEY_CLASSES_ROOT, wszBuf, L"", RRF_RT_REG_SZ, NULL, wszPath, &dwSize) == ERROR_SUCCESS)
|
||||||
{
|
{
|
||||||
/* Get path from command line */
|
/* Get path from command line */
|
||||||
ExpandEnvironmentStringsW(wszPath, wszBuf, _countof(wszBuf));
|
ExpandEnvironmentStringsW(wszPath, wszBuf, _countof(wszBuf));
|
||||||
PathRemoveArgs(wszBuf);
|
if (SHELL32_GetDllFromRundll32CommandLine(wszBuf, wszBuf, _countof(wszBuf)) != S_OK)
|
||||||
PathUnquoteSpacesW(wszBuf);
|
{
|
||||||
|
PathRemoveArgs(wszBuf);
|
||||||
|
PathUnquoteSpacesW(wszBuf);
|
||||||
|
}
|
||||||
PathSearchAndQualify(wszBuf, wszPath, _countof(wszPath));
|
PathSearchAndQualify(wszBuf, wszPath, _countof(wszPath));
|
||||||
|
|
||||||
HICON hIcon;
|
HICON hIcon;
|
||||||
|
|
|
@ -293,6 +293,7 @@ BindCtx_RegisterObjectParam(
|
||||||
BOOL PathIsDotOrDotDotW(_In_ LPCWSTR pszPath);
|
BOOL PathIsDotOrDotDotW(_In_ LPCWSTR pszPath);
|
||||||
BOOL PathIsValidElement(_In_ LPCWSTR pszPath);
|
BOOL PathIsValidElement(_In_ LPCWSTR pszPath);
|
||||||
BOOL PathIsDosDevice(_In_ LPCWSTR pszName);
|
BOOL PathIsDosDevice(_In_ LPCWSTR pszName);
|
||||||
|
HRESULT SHELL32_GetDllFromRundll32CommandLine(LPCWSTR pszCmd, LPWSTR pszOut, SIZE_T cchMax);
|
||||||
HRESULT SHILAppend(_Inout_ LPITEMIDLIST pidl, _Inout_ LPITEMIDLIST *ppidl);
|
HRESULT SHILAppend(_Inout_ LPITEMIDLIST pidl, _Inout_ LPITEMIDLIST *ppidl);
|
||||||
|
|
||||||
PIDLIST_ABSOLUTE SHELL_CIDA_ILCloneFull(_In_ const CIDA *pCIDA, _In_ UINT Index);
|
PIDLIST_ABSOLUTE SHELL_CIDA_ILCloneFull(_In_ const CIDA *pCIDA, _In_ UINT Index);
|
||||||
|
|
Loading…
Reference in a new issue