https://bugs.winehq.org/show_bug.cgi?id=51059
--- Comment #2 from Jinoh Kang jinoh.kang.kr@gmail.com --- (In reply to Erich E. Hoover from comment #1)
You are correct that O_SYMLINK is not identical to (O_NOFOLLOW | O_PATH), but I did some testing of this some time ago and the differences don't really matter for implementing FILE_OPEN_REPARSE_POINT.
What you get currently in wine-staging, as you have discovered, is an error on read/write/etc. where the real behavior is that these succeed but do nothing (return no bytes, size 0, etc.).
Or Is it so? I actually based my claim of this behavior being a bug based on Microsoft Docs on CreateFileW:
*FILE_FLAG_OPEN_REPARSE_POINT* 0x00200000
Normal reparse point processing will not occur; CreateFile will attempt to open the reparse point. When a file is opened, a file handle is returned, whether or not the filter that controls the reparse point is operational.
This flag cannot be used with the CREATE_ALWAYS flag.
If the file is not a reparse point, then this flag is ignored.
I acknowledge the docs (or MSDN) hasn't exactly been known for its accuracy on "internal" matters, though. Also there's no guarantee that the Win32 API won't do some other magic for that flag before passing it as FILE_OPEN_REPARSE_POINT to NtCreateFile. Might test about this later.
I have not gone to the trouble of implementing this because Windows applications don't expect this to "work".
However, you have stumbled across something _very_ interesting here in that it appears that cygwin opens the file and then "changes" it when converting it to a unix handle: https://cygwin.com/git/?p=cygwin-apps/setup.git;a=blob;f=filemanip.cc; h=48f5117f6e4c8a2f3bd13bc4c3c22ac418634ede;hb=HEAD#l469
I see it was the setup part. I couldn't debug it myself ATM since the debugger for some reason tripped into assertion failure while parsing DWARF2 debugging symbols.
I noticed my transcription error on the trace (my apologies), so the first part of the trace actually goes:
CreateFileW ("XXXX.tar.xz") [1] NtCreateFile ("XXXX.tar.xz", w/o FILE_OPEN_REPARSE_POINT) [1] CreateFileW return [1] NtQueryInformationFile *FileStandardInformation* [1] (server)close_handle [1]
Now that it's known that the setup calls into NTDLL directly, I suppose this part was simply a pre-flight query to fetch the file existence or size.
NtCreateFile ("XXXX.tar.xz", w/ FILE_OPEN_REPARSE_POINT) [2] NtReadFile [2] -> STATUS_INVALID_HANDLE
So this one is from io_stream ctor -> nt_wfopen. I don't think _open_osfhandle should be doing anything on the handle, but this is a speculation.
I'll need to put together a test case, but I suspect that _open_osfhandle actually opens a new handle that doesn't have FILE_OPEN_REPARSE_POINT set. I can probably get to that next weekend.