From: Johannes Schindelin <[email protected]> In 2533912fc76c (Allow executing Windows Store's "app execution aliases", 2021-03-12), I introduced support for calling Microsoft Store applications.
However, it was reported several times (first in https://inbox.sourceware.org/cygwin/CAAM_cieBo_M76sqZMGgF+tXxswvT=juhl_pshff+arv9p1e...@mail.gmail.com and then also in https://github.com/msys2/MSYS2-packages/issues/1943#issuecomment-3467583078) that there is something amiss: The standard handles are not working as expected, as they are not connected to the terminal at all (and hence the application seems to "hang"). The culprit is the `is_console_app()` function which assumes that it can simply open the first few bytes of the `.exe` file to read the PE header in order to determine whether it is a console application or not. For app execution aliases, already creating a regular file handle for reading will fail. Let's introduce some special handling for the exact error code returned in those instances, and try to read the symlink target instead (taking advantage of the code I introduced in 0631c6644e63 (Cygwin: Treat Windows Store's "app execution aliases" as symbolic links, 2021-03-22) to treat app execution aliases like symbolic links). Fixes: 2533912fc76c (Allow executing Windows Store's "app execution aliases", 2021-03-12) Signed-off-by: Johannes Schindelin <[email protected]> --- winsup/cygwin/fhandler/termios.cc | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/winsup/cygwin/fhandler/termios.cc b/winsup/cygwin/fhandler/termios.cc index 5505bf416..7751b6357 100644 --- a/winsup/cygwin/fhandler/termios.cc +++ b/winsup/cygwin/fhandler/termios.cc @@ -710,6 +710,25 @@ is_console_app (const WCHAR *filename) HANDLE h; h = CreateFileW (filename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); + /* The "app execution aliases", i.e. the reparse points installed into + `%LOCALAPPDATA%\Microsoft\WindowsApps` for Microsoft Store apps cannot be + opened for reading via `CreateFile(..,. GENERIC_READ, ...)`, failing with + ERROR_CANT_ACCESS_FILE. Therefore, whenever that error is encountered, + let's see whether it is a reparse point and if it is, open the target + file instead. */ + if (h == INVALID_HANDLE_VALUE && GetLastError () == ERROR_CANT_ACCESS_FILE) + { + UNICODE_STRING ustr; + RtlInitUnicodeString (&ustr, filename); + path_conv pc (&ustr, PC_SYM_FOLLOW); + if (!pc.error && pc.exists ()) + { + tmp_pathbuf tp; + PWCHAR path = tp.w_get (); + h = CreateFileW (pc.get_wide_win32_path (path), GENERIC_READ, + FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); + } + } if (h == INVALID_HANDLE_VALUE) return false; char buf[1024]; -- cygwingitgadget
