https://bugs.winehq.org/show_bug.cgi?id=53093
--- Comment #7 from Erich E. Hoover erich.e.hoover@gmail.com --- Hello everyone, sorry it's taken so long to get this done. This bug should be fixed by the latest commit to wine-staging (1ed196f0effa262b297705f36975261f44001417).
I apologize for the delay. This update ended up taking a lot more time than I expected, since the changes AJ requested ended up being more work than I had originally anticipated. However, in the end, I think that the patches are much cleaner and there is now a _much_ higher chance that this will get included into main Wine (after some testing, of course).
Summary of Changes: This is a complete rewrite of the underlying set/get reparse point behavior. Reparse point data is now encoded in the symlink target as a relative path composed of these components (slash separated): 1) .REPARSE_POINT 2) the filename of the symlink (to avoid collisions) 3) a flag to indicate whether the reparse point is a file (/) or directory (./) 4) the full reparse point buffer (base64url encoded) split into 255 byte slash-separated chunks (up to a total of 4095 bytes for all of the components of the symlink target) 5) a continuation id (0, 1, ...) for the next component (if the reparse point data is so large that it requires an additional file)
Additional (continuation) symlinks are composed of: 1) "../" (go to parent) however many times are needed to walk back up to the filename folder 2) the rest of the base64url-encoded reparse data (as much as will fit in the 4095 byte symlink target limit) 3) the next continuation id (to ensure that path collisions are impossible if there's a lot of identical data in the reparse buffer)
The final "continuation" symlink goes the target destination (if it's one of the reparse point types we understand, otherwise it's just a dangling symlink). If it's a relative symlink then it walks back up to the folder with the original symlink and appends the target from there, if it's an absolute symlink then it just goes straight to the target (absolute targets within the prefix use a special intermediary "${WINEPREFIX}" symlink to make it easy to fix the Unix symlink if a prefix gets moved to a new location). This symlink is not _necessary_ for the patches to work, but if it exists then it makes resolving the symlinks faster (with the added bonus of allowing the reparse point to work outside of Wine).
Now that we've had about 10 years to get the bugs and eccentricities of reparse points figured out, I'm hopeful that we can finally get this updated reparse point support integrated into vanilla Wine. In anticipation of that, I'm already looking at implementing the Single-Instance Store (SIS) reparse point so that we can use that feature to de-duplicate all the Wine DLLs that we currently copy into the prefix. All of this is a very long way of saying "a lot hash changed, please test this and report back with any problems".