From: Giang Nguyen <nen24t@gmail.com> GetFileAttributes() on a bound AF_UNIX socket file returns ERROR_INVALID_PARAMETER. The cause is in ntdll rather than in the server: NtQueryAttributesFile and NtQueryFullAttributesFile, and the FileBasic and FileStat paths of NtQueryInformationFile, reject anything that is neither S_ISREG nor S_ISDIR with STATUS_INVALID_INFO_CLASS, and a socket file is neither. get_file_info() now flags S_ISSOCK with FILE_ATTRIBUTE_REPARSE_POINT and IO_REPARSE_TAG_AF_UNIX, and the four guards accept S_ISSOCK. GetFileAttributes() then returns 0x420, FILE_ATTRIBUTE_REPARSE_POINT | FILE_ATTRIBUTE_ARCHIVE, which is what sock.c:14624 and sock.c:14703 expect. The change only admits cases that were rejected outright before, so it cannot regress a path that already worked. ws2_32:sock test_afunix: 32 failing assertions down to 24. Signed-off-by: Giang Nguyen <nen24t@gmail.com> --- dlls/ntdll/unix/file.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/dlls/ntdll/unix/file.c b/dlls/ntdll/unix/file.c index 7b15004bd9b..78eaea08258 100644 --- a/dlls/ntdll/unix/file.c +++ b/dlls/ntdll/unix/file.c @@ -1795,6 +1795,12 @@ static int get_file_info( const char *path, struct stat *st, ULONG *attr, ULONG if (reparse_tag) *reparse_tag = IO_REPARSE_TAG_LX_SYMLINK; } } + /* a bound AF_UNIX socket is a reparse point on Windows */ + else if (S_ISSOCK( st->st_mode )) + { + *attr |= FILE_ATTRIBUTE_REPARSE_POINT; + if (reparse_tag) *reparse_tag = IO_REPARSE_TAG_AF_UNIX; + } else if (S_ISDIR( st->st_mode ) && (parent_path = malloc( len + 4 ))) { struct stat parent_st; @@ -4899,7 +4905,7 @@ NTSTATUS WINAPI NtQueryFullAttributesFile( const OBJECT_ATTRIBUTES *attr, if (get_file_info( unix_name, &st, &attributes, NULL ) == -1) status = errno_to_status( errno ); - else if (!S_ISREG(st.st_mode) && !S_ISDIR(st.st_mode)) + else if (!S_ISREG(st.st_mode) && !S_ISDIR(st.st_mode) && !S_ISSOCK(st.st_mode)) status = STATUS_INVALID_INFO_CLASS; else fill_file_info( &st, attributes, info, FileNetworkOpenInformation ); @@ -4928,7 +4934,7 @@ NTSTATUS WINAPI NtQueryAttributesFile( const OBJECT_ATTRIBUTES *attr, FILE_BASIC if (get_file_info( unix_name, &st, &attributes, NULL ) == -1) status = errno_to_status( errno ); - else if (!S_ISREG(st.st_mode) && !S_ISDIR(st.st_mode)) + else if (!S_ISREG(st.st_mode) && !S_ISDIR(st.st_mode) && !S_ISSOCK(st.st_mode)) status = STATUS_INVALID_INFO_CLASS; else status = fill_file_info( &st, attributes, info, FileBasicInformation ); @@ -5058,7 +5064,7 @@ NTSTATUS WINAPI NtQueryInformationFile( HANDLE handle, IO_STATUS_BLOCK *io, case FileBasicInformation: if (fd_get_file_info( handle, fd, options, &st, &attr, NULL ) == -1) status = errno_to_status( errno ); - else if (!S_ISREG(st.st_mode) && !S_ISDIR(st.st_mode)) + else if (!S_ISREG(st.st_mode) && !S_ISDIR(st.st_mode) && !S_ISSOCK(st.st_mode)) status = STATUS_INVALID_INFO_CLASS; else fill_file_info( &st, attr, ptr, class ); @@ -5165,7 +5171,7 @@ NTSTATUS WINAPI NtQueryInformationFile( HANDLE handle, IO_STATUS_BLOCK *io, case FileStatInformation: if (fd_get_file_info( handle, fd, options, &st, &attr, &reparse_tag ) == -1) status = errno_to_status( errno ); - else if (!S_ISREG(st.st_mode) && !S_ISDIR(st.st_mode)) + else if (!S_ISREG(st.st_mode) && !S_ISDIR(st.st_mode) && !S_ISSOCK(st.st_mode)) status = STATUS_INVALID_INFO_CLASS; else { -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/7650