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
>       0x8000001B 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: <NUL Terminated Unicode String>
>       Entry Point: <NUL Terminated Unicode String>
>       Executable: <NUL Terminated Unicode String>
>       Application Type: <NUL Terminated Unicode String>

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

Reply via email to