[Bug 59738] New: GetFinalPathNameByHandleW returns unresolved symbolic link path instead of final resolved path
http://bugs.winehq.org/show_bug.cgi?id=59738 Bug ID: 59738 Summary: GetFinalPathNameByHandleW returns unresolved symbolic link path instead of final resolved path Product: Wine Version: 11.0 Hardware: x86-64 OS: Linux Status: UNCONFIRMED Severity: normal Priority: P2 Component: -unknown Assignee: wine-bugs@list.winehq.org Reporter: rikul@inbox.ru Distribution: --- Created attachment 80903 --> http://bugs.winehq.org/attachment.cgi?id=80903 The archive contains a minimal reproducer and a prebuilt executable demonstrating the issue. According to Microsoft documentation, GetFinalPathNameByHandleW() is expected to return the fully resolved final path for the object referenced by the handle. The documentation explicitly states: “A final path is the path that is returned when a path is fully resolved. For example, for a symbolic link named C:\tmp\mydir that points to D:\yourdir, the final path would be D:\yourdir.” Wine currently returns the original unresolved path containing the symbolic link component instead of the resolved target path. This differs from native Windows behavior and breaks applications relying on canonical filesystem paths. The issue also affects std::filesystem::weakly_canonical, which internally depends on GetFinalPathNameByHandleW. Steps to reproduce ------------------ Create a symbolic link: 1. touch /tmp/real.txt 2. ln -s /tmp/real.txt /tmp/link.txt 3. wine symlink_test.exe /tmp/link.txt. The program opens link.txt and calls GetFinalPathNameByHandleW() on the handle. Expected behavior ------------------ Input path: /tmp/link.txt GetFinalPathNameByHandleW result: \\?\Z:\tmp\real.txt std::filesystem::weakly_canonical result: Z:\tmp\real.txt The returned path is fully resolved and does not contain the symbolic link component. Actual behavior --------------- Input path: /tmp/link.txt GetFinalPathNameByHandleW result: \\?\Z:\tmp\link.txt std::filesystem::weakly_canonical result: Z:\tmp\link.txt Wine returns the unresolved original path used to open the handle. Regression information ---------------------- A git bisect identifies the following commit as the first bad commit: https://gitlab.winehq.org/wine/wine/-/commit/af35741d3681f21222a85900b54d95e... Before this commit, GetFinalPathNameByHandleW() returned the resolved canonical path correctly. Tested on Wine 11.0 -- Do not reply to this email, post in Bugzilla using the above URL to reply. You are receiving this mail because: You are watching all bug changes.
http://bugs.winehq.org/show_bug.cgi?id=59738 BugSeeker <rikul@inbox.ru> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |l@laa.am -- Do not reply to this email, post in Bugzilla using the above URL to reply. You are receiving this mail because: You are watching all bug changes.
http://bugs.winehq.org/show_bug.cgi?id=59738 BugSeeker <rikul@inbox.ru> changed: What |Removed |Added ---------------------------------------------------------------------------- Regression SHA1| |af35741d3681f21222a85900b54 | |d95ee422fe074 Component|-unknown |inkobj -- Do not reply to this email, post in Bugzilla using the above URL to reply. You are receiving this mail because: You are watching all bug changes.
http://bugs.winehq.org/show_bug.cgi?id=59738 BugSeeker <rikul@inbox.ru> changed: What |Removed |Added ---------------------------------------------------------------------------- Component|inkobj |-unknown -- Do not reply to this email, post in Bugzilla using the above URL to reply. You are receiving this mail because: You are watching all bug changes.
http://bugs.winehq.org/show_bug.cgi?id=59738 Zeb Figura <z.figura12@gmail.com> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |z.figura12@gmail.com --- Comment #1 from Zeb Figura <z.figura12@gmail.com> --- What exactly depends on this? Windows applications can't depend on Unix symlinks being resolved... -- Do not reply to this email, post in Bugzilla using the above URL to reply. You are receiving this mail because: You are watching all bug changes.
http://bugs.winehq.org/show_bug.cgi?id=59738 --- Comment #2 from BugSeeker <rikul@inbox.ru> --- I understand that Unix symlinks themselves are not guaranteed to exist on Windows, and applications cannot generally rely on Unix-specific filesystem behavior. However, the issue here is about GetFinalPathNameByHandleW() behavior on Wine versus Windows. On native Windows, when opening a file via a symbolic link, GetFinalPathNameByHandleW() returns the fully resolved final path — i.e., the target of the symlink — not the original path containing the link. I have verified this on Windows, and the results confirm that the path returned points to the target, not the symlink itself. This is what applications like std::filesystem::weakly_canonical rely on: the resolved, canonical path of the file handle. So this is not about Unix symlink semantics per se, but about matching Windows API behavior, which Wine aims to emulate. Windows test result: ------------------- mklink C:\workarea\link.txt C:\workarea\real.txt symlink_test.exe c:\workarea\link.txt Input path: c:\workarea\link.txt GetFinalPathNameByHandleW result: \\?\C:\workarea\real.txt std::filesystem::weakly_canonical result: C:\workarea\real.txt -- Do not reply to this email, post in Bugzilla using the above URL to reply. You are receiving this mail because: You are watching all bug changes.
http://bugs.winehq.org/show_bug.cgi?id=59738 --- Comment #3 from Hans Leidekker <hans@meelstraat.net> --- (In reply to BugSeeker from comment #2)
So this is not about Unix symlink semantics per se, but about matching Windows API behavior, which Wine aims to emulate.
Wine emulates Windows symlinks but not with Unix symlinks. -- Do not reply to this email, post in Bugzilla using the above URL to reply. You are receiving this mail because: You are watching all bug changes.
http://bugs.winehq.org/show_bug.cgi?id=59738 --- Comment #4 from BugSeeker <rikul@inbox.ru> --- I understand the distinction you’re making. Even so, I don’t think ignoring Unix symlinks here is the right trade-off: on Linux, the actual filesystem people run Wine against is dominated by Unix symlinks, not whatever Wine maps as Windows symlinks. Callers of GetFinalPathNameByHandleW therefore reasonably expect full resolution of the path that produced the handle — including those Unix symlinks — so the result matches Windows-style “final path” semantics. -- Do not reply to this email, post in Bugzilla using the above URL to reply. You are receiving this mail because: You are watching all bug changes.
http://bugs.winehq.org/show_bug.cgi?id=59738 --- Comment #5 from Hans Leidekker <hans@meelstraat.net> --- (In reply to BugSeeker from comment #4)
I understand the distinction you’re making. Even so, I don’t think ignoring Unix symlinks here is the right trade-off: on Linux, the actual filesystem people run Wine against is dominated by Unix symlinks, not whatever Wine maps as Windows symlinks. Callers of GetFinalPathNameByHandleW therefore reasonably expect full resolution of the path that produced the handle — including those Unix symlinks — so the result matches Windows-style “final path” semantics.
Invisible Unix symlinks can be a useful feature. It means you can use them where Windows apps don't expect symlinks. -- Do not reply to this email, post in Bugzilla using the above URL to reply. You are receiving this mail because: You are watching all bug changes.
http://bugs.winehq.org/show_bug.cgi?id=59738 --- Comment #6 from BugSeeker <rikul@inbox.ru> --- Yes — in that situation invisible Unix symlinks are useful, but I still don’t think that should alter how GetFinalPathNameByHandleW behaves: callers use it precisely to get a fully resolved path, and that expectation should be honoured. -- Do not reply to this email, post in Bugzilla using the above URL to reply. You are receiving this mail because: You are watching all bug changes.
http://bugs.winehq.org/show_bug.cgi?id=59738 --- Comment #7 from Hans Leidekker <hans@meelstraat.net> --- (In reply to BugSeeker from comment #6)
Yes — in that situation invisible Unix symlinks are useful, but I still don’t think that should alter how GetFinalPathNameByHandleW behaves: callers use it precisely to get a fully resolved path, and that expectation should be honoured.
Windows apps don't expect that because they have no notion of Unix symlinks. Humans may expect that but resolving to a Unix symlink means fully resolved from the perspective of the Windows app. Also note that if you treat Unix symlinks as a type of Windows symlinks then it needs to be done consistently, not only in GetFinalPathNameByHandleW(). -- Do not reply to this email, post in Bugzilla using the above URL to reply. You are receiving this mail because: You are watching all bug changes.
http://bugs.winehq.org/show_bug.cgi?id=59738 --- Comment #8 from Zeb Figura <z.figura12@gmail.com> --- Making the NT path match the resolved Unix path is not exactly easy. The documentation says that symlinks are resolved, and they are, but obviously it's not talking about Unix symlinks, only NT symlinks. It's not even clear that there's a good reason for Unix symlinks to be resolved. Can you provide one other than extrapolation of existing rules? -- Do not reply to this email, post in Bugzilla using the above URL to reply. You are receiving this mail because: You are watching all bug changes.
participants (1)
-
WineHQ Bugzilla