1
0
mirror of https://github.com/wine-mirror/wine synced 2024-07-05 17:28:47 +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, typedef UINT_PTR (*SHELL_ExecuteW32)(const WCHAR *lpCmd, WCHAR *env, BOOL shWait,
const SHELLEXECUTEINFOW *sei, LPSHELLEXECUTEINFOW sei_out); const SHELLEXECUTEINFOW *sei, LPSHELLEXECUTEINFOW sei_out);
extern BOOL WINAPI PathResolveAW(void *path, const void **paths, DWORD flags); 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) static inline BOOL isSpace(WCHAR c)
{ {
@ -627,6 +628,39 @@ static UINT SHELL_FindExecutable(LPCWSTR lpPath, LPCWSTR lpFile, LPCWSTR lpVerb,
return 33; return 33;
} }
GetCurrentDirectoryW(ARRAY_SIZE(curdir), curdir);
if (!PathIsFileSpecW(lpFile))
{
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
{
if (lpPath && *lpPath) if (lpPath && *lpPath)
{ {
search_paths[0] = lpPath; search_paths[0] = lpPath;
@ -634,7 +668,6 @@ static UINT SHELL_FindExecutable(LPCWSTR lpPath, LPCWSTR lpFile, LPCWSTR lpVerb,
} }
else else
search_paths[0] = curdir; search_paths[0] = curdir;
GetCurrentDirectoryW(ARRAY_SIZE(curdir), curdir);
lstrcpyW(xlpFile, lpFile); lstrcpyW(xlpFile, lpFile);
if (PathResolveAW(xlpFile, (const void **)search_paths, PRF_TRYPROGRAMEXTENSIONS | PRF_VERIFYEXISTS)) if (PathResolveAW(xlpFile, (const void **)search_paths, PRF_TRYPROGRAMEXTENSIONS | PRF_VERIFYEXISTS))
{ {
@ -645,6 +678,7 @@ static UINT SHELL_FindExecutable(LPCWSTR lpPath, LPCWSTR lpFile, LPCWSTR lpVerb,
} }
else else
xlpFile[0] = '\0'; xlpFile[0] = '\0';
}
attribs = GetFileAttributesW(lpFile); attribs = GetFileAttributesW(lpFile);
if (attribs!=INVALID_FILE_ATTRIBUTES && (attribs&FILE_ATTRIBUTE_DIRECTORY)) 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 filename[2 * MAX_PATH + 17];
char params[1024]; char params[1024];
char curdir[MAX_PATH]; 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; INT_PTR rc;
*strrchr(dirname, '\\') = '\0';
sprintf(params, "shlexec \"%s\" Exec", child_file); sprintf(params, "shlexec \"%s\" Exec", child_file);
/* We need NOZONECHECKS on Win2003 to block a dialog */ /* We need NOZONECHECKS on Win2003 to block a dialog */
@ -2279,6 +2281,15 @@ static void test_exes(void)
okChildInt("argcA", 4); okChildInt("argcA", 4);
okChildString("argvA3", "Exec"); 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, rc=shell_execute_ex(SEE_MASK_NOZONECHECKS | SEE_MASK_CLASSNAME | SEE_MASK_FLAG_NO_UI, NULL, argv0, params,
NULL, ".exe"); NULL, ".exe");
okShell(rc > 32, "returned %Iu\n", rc); okShell(rc > 32, "returned %Iu\n", rc);