[PATCH 5/5] ws2_32: Move the getpeername() implementation to ntdll.

Zebediah Figura z.figura12 at gmail.com
Wed Jun 16 23:33:12 CDT 2021


This adds todo_wine to a couple of tests; however, these are overly zealous
invalid parameter tests, and fixing them is nontrivial.

Signed-off-by: Zebediah Figura <z.figura12 at gmail.com>
---
 dlls/ntdll/unix/socket.c | 26 ++++++++++++++++++++
 dlls/ws2_32/socket.c     | 51 +++++++++++++++++-----------------------
 dlls/ws2_32/tests/sock.c |  4 ++--
 include/wine/afd.h       |  1 +
 4 files changed, 51 insertions(+), 31 deletions(-)

diff --git a/dlls/ntdll/unix/socket.c b/dlls/ntdll/unix/socket.c
index 02700d37d6a..04db120dcbd 100644
--- a/dlls/ntdll/unix/socket.c
+++ b/dlls/ntdll/unix/socket.c
@@ -1540,6 +1540,32 @@ NTSTATUS sock_ioctl( HANDLE handle, HANDLE event, PIO_APC_ROUTINE apc, void *apc
             break;
         }
 
+        case IOCTL_AFD_WINE_GETPEERNAME:
+        {
+            union unix_sockaddr unix_addr;
+            socklen_t unix_len = sizeof(unix_addr);
+            int len;
+
+            if ((status = server_get_unix_fd( handle, 0, &fd, &needs_close, NULL, NULL )))
+                return status;
+
+            if (getpeername( fd, &unix_addr.addr, &unix_len ) < 0)
+            {
+                status = sock_errno_to_status( errno );
+                break;
+            }
+
+            len = sockaddr_from_unix( &unix_addr, out_buffer, out_size );
+            if (out_size < len)
+            {
+                status = STATUS_BUFFER_TOO_SMALL;
+                break;
+            }
+            io->Information = len;
+            status = STATUS_SUCCESS;
+            break;
+        }
+
         default:
         {
             if ((code >> 16) == FILE_DEVICE_NETWORK)
diff --git a/dlls/ws2_32/socket.c b/dlls/ws2_32/socket.c
index 1a484da1527..a4d89e728b8 100644
--- a/dlls/ws2_32/socket.c
+++ b/dlls/ws2_32/socket.c
@@ -2077,42 +2077,35 @@ static BOOL WINAPI WS2_DisconnectEx( SOCKET s, OVERLAPPED *overlapped, DWORD fla
     return !status;
 }
 
+
 /***********************************************************************
- *		getpeername		(WS2_32.5)
+ *      getpeername   (ws2_32.5)
  */
-int WINAPI WS_getpeername(SOCKET s, struct WS_sockaddr *name, int *namelen)
+int WINAPI WS_getpeername( SOCKET s, struct WS_sockaddr *addr, int *len )
 {
-    int fd;
-    int res;
+    IO_STATUS_BLOCK io;
+    NTSTATUS status;
 
-    TRACE("socket %04lx, ptr %p, len %08x\n", s, name, namelen ? *namelen : 0);
+    TRACE( "socket %#lx, addr %p, len %d\n", s, addr, len ? *len : 0 );
 
-    fd = get_sock_fd( s, 0, NULL );
-    res = SOCKET_ERROR;
-
-    if (fd != -1)
+    if (!socket_list_find( s ))
     {
-        union generic_unix_sockaddr uaddr;
-        socklen_t uaddrlen = sizeof(uaddr);
-
-        if (getpeername(fd, &uaddr.addr, &uaddrlen) == 0)
-        {
-            if (!name || !namelen)
-                SetLastError(WSAEFAULT);
-            else if (ws_sockaddr_u2ws(&uaddr.addr, name, namelen) != 0)
-                /* The buffer was too small */
-                SetLastError(WSAEFAULT);
-            else
-            {
-                res = 0;
-                TRACE("=> %s\n", debugstr_sockaddr(name));
-            }
-        }
-        else
-            SetLastError(wsaErrno());
-        release_sock_fd( s, fd );
+        WSASetLastError( WSAENOTSOCK );
+        return -1;
     }
-    return res;
+
+    if (!len)
+    {
+        SetLastError( WSAEFAULT );
+        return -1;
+    }
+
+    status = NtDeviceIoControlFile( (HANDLE)s, NULL, NULL, NULL, &io,
+                                    IOCTL_AFD_WINE_GETPEERNAME, NULL, 0, addr, *len );
+    if (!status)
+        *len = io.Information;
+    SetLastError( NtStatusToWSAError( status ) );
+    return status ? -1 : 0;
 }
 
 
diff --git a/dlls/ws2_32/tests/sock.c b/dlls/ws2_32/tests/sock.c
index 3e6461ad994..f67bc4efae5 100644
--- a/dlls/ws2_32/tests/sock.c
+++ b/dlls/ws2_32/tests/sock.c
@@ -7752,7 +7752,7 @@ static void test_getpeername(void)
 
     ret = getpeername(sock, NULL, NULL);
     ok(ret == SOCKET_ERROR, "Expected getpeername to return SOCKET_ERROR, got %d\n", ret);
-    ok(WSAGetLastError() == WSAENOTCONN,
+    todo_wine ok(WSAGetLastError() == WSAENOTCONN,
        "Expected WSAGetLastError() to return WSAENOTCONN, got %d\n", WSAGetLastError());
 
     memset(&sa, 0, sizeof(sa));
@@ -7767,7 +7767,7 @@ static void test_getpeername(void)
 
     ret = getpeername(sock, NULL, NULL);
     ok(ret == SOCKET_ERROR, "Expected getpeername to return SOCKET_ERROR, got %d\n", ret);
-    ok(WSAGetLastError() == WSAENOTCONN,
+    todo_wine ok(WSAGetLastError() == WSAENOTCONN,
        "Expected WSAGetLastError() to return WSAENOTCONN, got %d\n", WSAGetLastError());
 
     ret = connect(sock, (struct sockaddr*)&sa, sizeof(sa));
diff --git a/include/wine/afd.h b/include/wine/afd.h
index 19c1e064aaf..ad8e3abf5ba 100644
--- a/include/wine/afd.h
+++ b/include/wine/afd.h
@@ -156,6 +156,7 @@ struct afd_get_events_params
 #define IOCTL_AFD_WINE_GET_INTERFACE_LIST   CTL_CODE(FILE_DEVICE_NETWORK, 213, METHOD_BUFFERED, FILE_ANY_ACCESS)
 #define IOCTL_AFD_WINE_KEEPALIVE_VALS       CTL_CODE(FILE_DEVICE_NETWORK, 214, METHOD_BUFFERED, FILE_ANY_ACCESS)
 #define IOCTL_AFD_WINE_MESSAGE_SELECT       CTL_CODE(FILE_DEVICE_NETWORK, 215, METHOD_BUFFERED, FILE_ANY_ACCESS)
+#define IOCTL_AFD_WINE_GETPEERNAME          CTL_CODE(FILE_DEVICE_NETWORK, 216, METHOD_BUFFERED, FILE_ANY_ACCESS)
 
 struct afd_create_params
 {
-- 
2.30.2




More information about the wine-devel mailing list