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

Reply via email to