diff --git a/dll/win32/shell32/shlexec.cpp b/dll/win32/shell32/shlexec.cpp index ce8113aefa9..d53ffdc9349 100644 --- a/dll/win32/shell32/shlexec.cpp +++ b/dll/win32/shell32/shlexec.cpp @@ -1259,25 +1259,49 @@ HINSTANCE WINAPI FindExecutableW(LPCWSTR lpFile, LPCWSTR lpDirectory, LPWSTR lpR UINT_PTR retval = SE_ERR_NOASSOC; WCHAR old_dir[1024]; WCHAR res[MAX_PATH]; + 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; - 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; - retval = SHELL_FindExecutable(lpDirectory, lpFile, L"open", res, MAX_PATH, NULL, NULL, NULL, NULL); - if (retval > 32) - strcpyW(lpResult, res); + if (!GetShortPathNameW(lpFile, res, _countof(res))) + lstrcpynW(res, lpFile, _countof(res)); + + if (PathResolveW(res, dirs, PRF_TRYPROGRAMEXTENSIONS)) + { + if (PathIsExeW(res)) + { + DWORD cchPath = _countof(res); + HRESULT hr = AssocQueryStringW(0, ASSOCSTR_EXECUTABLE, res, NULL, res, &cchPath); + if (SUCCEEDED(hr)) + StrCpyNW(lpResult, res, _countof(res)); + } + else + { + retval = SE_ERR_NOASSOC; + } + } + else + { + retval = SE_ERR_FNF; + } TRACE("returning %s\n", debugstr_w(lpResult)); - if (lpDirectory) + if (lpDirectory && *lpDirectory) SetCurrentDirectoryW(old_dir); return (HINSTANCE)retval; }