- Handle SO_PROTOCOL_INFOA in getsockopt based on ws2_32_new.
CORE-10440

svn path=/trunk/; revision=69826
This commit is contained in:
Thomas Faber 2015-11-07 09:38:13 +00:00
parent 3d52f24d8b
commit 5759f02c73
3 changed files with 95 additions and 1 deletions

View 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)

View file

@ -16,10 +16,12 @@
#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>

View 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)