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