diff options
-rw-r--r-- | e2fsprogs/e2fs_lib.c | 6 | ||||
-rw-r--r-- | e2fsprogs/lsattr.c | 1 | ||||
-rw-r--r-- | win32/mingw.c | 37 |
3 files changed, 43 insertions, 1 deletions
diff --git a/e2fsprogs/e2fs_lib.c b/e2fsprogs/e2fs_lib.c index 031f5e06b..4a4db1a13 100644 --- a/e2fsprogs/e2fs_lib.c +++ b/e2fsprogs/e2fs_lib.c | |||
@@ -135,6 +135,9 @@ void print_e2flags_long(struct stat *sb) | |||
135 | case IO_REPARSE_TAG_MOUNT_POINT: | 135 | case IO_REPARSE_TAG_MOUNT_POINT: |
136 | ln = "Junction"; | 136 | ln = "Junction"; |
137 | break; | 137 | break; |
138 | case IO_REPARSE_TAG_APPEXECLINK: | ||
139 | ln = "App_Exec_Link"; | ||
140 | break; | ||
138 | } | 141 | } |
139 | } | 142 | } |
140 | fputs(ln, stdout); | 143 | fputs(ln, stdout); |
@@ -174,6 +177,9 @@ void print_e2flags(struct stat *sb) | |||
174 | case IO_REPARSE_TAG_MOUNT_POINT: | 177 | case IO_REPARSE_TAG_MOUNT_POINT: |
175 | c = 'j'; | 178 | c = 'j'; |
176 | break; | 179 | break; |
180 | case IO_REPARSE_TAG_APPEXECLINK: | ||
181 | c = 'A'; | ||
182 | break; | ||
177 | } | 183 | } |
178 | } | 184 | } |
179 | #endif | 185 | #endif |
diff --git a/e2fsprogs/lsattr.c b/e2fsprogs/lsattr.c index a6c4a27e9..87fdb78b3 100644 --- a/e2fsprogs/lsattr.c +++ b/e2fsprogs/lsattr.c | |||
@@ -47,6 +47,7 @@ | |||
47 | //usage: "\n\nAttributes:\n" | 47 | //usage: "\n\nAttributes:\n" |
48 | //usage: "\n j Junction" | 48 | //usage: "\n j Junction" |
49 | //usage: "\n l Symbolic link" | 49 | //usage: "\n l Symbolic link" |
50 | //usage: "\n A App exec link" | ||
50 | //usage: "\n R Reparse point" | 51 | //usage: "\n R Reparse point" |
51 | //usage: "\n o Offline" | 52 | //usage: "\n o Offline" |
52 | //usage: "\n e Encrypted" | 53 | //usage: "\n e Encrypted" |
diff --git a/win32/mingw.c b/win32/mingw.c index 9e1cf5eea..be4fc7aa1 100644 --- a/win32/mingw.c +++ b/win32/mingw.c | |||
@@ -593,6 +593,7 @@ static DWORD get_symlink_data(DWORD attr, const char *pathname, | |||
593 | switch (fbuf->dwReserved0) { | 593 | switch (fbuf->dwReserved0) { |
594 | case IO_REPARSE_TAG_SYMLINK: | 594 | case IO_REPARSE_TAG_SYMLINK: |
595 | case IO_REPARSE_TAG_MOUNT_POINT: | 595 | case IO_REPARSE_TAG_MOUNT_POINT: |
596 | case IO_REPARSE_TAG_APPEXECLINK: | ||
596 | return fbuf->dwReserved0; | 597 | return fbuf->dwReserved0; |
597 | } | 598 | } |
598 | } | 599 | } |
@@ -1602,6 +1603,23 @@ static wchar_t *normalize_ntpath(wchar_t *wbuf) | |||
1602 | return wbuf; | 1603 | return wbuf; |
1603 | } | 1604 | } |
1604 | 1605 | ||
1606 | /* | ||
1607 | * This is the stucture required for reparse points with the tag | ||
1608 | * IO_REPARSE_TAG_APPEXECLINK. The Buffer member contains four | ||
1609 | * NUL-terminated, concatentated strings: | ||
1610 | * | ||
1611 | * package id, entry point, executable path and application type. | ||
1612 | * | ||
1613 | * https://www.tiraniddo.dev/2019/09/overview-of-windows-execution-aliases.html | ||
1614 | */ | ||
1615 | typedef struct { | ||
1616 | DWORD ReparseTag; | ||
1617 | USHORT ReparseDataLength; | ||
1618 | USHORT Reserved; | ||
1619 | ULONG Version; | ||
1620 | WCHAR Buffer[1]; | ||
1621 | } APPEXECLINK_BUFFER; | ||
1622 | |||
1605 | #define SRPB rptr->SymbolicLinkReparseBuffer | 1623 | #define SRPB rptr->SymbolicLinkReparseBuffer |
1606 | ssize_t readlink(const char *pathname, char *buf, size_t bufsiz) | 1624 | ssize_t readlink(const char *pathname, char *buf, size_t bufsiz) |
1607 | { | 1625 | { |
@@ -1613,9 +1631,11 @@ ssize_t readlink(const char *pathname, char *buf, size_t bufsiz) | |||
1613 | DWORD nbytes; | 1631 | DWORD nbytes; |
1614 | BYTE rbuf[MAXIMUM_REPARSE_DATA_BUFFER_SIZE]; | 1632 | BYTE rbuf[MAXIMUM_REPARSE_DATA_BUFFER_SIZE]; |
1615 | PREPARSE_DATA_BUFFER rptr = (PREPARSE_DATA_BUFFER)rbuf; | 1633 | PREPARSE_DATA_BUFFER rptr = (PREPARSE_DATA_BUFFER)rbuf; |
1634 | APPEXECLINK_BUFFER *aptr = (APPEXECLINK_BUFFER *)rptr; | ||
1616 | BOOL status; | 1635 | BOOL status; |
1617 | size_t len; | 1636 | size_t len; |
1618 | WCHAR *name = NULL; | 1637 | WCHAR *name = NULL, *str[4], *s; |
1638 | int i; | ||
1619 | 1639 | ||
1620 | status = DeviceIoControl(h, FSCTL_GET_REPARSE_POINT, NULL, 0, | 1640 | status = DeviceIoControl(h, FSCTL_GET_REPARSE_POINT, NULL, 0, |
1621 | rptr, sizeof(rbuf), &nbytes, NULL); | 1641 | rptr, sizeof(rbuf), &nbytes, NULL); |
@@ -1627,6 +1647,21 @@ ssize_t readlink(const char *pathname, char *buf, size_t bufsiz) | |||
1627 | } else if (status && rptr->ReparseTag == IO_REPARSE_TAG_MOUNT_POINT) { | 1647 | } else if (status && rptr->ReparseTag == IO_REPARSE_TAG_MOUNT_POINT) { |
1628 | len = MRPB.SubstituteNameLength/sizeof(WCHAR); | 1648 | len = MRPB.SubstituteNameLength/sizeof(WCHAR); |
1629 | name = MRPB.PathBuffer + MRPB.SubstituteNameOffset/sizeof(WCHAR); | 1649 | name = MRPB.PathBuffer + MRPB.SubstituteNameOffset/sizeof(WCHAR); |
1650 | } else if (status && rptr->ReparseTag == IO_REPARSE_TAG_APPEXECLINK) { | ||
1651 | // We only need the executable path but we determine all of | ||
1652 | // the strings as a sanity check. | ||
1653 | i = 0; | ||
1654 | s = aptr->Buffer; | ||
1655 | do { | ||
1656 | str[i] = s; | ||
1657 | while (*s++) | ||
1658 | ; | ||
1659 | } while (++i < 4); | ||
1660 | |||
1661 | if (s - aptr->Buffer < MAXIMUM_REPARSE_DATA_BUFFER_SIZE) { | ||
1662 | len = wcslen(str[2]); | ||
1663 | name = str[2]; | ||
1664 | } | ||
1630 | } | 1665 | } |
1631 | 1666 | ||
1632 | if (name) { | 1667 | if (name) { |