[PATCH 0/3] MR5400: Draft: shell32: Tying up some loose ends
Follow up to !5342. This adds the last missing piece for fixing how `ShellExecute` finds files, and restore the ability of running native unix programs with `ShellExecute` -- https://gitlab.winehq.org/wine/wine/-/merge_requests/5400
From: Yuxuan Shui <yshui(a)codeweavers.com> --- dlls/shell32/shlexec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dlls/shell32/shlexec.c b/dlls/shell32/shlexec.c index f09b6d4daf3..804aa38a904 100644 --- a/dlls/shell32/shlexec.c +++ b/dlls/shell32/shlexec.c @@ -637,7 +637,7 @@ static UINT SHELL_FindExecutable(LPCWSTR lpPath, LPCWSTR lpFile, LPCWSTR lpVerb, lstrcpyW(xlpFile, lpFile); if (PathResolveAW(xlpFile, (const void **)search_paths, PRF_TRYPROGRAMEXTENSIONS | PRF_VERIFYEXISTS)) { - TRACE("SearchPathW returned non-zero\n"); + TRACE("PathResolveAW returned non-zero\n"); lpFile = xlpFile; /* The file was found in lpPath or one of the directories in the system-wide search path */ } -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/5400
From: Yuxuan Shui <yshui(a)codeweavers.com> So that the path returned by SHELL_FindExecutable would be fully qualified, otherwise CreateProcess will do its own path resolution which is not what we want. --- dlls/shell32/shlexec.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/dlls/shell32/shlexec.c b/dlls/shell32/shlexec.c index 804aa38a904..9704f9d8f06 100644 --- a/dlls/shell32/shlexec.c +++ b/dlls/shell32/shlexec.c @@ -1797,10 +1797,10 @@ static BOOL SHELL_execute( LPSHELLEXECUTEINFOW sei, SHELL_ExecuteW32 execfunc ) if (*sei_tmp.lpDirectory) { + LPWSTR buf; len = ExpandEnvironmentStringsW(sei_tmp.lpDirectory, NULL, 0); if (len > 0) { - LPWSTR buf; len++; buf = malloc(len * sizeof(WCHAR)); ExpandEnvironmentStringsW(sei_tmp.lpDirectory, buf, len); @@ -1809,6 +1809,18 @@ static BOOL SHELL_execute( LPSHELLEXECUTEINFOW sei, SHELL_ExecuteW32 execfunc ) wszDir = buf; sei_tmp.lpDirectory = wszDir; } + + len = GetFullPathNameW(sei_tmp.lpDirectory, 0, NULL, NULL); + if (len > 0) + { + len++; + buf = malloc(len * sizeof(WCHAR)); + GetFullPathNameW(sei_tmp.lpDirectory, len, buf, NULL); + if (wszDir != dirBuffer) + free(wszDir); + wszDir = buf; + sei_tmp.lpDirectory = wszDir; + } } /* Else, try to execute the filename */ -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/5400
From: Yuxuan Shui <yshui(a)codeweavers.com> When ShellExecute is called with the expressed intention to run a file without an extension (i.e. by putting a trailing dot in the file name), honor that and try running the file as a program. --- dlls/shell32/shlexec.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/dlls/shell32/shlexec.c b/dlls/shell32/shlexec.c index 9704f9d8f06..b437f98e6e6 100644 --- a/dlls/shell32/shlexec.c +++ b/dlls/shell32/shlexec.c @@ -601,6 +601,7 @@ static UINT SHELL_FindExecutable(LPCWSTR lpPath, LPCWSTR lpFile, LPCWSTR lpVerb, WCHAR xlpFile[256]; /* result of SearchPath */ DWORD attribs; /* file attributes */ WCHAR curdir[MAX_PATH]; + BOOL has_trailing_dot; const WCHAR *search_paths[3] = {0}; TRACE("%s\n", debugstr_w(lpFile)); @@ -626,6 +627,7 @@ static UINT SHELL_FindExecutable(LPCWSTR lpPath, LPCWSTR lpFile, LPCWSTR lpVerb, return 33; } + has_trailing_dot = lpFile[lstrlenW(lpFile) - 1] == '.'; if (lpPath && *lpPath) { search_paths[0] = lpPath; @@ -663,10 +665,18 @@ static UINT SHELL_FindExecutable(LPCWSTR lpPath, LPCWSTR lpFile, LPCWSTR lpVerb, /* .\FILE.EXE :( */ TRACE("xlpFile=%s,extension=%s\n", debugstr_w(xlpFile), debugstr_w(extension)); - if (extension == NULL || extension[1]==0) + if (extension == NULL) { - WARN("Returning SE_ERR_NOASSOC\n"); - return SE_ERR_NOASSOC; + if (!has_trailing_dot) + { + WARN("Returning SE_ERR_NOASSOC\n"); + return SE_ERR_NOASSOC; + } + + /* Special wine extension to support running a native unix program, + * if the file name has an trailing dot. */ + lstrcpyW(lpResult, xlpFile); + return 33; } /* Three places to check: */ -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/5400
Would it be possible to add some tests? -- https://gitlab.winehq.org/wine/wine/-/merge_requests/5400#note_66246
On Wed Mar 27 14:24:44 2024 +0000, Huw Davies wrote:
Would it be possible to add some tests? What's the best way to add tests that only run on wine? Can't test running unix programs on Windows, also feels odd to use `broken` here.
-- https://gitlab.winehq.org/wine/wine/-/merge_requests/5400#note_66279
This is still failing for me. ShellExecute( NULL, NULL, "linuxbinary", "1", "c:\temp\", SW_SHOW); -- https://gitlab.winehq.org/wine/wine/-/merge_requests/5400#note_66316
On Fri Mar 29 18:13:51 2024 +0000, Alistair Leslie-Hughes wrote:
This is still failing for me. ShellExecute( NULL, NULL, "linuxbinary", "1", "c:\temp\", SW_SHOW); what about "linuxbinary." ?
-- https://gitlab.winehq.org/wine/wine/-/merge_requests/5400#note_66494
participants (4)
-
Alistair Leslie-Hughes (@alesliehughes) -
Huw Davies (@huw) -
Yuxuan Shui -
Yuxuan Shui (@yshui)