Re: [PATCH 1/2] Treat Windows Store's "app execution aliases" as symbolic links

2021-03-15 Thread Corinna Vinschen via Cygwin-patches
Hi Johannes,

I'm not opposed to treat these applinks as symlinks.  I have a
suggestion and a style nit, though.

On Mar 12 16:11, Johannes Schindelin via Cygwin-patches wrote:
> When the Windows Store version of Python is installed, so-called "app
> execution aliases" are put into the `PATH`. These are reparse points
> under the hood, with an undocumented format.
> 
> We do know a bit about this format, though, as per the excellent analysis:
> https://www.tiraniddo.dev/2019/09/overview-of-windows-execution-aliases.html
> 
>   The first 4 bytes is the reparse tag, in this case it's
>   0x801B which is documented in the Windows SDK as
>   IO_REPARSE_TAG_APPEXECLINK. Unfortunately there doesn't seem to
>   be a corresponding structure, but with a bit of reverse
>   engineering we can work out the format is as follows:
> 
>   Version: <4 byte integer>
>   Package ID: 
>   Entry Point: 
>   Executable: 
>   Application Type: 

Given we know this layout, what about introducing a matching struct,
like I did for REPARSE_LX_SYMLINK_BUFFER, for instructional purposes?

I. e.

typedef struct _REPARSE_APPEXECLINK_BUFFER
{
  DWORD ReparseTag;
  WORD  ReparseDataLength;
  WORD  Reserved;
  struct {
DWORD Version;   /* Take member name with a grain of salt. */
WCHAR Strings[1];/* Four serialized, NUL-terminated WCHAR strings:
- Package ID
- Entry Point
- Executable Path
- Application Type
We're only interested in the Executable Path */
  } AppExecLinkReparseBuffer;
} REPARSE_APPEXECLINK_BUFFER,*PREPARSE_APPEXECLINK_BUFFER;


> +  else if (!remote && rp->ReparseTag == IO_REPARSE_TAG_APPEXECLINK)
> +{
> +  /* App execution aliases are commonly used by Windows Store apps. */
> +  WCHAR *buf = (WCHAR *)(rp->GenericReparseBuffer.DataBuffer + 4);

Analogue:

 PREPARSE_APPEXECLINK_BUFFER rpl = (PREPARSE_APPEXECLINK_BUFFER) rp;
 WCHAR *buf = rpl->AppExecLinkReparseBuffer.Strings;

Maybe use 'str' or 'strp' here, instead of buf?

> +  for (int i = 0; i < 3 && size > 0; i++)
> +{
> +   n = wcsnlen (buf, size - 1);
> +   if (i == 2 && n > 0 && n < size)
> + {
> +   RtlInitCountedUnicodeString (psymbuf, buf, n * sizeof(WCHAR));
  ^^^
  space


Thanks,
Corinna


Re: [PATCH 1/2] Treat Windows Store's "app execution aliases" as symbolic links

2021-03-15 Thread Hans-Bernhard Bröker

Am 15.03.2021 um 04:19 schrieb Johannes Schindelin via Cygwin-patches:

Hi Joe,

On Sat, 13 Mar 2021, Joe Lowe wrote:


I agree on the usefulness to the user of showing appexec target executable as
symlink target. But I am uncertain about the effect on code.


Maybe. But I am concerned about the effect of not being able to do
anything useful with app execution aliases in the first place. 


That argument might hold more sway if Windows itself didn't quite so 
completely hide that information from users, too.


I found only one Windows native tool that will even show _any_ kind of 
information about these reparse points: fsutil.  That is a) only 
available as part of the highly optional WSL feature and b) only gives 
you a hexdump of the actual data, without any meaningful interpretation.


For something that Windows itself gives the "no user servicable parts 
inside" treatment to the extent it does for these reparse points, I 
rather doubt that Cygwin users really _need_ to see it.




Re: [PATCH 1/2] Treat Windows Store's "app execution aliases" as symbolic links

2021-03-15 Thread Johannes Schindelin via Cygwin-patches
Hi Joe,

On Sat, 13 Mar 2021, Joe Lowe wrote:

> I agree on the usefulness to the user of showing appexec target executable as
> symlink target. But I am uncertain about the effect on code.

Maybe. But I am concerned about the effect of not being able to do
anything useful with app execution aliases in the first place. I'd rather
have them represented as if they were symlinks (even if that is not 100%
accurate) than not being able to even answer the very simple (and
obvious!) question: where does this thing point to?

> One example: Any app that is able to archive/copy posix symlinks will convert
> the appexec to a symlink and silently drop the appexec data. Whether this is a
> significant issue depends on if most/all relevent store apps function the same
> when the executable is exec-ed directly vs via the appexec link.

I do have bad news for you: WSL symlinks are _already_ supported
(https://github.com/cygwin/cygwin/blob/d10d0d9b03f85/winsup/cygwin/path.cc#L2561-L2630),
and just like app execution aliases, they are not faithfully recreated.

Likewise junctions:
https://github.com/cygwin/cygwin/blob/d10d0d9b03f85/winsup/cygwin/path.cc#L2540-L2560

This suggests to me that the endeavor to have archive/copy programs based
on Cygwin's runtime work as you expect is doomed from the start.

> Another example: Much code exists in the field that intentionally detects
> symlinks, dereferences, and works directly on the target. This may not be an
> issue, if most/all relevent store apps function the same when the executable
> is exec-ed directly vs via the appexec link.

As far as I can tell, the only thing you _can_ do with an app execution
alias (apart from creating/deleting it) is to execute it. If you try to
read or write them, you get a "Permission denied".

Their intended use case seems to be the same as Debian Alternatives
(https://wiki.debian.org/DebianAlternatives) which _are_ implemented as
symbolic links.

So I still think that the best we can do with app execution aliases in
Cygwin is to display them as if they were plain old symbolic links.

Ciao,
Johannes

>
>
> Joe L.
>
>
>
> On 3/13/2021 4:21 PM, Johannes Schindelin wrote:
> > Hi Joe,
> >
> > On Fri, 12 Mar 2021, Joe Lowe wrote:
> >
> > > I am skeptical about this patch (part 1), interposing appexec reparse
> > > point
> > > data as symlinks for cygwin applications.
> > >
> > > The appexec reparse point data is essentially an extended attribute
> > > holding
> > > data that is used by CreateProcess(), more like a windows .lnk file or an
> > > X11
> > > .desktop file, not like a posix symlink. M$ just chose an unnecessarily
> > > obtuse
> > > way to store the files data. This reminds me of old Macintosh zero length
> > > font
> > > files.
> >
> > The obvious difference being that you cannot read those 0-length files.
> > And you _can_ determine the target from reading .lnk or .desktop files.
> >
> > > The useful function of the patch would seem to be as a way to display a
> > > portion of the data in shell directory listings for the user. I suggest
> > > this
> > > function is better provided by updated application code.
> >
> > I find your argument unconvincing.
> >
> > For all practical purposes, users are likely to want to treat app
> > execution aliases as if they were symbolic links.
> >
> > If users want to know more about the app execution alias than just the
> > path of the actual `.exe` (and that is a rather huge if), _then_ I would
> > buy your argument that it should be queried via application code.
> >
> > But for the common case of reading the corresponding `.exe` or accessing
> > the path? Why should we follow your suggestion and keep making it really
> > hard for users to get to that information? I really don't get it.
> >
> > Ciao,
> > Johannes
> >
> > >
> > >
> > > The patch part 2 seems entirely appropriate.
> > >
> > >
> > > Joe L.
> > >
> > >
> > > On 2021-03-12 07:11, Johannes Schindelin via Cygwin-patches wrote:
> > > > When the Windows Store version of Python is installed, so-called "app
> > > > execution aliases" are put into the `PATH`. These are reparse points
> > > > under the hood, with an undocumented format.
> > > >
> > > > We do know a bit about this format, though, as per the excellent
> > > > analysis:
> > > > https://www.tiraniddo.dev/2019/09/overview-of-windows-execution-aliases.html
> > > >
> > > >   The first 4 bytes is the reparse tag, in this case it's
> > > >   0x801B which is documented in the Windows SDK as
> > > >   IO_REPARSE_TAG_APPEXECLINK. Unfortunately there doesn't seem to
> > > >   be a corresponding structure, but with a bit of reverse
> > > >   engineering we can work out the format is as follows:
> > > >
> > > >   Version: <4 byte integer>
> > > >   Package ID: 
> > > >   Entry Point: 
> > > >   Executable: 
> > > >   Application Type: 
> > > >
> > > > Let's treat them as symbolic links. For example, in this developer's
> > > > setup, this will result in the following nice output:
> > > >
> > 

Re: [PATCH 1/2] Treat Windows Store's "app execution aliases" as symbolic links

2021-03-15 Thread Corinna Vinschen via Cygwin-patches
On Mar 13 19:41, Joe Lowe via Cygwin-patches wrote:
> Hi Johannes,
> 
> I agree on the usefulness to the user of showing appexec target executable
> as symlink target. But I am uncertain about the effect on code.
> 
> One example: Any app that is able to archive/copy posix symlinks will
> convert the appexec to a symlink and silently drop the appexec data. Whether
> this is a significant issue depends on if most/all relevent store apps
> function the same when the executable is exec-ed directly vs via the appexec
> link.

You won't get a sufficent, POSIX-like handling one way or the other.
Handling them as files will not allow correct archiving either, because
the reparse point data required to restore them correctly to work in
Windows won't be archived anyway.  There's only so much we can do in the
Windows environment.  ¯\_(ツ)_/¯

I'd just like to postpone this patch to get 3.2.0 out.  I'll add that
patch to the inevitable 3.2.1 release, given the massive testing of
3.2.0-0.1 on the Cygwin ML...


Thanks,
Corinna