diff --git a/dll/win32/shell32/shlexec.cpp b/dll/win32/shell32/shlexec.cpp index 3d74c669540..10d2756013c 100644 --- a/dll/win32/shell32/shlexec.cpp +++ b/dll/win32/shell32/shlexec.cpp @@ -1256,29 +1256,52 @@ HINSTANCE WINAPI FindExecutableA(LPCSTR lpFile, LPCSTR lpDirectory, LPSTR lpResu */ HINSTANCE WINAPI FindExecutableW(LPCWSTR lpFile, LPCWSTR lpDirectory, LPWSTR lpResult) { - UINT_PTR retval = SE_ERR_NOASSOC; - WCHAR old_dir[1024]; - WCHAR res[MAX_PATH]; + UINT_PTR retval; + WCHAR old_dir[MAX_PATH], res[MAX_PATH]; + DWORD cch = _countof(res); + LPCWSTR dirs[2]; TRACE("File %s, Dir %s\n", debugstr_w(lpFile), debugstr_w(lpDirectory)); - lpResult[0] = '\0'; /* Start off with an empty return string */ - if (lpFile == NULL) - return (HINSTANCE)SE_ERR_FNF; + *lpResult = UNICODE_NULL; - if (lpDirectory) + GetCurrentDirectoryW(_countof(old_dir), old_dir); + + if (lpDirectory && *lpDirectory) { - GetCurrentDirectoryW(ARRAY_SIZE(old_dir), old_dir); SetCurrentDirectoryW(lpDirectory); + dirs[0] = lpDirectory; + } + else + { + dirs[0] = old_dir; + } + dirs[1] = NULL; + + if (!GetShortPathNameW(lpFile, res, _countof(res))) + StringCchCopyW(res, _countof(res), lpFile); + + if (PathResolveW(res, dirs, PRF_TRYPROGRAMEXTENSIONS)) + { + // NOTE: The last parameter of this AssocQueryStringW call is "strange" in Windows. + if (PathIsExeW(res) || + SUCCEEDED(AssocQueryStringW(ASSOCF_NONE, ASSOCSTR_EXECUTABLE, res, NULL, res, &cch))) + { + StringCchCopyW(lpResult, MAX_PATH, res); + retval = 42; + } + else + { + retval = SE_ERR_NOASSOC; + } + } + else + { + retval = SE_ERR_FNF; } - retval = SHELL_FindExecutable(lpDirectory, lpFile, L"open", res, MAX_PATH, NULL, NULL, NULL, NULL); - if (retval > 32) - strcpyW(lpResult, res); - TRACE("returning %s\n", debugstr_w(lpResult)); - if (lpDirectory) - SetCurrentDirectoryW(old_dir); + SetCurrentDirectoryW(old_dir); return (HINSTANCE)retval; } @@ -2550,7 +2573,7 @@ HRESULT WINAPI ShellExecCmdLine( if (dwSeclFlags & SECL_RUNAS) { dwSize = 0; - hr = AssocQueryStringW(0, ASSOCSTR_COMMAND, lpCommand, L"RunAs", NULL, &dwSize); + hr = AssocQueryStringW(ASSOCF_NONE, ASSOCSTR_COMMAND, lpCommand, L"RunAs", NULL, &dwSize); if (SUCCEEDED(hr) && dwSize != 0) { pszVerb = L"runas";