1
0
mirror of https://github.com/wine-mirror/wine synced 2024-06-29 06:14:34 +00:00

shell32: Fix ShellExecute for non-filespec paths.

This commit is contained in:
Yuxuan Shui 2024-05-20 09:51:07 +01:00 committed by Alexandre Julliard
parent 436e96c5cb
commit 0bad544aab
2 changed files with 60 additions and 15 deletions

View File

@ -49,6 +49,7 @@ WINE_DEFAULT_DEBUG_CHANNEL(exec);
typedef UINT_PTR (*SHELL_ExecuteW32)(const WCHAR *lpCmd, WCHAR *env, BOOL shWait,
const SHELLEXECUTEINFOW *sei, LPSHELLEXECUTEINFOW sei_out);
extern BOOL WINAPI PathResolveAW(void *path, const void **paths, DWORD flags);
extern BOOL WINAPI PathFileExistsDefExtW(LPWSTR lpszPath,DWORD dwWhich);
static inline BOOL isSpace(WCHAR c)
{
@ -627,24 +628,57 @@ static UINT SHELL_FindExecutable(LPCWSTR lpPath, LPCWSTR lpFile, LPCWSTR lpVerb,
return 33;
}
if (lpPath && *lpPath)
{
search_paths[0] = lpPath;
search_paths[1] = curdir;
}
else
search_paths[0] = curdir;
GetCurrentDirectoryW(ARRAY_SIZE(curdir), curdir);
lstrcpyW(xlpFile, lpFile);
if (PathResolveAW(xlpFile, (const void **)search_paths, PRF_TRYPROGRAMEXTENSIONS | PRF_VERIFYEXISTS))
if (!PathIsFileSpecW(lpFile))
{
TRACE("PathResolveAW returned non-zero\n");
lpFile = xlpFile;
lstrcpyW(lpResult, xlpFile);
/* The file was found in lpPath or one of the directories in the system-wide search path */
BOOL found = FALSE;
if (lpPath && *lpPath)
{
TRACE("ASDF %s\n", debugstr_w(lpPath));
PathCombineW(xlpFile, lpPath, lpFile);
if (PathFileExistsDefExtW(xlpFile, 0xbf))
{
GetFullPathNameW(xlpFile, ARRAY_SIZE(xlpFile), xlpFile, NULL);
found = TRUE;
}
}
if (!found)
{
lstrcpyW(xlpFile, lpFile);
if (PathFileExistsDefExtW(xlpFile, 0xbf))
{
GetFullPathNameW(xlpFile, ARRAY_SIZE(xlpFile), xlpFile, NULL);
found = TRUE;
}
}
if (found)
{
lpFile = xlpFile;
lstrcpyW(lpResult, xlpFile);
}
else
xlpFile[0] = '\0';
}
else
xlpFile[0] = '\0';
{
if (lpPath && *lpPath)
{
search_paths[0] = lpPath;
search_paths[1] = curdir;
}
else
search_paths[0] = curdir;
lstrcpyW(xlpFile, lpFile);
if (PathResolveAW(xlpFile, (const void **)search_paths, PRF_TRYPROGRAMEXTENSIONS | PRF_VERIFYEXISTS))
{
TRACE("PathResolveAW returned non-zero\n");
lpFile = xlpFile;
lstrcpyW(lpResult, xlpFile);
/* The file was found in lpPath or one of the directories in the system-wide search path */
}
else
xlpFile[0] = '\0';
}
attribs = GetFileAttributesW(lpFile);
if (attribs!=INVALID_FILE_ATTRIBUTES && (attribs&FILE_ATTRIBUTE_DIRECTORY))

View File

@ -2267,9 +2267,11 @@ static void test_exes(void)
char filename[2 * MAX_PATH + 17];
char params[1024];
char curdir[MAX_PATH];
char *basename = strrchr(argv0, '\\') + 1;
char relative_basename[MAX_PATH];
char *basename = strrchr(argv0, '\\') + 1, *dirname = strdup(argv0);
INT_PTR rc;
*strrchr(dirname, '\\') = '\0';
sprintf(params, "shlexec \"%s\" Exec", child_file);
/* We need NOZONECHECKS on Win2003 to block a dialog */
@ -2279,6 +2281,15 @@ static void test_exes(void)
okChildInt("argcA", 4);
okChildString("argvA3", "Exec");
/* Check non-filespec paths */
snprintf(relative_basename, ARRAY_SIZE(relative_basename), ".\\\\%s", basename);
rc=shell_execute_ex(SEE_MASK_NOZONECHECKS | SEE_MASK_FLAG_NO_UI, NULL, relative_basename, params,
dirname, NULL);
okShell(rc > 32, "returned %Iu\n", rc);
okChildInt("argcA", 4);
okChildString("argvA3", "Exec");
free(dirname);
rc=shell_execute_ex(SEE_MASK_NOZONECHECKS | SEE_MASK_CLASSNAME | SEE_MASK_FLAG_NO_UI, NULL, argv0, params,
NULL, ".exe");
okShell(rc > 32, "returned %Iu\n", rc);