Hans Leidekker : ws2_32: Implement the SIO_ADDRESS_LIST_QUERY ioctl.

Alexandre Julliard julliard at wine.codeweavers.com
Tue Dec 19 10:04:54 CST 2006


Module: wine
Branch: master
Commit: 84f0a03556f81d47b5aa65b50f6aa5c8b502e82b
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=84f0a03556f81d47b5aa65b50f6aa5c8b502e82b

Author: Hans Leidekker <hans at it.vu.nl>
Date:   Mon Dec 18 19:37:52 2006 +0100

ws2_32: Implement the SIO_ADDRESS_LIST_QUERY ioctl.

---

 dlls/ws2_32/socket.c |   73 ++++++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 71 insertions(+), 2 deletions(-)

diff --git a/dlls/ws2_32/socket.c b/dlls/ws2_32/socket.c
index 99f46bc..76e60cc 100644
--- a/dlls/ws2_32/socket.c
+++ b/dlls/ws2_32/socket.c
@@ -2389,9 +2389,78 @@ INT WINAPI WSAIoctl(SOCKET s,
        break;
 
    case WS_SIO_ADDRESS_LIST_QUERY:
-        FIXME("-> SIO_ADDRESS_LIST_QUERY request: stub\n");
-        break;
+   {
+        DWORD size;
+
+        TRACE("-> SIO_ADDRESS_LIST_QUERY request\n");
+
+        if (!lpcbBytesReturned)
+        {
+            WSASetLastError(WSAEFAULT);
+            return SOCKET_ERROR;
+        }
+
+        if (GetAdaptersInfo(NULL, &size) == ERROR_BUFFER_OVERFLOW)
+        {
+            IP_ADAPTER_INFO *p, *table = HeapAlloc(GetProcessHeap(), 0, size);
+            DWORD need, num;
+
+            if (!table || GetAdaptersInfo(table, &size))
+            {
+                HeapFree(GetProcessHeap(), 0, table);
+                WSASetLastError(WSAEINVAL);
+                return SOCKET_ERROR;
+            }
+
+            for (p = table, num = 0; p; p = p->Next)
+                if (p->IpAddressList.IpAddress.String[0]) num++;
+
+            need = sizeof(SOCKET_ADDRESS_LIST) + sizeof(SOCKET_ADDRESS) * (num - 1);
+            need += sizeof(SOCKADDR) * num;
+            *lpcbBytesReturned = need;
+
+            if (need > cbOutBuffer)
+            {
+                HeapFree(GetProcessHeap(), 0, table);
+                WSASetLastError(WSAEFAULT);
+                return SOCKET_ERROR;
+            }
+
+            if (lpbOutBuffer)
+            {
+                unsigned int i;
+                SOCKET_ADDRESS *sa;
+                SOCKET_ADDRESS_LIST *sa_list = (SOCKET_ADDRESS_LIST *)lpbOutBuffer;
+                SOCKADDR_IN *sockaddr;
+
+                sa = sa_list->Address;
+                sockaddr = (SOCKADDR_IN *)((char *)sa + num * sizeof(SOCKET_ADDRESS));
+                sa_list->iAddressCount = num;
+
+                for (p = table, i = 0; p; p = p->Next)
+                {
+                    if (!p->IpAddressList.IpAddress.String[0]) continue;
+
+                    sa[i].lpSockaddr = (SOCKADDR *)&sockaddr[i];
+                    sa[i].iSockaddrLength = sizeof(SOCKADDR);
+
+                    sockaddr[i].sin_family = AF_INET;
+                    sockaddr[i].sin_port = 0;
+                    sockaddr[i].sin_addr.WS_s_addr = inet_addr(p->IpAddressList.IpAddress.String);
+                    i++;
+                }
+            }
 
+            HeapFree(GetProcessHeap(), 0, table);
+            return 0;
+        }
+        else
+        {
+            WARN("unable to get IP address list\n");
+            WSASetLastError(WSAEINVAL);
+            return SOCKET_ERROR;
+        }
+   }
    case WS_SIO_FLUSH:
 	FIXME("SIO_FLUSH: stub.\n");
 	break;




More information about the wine-cvs mailing list