[Bug 59922] New: CreateSymbolicLinkW misbehaves for directory symlink
http://bugs.winehq.org/show_bug.cgi?id=59922 Bug ID: 59922 Summary: CreateSymbolicLinkW misbehaves for directory symlink 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: winehq@kayari.org Distribution: --- Created attachment 81254 --> http://bugs.winehq.org/attachment.cgi?id=81254 gzipped output of WINEDEBUG=+file,+ntdll,+relay wine repro.exe #define UNICODE #define _UNICODE #include <windows.h> #include <stdio.h> static void check(BOOL ok, const char* what) { if (!ok) printf("%s failed: %lu\n", what, GetLastError()); } int main(void) { RemoveDirectoryW(L"test\\foo\\baz"); RemoveDirectoryW(L"test\\foo"); RemoveDirectoryW(L"test\\baz"); RemoveDirectoryW(L"test"); check(CreateDirectoryW(L"test", NULL), "CreateDirectory(test)"); check(CreateDirectoryW(L"test\\foo", NULL), "CreateDirectory(foo)"); check(CreateDirectoryW(L"test\\baz", NULL), "CreateDirectory(baz)"); BOOL ok = CreateSymbolicLinkW( L"test\\foo\\baz", L"..\\baz", SYMBOLIC_LINK_FLAG_DIRECTORY); printf("CreateSymbolicLinkW returned %d\n", ok); printf("GetLastError() = %lu\n", GetLastError()); DWORD attrs = GetFileAttributesW(L"test\\foo\\baz"); if (attrs == INVALID_FILE_ATTRIBUTES) printf("GetFileAttributes failed: %lu\n", GetLastError()); else printf("Attributes: 0x%08lx\n", attrs); return 0; } I compile this with x86_64-w64-mingw32-gcc (from the Fedora 43 repos, or a self-built cross-compiler from GCC git master) and then run it using Fedora's wine-11.0-2.fc43.x86_64 package: $ x86_64-w64-mingw32-gcc test.c -o repro.exe $ rm -rf test $ wine repro.exe 2>/dev/null CreateSymbolicLinkW returned 1 GetLastError() = 0 Attributes: 0x00000410 $ ls -l test/* test/baz: total 0 test/foo: total 0 drwxr-xr-x. 2 jwakely jwakely 40 Jun 26 19:01 'baz?' Observe that CreateSymbolicLinkW returns successfully, and the attributes of the new symlink can be read, but in fact it did not create "test/foo/baz" as a symlink to "../baz". Instead it created "test/foo/baz?" as a directory. If I re-run with WINEDEBUG settings: $ rm -r test $ WINEDEBUG=+file,+ntdll,+relay wine repro.exe 2>&1 | grep -E "symlink|mkdir|baz" I see the correct arguments passed to the CreateSymbolicLinkW function: 0024:Call KERNEL32.CreateSymbolicLinkW(14000a010 L"test\\foo\\baz",14000a098 L"..\\baz",00000001) ret=140001581 But the very last line shows the wrong path: 0024:trace:file:get_nt_and_unix_names L"\\??\\Z:\\tmp\\test\\foo\\baz" -> ret 0 nt L"\\??\\Z:\\tmp\\test\\foo\\baz" unix "/home/jwakely/.wine/dosdevices/z:/tmp/test/foo/baz?" Running the same executable on Windows 11 behaves correctly. It prints the same output, but the file that is created is a real symlink, not a directory with '?' appended. I've attached the complete output of `WINEDEBUG=+file,+ntdll,+relay wine repro.exe` (not just the grepped parts). -- 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=59922 Ken Sharp <imwellcushtymelike@gmail.com> changed: What |Removed |Added ---------------------------------------------------------------------------- Keywords| |download, source --- Comment #1 from Ken Sharp <imwellcushtymelike@gmail.com> --- Have you tried the latest release? -- 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=59922 Jonathan Wakely <winehq@kayari.org> changed: What |Removed |Added ---------------------------------------------------------------------------- Version|11.0 |11.11 --- Comment #2 from Jonathan Wakely <winehq@kayari.org> --- I've tried wine-staging 11.11 from the https://dl.winehq.org/wine-builds/fedora/44/winehq.repo repo and it has the same behaviour. -- 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=59922 Ken Sharp <imwellcushtymelike@gmail.com> changed: What |Removed |Added ---------------------------------------------------------------------------- Version|11.11 |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=59922 Zeb Figura <z.figura12@gmail.com> changed: What |Removed |Added ---------------------------------------------------------------------------- Resolution|--- |WONTFIX Status|UNCONFIRMED |RESOLVED CC| |z.figura12@gmail.com --- Comment #3 from Zeb Figura <z.figura12@gmail.com> --- This is intentional. Unix symlinks are not capable of expressing all of the behaviour of NT reparse points; we need to use a special Wine-specific scheme. If you want to create a Unix symlink, don't use CreateSymbolicLink(). -- 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=59922 --- Comment #4 from Jonathan Wakely <winehq@kayari.org> --- Aha, thanks! The original code where this was observed was in an implementation of std::filesystem::create_directory_symlink for libstdc++. My hacky support for mingw-w64 (which I test using Wine) uses a mixture of POSIX system calls and Win32 APIs, which seems to be the problem. A directory symlink created with CreateSymbolicLinkW works OK with other Win32 functions, but doesn't play well with POSIX calls that try to work with the symlink. I think what this means is that our std::filesystem implementation should use Win32 APIs consistently, and not mix calls like _opendir with Win32 APIs like CreateSymbolicLinkW. That would probably be more work than I'm willing to put in for Windows support, so I might just report a GCC bug and leave it open until somebody else is motivated to redo all the Windows support in std::filesystem. Or just document that our std::filesystem::create_directory_symlink has some limitations. Thanks again for the quick response. -- 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=59922 --- Comment #5 from Zeb Figura <z.figura12@gmail.com> --- (In reply to Jonathan Wakely from comment #4)
Aha, thanks!
The original code where this was observed was in an implementation of std::filesystem::create_directory_symlink for libstdc++. My hacky support for mingw-w64 (which I test using Wine) uses a mixture of POSIX system calls and Win32 APIs, which seems to be the problem. A directory symlink created with CreateSymbolicLinkW works OK with other Win32 functions, but doesn't play well with POSIX calls that try to work with the symlink.
Is this all mingw-w64? You say "POSIX", but presumably that means it's CRT functions that are still essentially running win32 code. How do they work on Windows? Windows doesn't have POSIX symlinks. If there's a difference in behaviour between Wine and Windows with the same mingw implementation, such as msvcrt/ucrtbase functions not behaving the right way, that's still probably a bug. -- 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