[WS2_32]
authorThomas Faber <thomas.faber@reactos.org>
Sat, 7 Nov 2015 09:38:13 +0000 (09:38 +0000)
committerThomas Faber <thomas.faber@reactos.org>
Sat, 7 Nov 2015 09:38:13 +0000 (09:38 +0000)
- Handle SO_PROTOCOL_INFOA in getsockopt based on ws2_32_new.
CORE-10440

svn path=/trunk/; revision=69826

reactos/dll/win32/ws2_32/CMakeLists.txt
reactos/dll/win32/ws2_32/include/ws2_32.h
reactos/dll/win32/ws2_32/misc/stubs.c

index 6015ff0..fecd5b8 100644 (file)
@@ -25,7 +25,7 @@ add_library(ws2_32 SHARED
     ${CMAKE_CURRENT_BINARY_DIR}/ws2_32.def)
 
 set_module_type(ws2_32 win32dll UNICODE)
-target_link_libraries(ws2_32 wine)
+target_link_libraries(ws2_32 wine ${PSEH_LIB})
 add_delay_importlibs(ws2_32 user32)
 add_importlibs(ws2_32 advapi32 dnsapi ws2help msvcrt kernel32 ntdll)
 add_pch(ws2_32 include/ws2_32.h SOURCE)
index 8ecf358..fbd894a 100644 (file)
 
 #include <windef.h>
 #include <winbase.h>
+#include <winnls.h>
 #include <winuser.h>
 #include <ws2spi.h>
 #define NTOS_MODE_USER
 #include <ndk/rtlfuncs.h>
+#include <pseh/pseh2.h>
 
 #include <wsahelp.h>
 
index 28f044c..2ce641c 100644 (file)
@@ -96,6 +96,32 @@ getsockname(IN     SOCKET s,
     return Error;
 }
 
+INT
+WSAAPI
+MapUnicodeProtocolInfoToAnsi(IN LPWSAPROTOCOL_INFOW UnicodeInfo,
+                             OUT LPWSAPROTOCOL_INFOA AnsiInfo)
+{
+    INT ReturnValue;
+
+    /* Copy all the data that doesn't need converting */
+    RtlCopyMemory(AnsiInfo,
+                  UnicodeInfo,
+                  FIELD_OFFSET(WSAPROTOCOL_INFOA, szProtocol));
+
+    /* Now convert the protocol string */
+    ReturnValue = WideCharToMultiByte(CP_ACP,
+                                      0,
+                                      UnicodeInfo->szProtocol,
+                                      -1,
+                                      AnsiInfo->szProtocol,
+                                      sizeof(AnsiInfo->szProtocol),
+                                      NULL,
+                                      NULL);
+    if (!ReturnValue) return WSASYSCALLFAILURE;
+
+    /* Return success */
+    return ERROR_SUCCESS;
+}
 
 /*
  * @implemented
@@ -111,6 +137,9 @@ getsockopt(IN      SOCKET s,
     PCATALOG_ENTRY Provider;
     INT Errno;
     int Error;
+    WSAPROTOCOL_INFOW ProtocolInfo;
+    PCHAR OldOptVal = NULL;
+    INT OldOptLen = 0;
 
     if (!WSAINITIALIZED)
     {
@@ -125,6 +154,47 @@ getsockopt(IN      SOCKET s,
         return SOCKET_ERROR;
     }
 
+    /* Check if ANSI data was requested */
+    if ((level == SOL_SOCKET) && (optname == SO_PROTOCOL_INFOA))
+    {
+        /* Validate size and pointers */
+        Errno = NO_ERROR;
+        _SEH2_TRY
+        {
+            if (!(optval) ||
+                !(optlen) ||
+                (*optlen < sizeof(WSAPROTOCOL_INFOA)))
+            {
+                /* Set return size and error code */
+                *optlen = sizeof(WSAPROTOCOL_INFOA);
+                Errno = WSAEFAULT;
+                _SEH2_LEAVE;
+            }
+
+            /* It worked. Save the values */
+            OldOptLen = *optlen;
+            OldOptVal = optval;
+
+            /* Hack them so WSP will know how to deal with it */
+            *optlen = sizeof(WSAPROTOCOL_INFOW);
+            optval = (PCHAR)&ProtocolInfo;
+            optname = SO_PROTOCOL_INFOW;
+        }
+        _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+        {
+            Errno = WSAEFAULT;
+        }
+        _SEH2_END;
+
+        /* Did we encounter invalid parameters? */
+        if (Errno != NO_ERROR)
+        {
+            /* Fail */
+            Error = SOCKET_ERROR;
+            goto Exit;
+        }
+    }
+
     Error = Provider->ProcTable.lpWSPGetSockOpt(s,
                                                 level,
                                                 optname,
@@ -132,6 +202,28 @@ getsockopt(IN      SOCKET s,
                                                 optlen,
                                                 &Errno);
 
+    /* Did we use the A->W hack? */
+    if (Error == ERROR_SUCCESS && OldOptVal)
+    {
+        /* We did, so we have to convert the unicode info to ansi */
+        Errno = MapUnicodeProtocolInfoToAnsi(&ProtocolInfo,
+                                             (LPWSAPROTOCOL_INFOA)
+                                             OldOptVal);
+
+        /* Return the length */
+        _SEH2_TRY
+        {
+            *optlen = OldOptLen;
+        }
+        _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
+        {
+            Errno = WSAEFAULT;
+            Error = SOCKET_ERROR;
+        }
+        _SEH2_END;
+    }
+
+Exit:
     DereferenceProviderByPointer(Provider);
 
     if (Error == SOCKET_ERROR)