*/
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;
- 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)))
+ 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;
+ }
TRACE("returning %s\n", debugstr_w(lpResult));
- if (lpDirectory)
- SetCurrentDirectoryW(old_dir);
+ SetCurrentDirectoryW(old_dir);
return (HINSTANCE)retval;
}
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";