A Wine user has requested the ability to interact with Unix symlinks from Win32
code.
While the generic functionality of NT reparse points is still not implemented
upstream, it will probably involve a completely different code path than this,
so there does not seem to me to be any point in waiting for that to be done
before submitting these patches.
This does not implement all the relevant functionality. FILE_OPEN_REPARSE_POINT
is now respected, but returns an fd with no fd->unix_fd. Thus far only file
disposition (i.e. deletion), renaming and hardlinking are implemented, and all
other operations return the no_fd_status, for which
STATUS_REPARSE_POINT_NOT_RESOLVED is arbitrarily chosen.
This is probably going to be controversial. As controversial patches tend to get
deferred forever, I'm going to at least try to pose some questions related to
concept and implementation which may be easier to answer.
* Do we want to expose Unix symlinks at all? This was requested by a Wine user,
and it does seem a strong argument that Wine, in general, supports some
measure of integration with the host, including exposing custom interfaces for
programs written to take advantage of it.
We also, currently, already expose Unix *directory* symlinks via
NtQueryAttributesFile(). We don't currently expose such file symlinks (and
this series does not change that particular point, but it would be done by
follow-up patches). In a sense we are expanding existing partial support.
On the other hand, Unix symlinks which are completely opaque can be useful,
and some downstream distributions (CrossOver and Proton) currently rely on
them to reduce disk space usage while keeping the application unaware of a
symlink (even if it were to use FILE_OPEN_REPARSE_POINT. Not that any
applications are currently known that would break if this were to change, and
in any case they could simply revert these patches.)
* Implementation-wise, is having unix_fd == -1 a non-starter? This can be true
of other real fds in some specific cases...
* It's also true that this current implementation suffers from some degree of
TOCTOU problems: because we only store the name and not the FD anymore, the
actual underlying object at that path can change. This would not be true on
Windows. Is this a problem?
* One alternate approach would be to use O_PATH (Linux, FreeBSD) and
O_SYMLINK (Mac). I don't see any equivalent flag for NetBSD or Solaris, so
we would probably just not be able to expose this functionality there.
Note that while the documentation seems to imply that O_PATH only stores the
path, manual testing shows that (at least on Linux) a fd opened with O_PATH
will remain pointing at the same *inode* even if it is moved or deleted. So
this would avoid the aforementioned TOCTOU problem.
--
https://gitlab.winehq.org/wine/wine/-/merge_requests/8688
When running `SymInitializeW(GetCurrentProcess(), NULL, TRUE)` in a 32-bit EXE on 64-bit macOS, there are a number of syscall faults resulting from 64-bit pointers being truncated to 32 bits and then passed to `ReadProcessMemory()`. Fix these, mostly by widening variables to 64 bits.
--
v2: dbghelp: Don't try to load 64-bit ELF/Mach-O debug info in a Wow64 process.
https://gitlab.winehq.org/wine/wine/-/merge_requests/8962
Instead of https://gitlab.winehq.org/wine/wine/-/merge_requests/8869
I think this would be a much lighter and less complicated approach than trying to wake the window threads with internal messages. And it should be able to avoid spurious wake ups when there's no window surfaces involved.
What I'm not completely sure about is whether this is going to flush the surfaces frequently enough, and if we can assume the window thread will always either peek or wait for messages.
--
v2: win32u: Keep window surfaces in a per-thread linked list.
win32u: Remove window surface flush in expose_window_surface.
win32u: Remove window surface flush on lock / unlock.
win32u: Remove some less useful flush_window_surfaces.
win32u: Flush window surfaces while waiting for messages.
win32u: Use an absolute wait timeout in wait_message.
win32u: Remove unnecessary window_surface exports.
win32u: Dispatch NtUserUpdateLayeredWindow to the owner thread.
https://gitlab.winehq.org/wine/wine/-/merge_requests/8965
Every 33ms on toplevel windows with a non-dummy, non-offscreen window surface.
Making sure the window surfaces are flushed from their owner thread instead of any other thread that might draw to it and trigger an occasional flush. This removes the need for tracking window surfaces to additionally flush them in win32u.
It will make it easier to implement GL-based window surfaces for compositing, and simplify context management. Instead of one context per window, made current on the flushing thread we can have a single context on each thread owning a window that is used to flush them.
--
v2: win32u: Remove now unnecessary window surfaces list.
win32u: Flush window surfaces in process_wine_present.
server: Post a WINE_WM_PRESENT for window surface present.
win32u: Remove unnecessary window_surface exports.
https://gitlab.winehq.org/wine/wine/-/merge_requests/8869
Instead of https://gitlab.winehq.org/wine/wine/-/merge_requests/8869
I think this would be a much lighter and less complicated approach than trying to wake the window threads with internal messages. And it should be able to avoid spurious wake ups when there's no window surfaces involved.
What I'm not completely sure about is whether this is going to flush the surfaces frequently enough, and if we can assume the window thread will always either peek or wait for messages.
--
https://gitlab.winehq.org/wine/wine/-/merge_requests/8965