Looking up protocol information by protocol number is not reliable, as protocol numbers for different families may overlap.
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/ws2_32/socket.c | 210 ++++++++++++++++++++++++++++++------------- 1 file changed, 149 insertions(+), 61 deletions(-)
diff --git a/dlls/ws2_32/socket.c b/dlls/ws2_32/socket.c index 5089029f4b4..2316ab3929e 100644 --- a/dlls/ws2_32/socket.c +++ b/dlls/ws2_32/socket.c @@ -200,6 +200,90 @@ static const GUID ProviderIdIPX = { 0x11058240, 0xbe47, 0x11cf, static const GUID ProviderIdSPX = { 0x11058241, 0xbe47, 0x11cf, { 0x95, 0xc8, 0x00, 0x80, 0x5f, 0x48, 0xa1, 0x92 } };
+static const WSAPROTOCOL_INFOW supported_protocols[] = +{ + { + .dwServiceFlags1 = XP1_IFS_HANDLES | XP1_EXPEDITED_DATA | XP1_GRACEFUL_CLOSE + | XP1_GUARANTEED_ORDER | XP1_GUARANTEED_DELIVERY, + .dwProviderFlags = PFL_MATCHES_PROTOCOL_ZERO, + .ProviderId = ProviderIdIP, + .dwCatalogEntryId = 1001, + .ProtocolChain.ChainLen = 1, + .iVersion = 2, + .iAddressFamily = WS_AF_INET, + .iMaxSockAddr = sizeof(struct WS_sockaddr_in), + .iMinSockAddr = sizeof(struct WS_sockaddr_in), + .iSocketType = WS_SOCK_STREAM, + .iProtocol = WS_IPPROTO_TCP, + .szProtocol = {'T','C','P','/','I','P',0}, + }, + { + .dwServiceFlags1 = XP1_IFS_HANDLES | XP1_SUPPORT_BROADCAST + | XP1_SUPPORT_MULTIPOINT | XP1_MESSAGE_ORIENTED | XP1_CONNECTIONLESS, + .dwProviderFlags = PFL_MATCHES_PROTOCOL_ZERO, + .ProviderId = ProviderIdIP, + .dwCatalogEntryId = 1002, + .ProtocolChain.ChainLen = 1, + .iVersion = 2, + .iAddressFamily = WS_AF_INET, + .iMaxSockAddr = sizeof(struct WS_sockaddr_in), + .iMinSockAddr = sizeof(struct WS_sockaddr_in), + .iSocketType = WS_SOCK_DGRAM, + .iProtocol = WS_IPPROTO_UDP, + .dwMessageSize = 0xffbb, + .szProtocol = {'U','D','P','/','I','P',0}, + }, + { + .dwServiceFlags1 = XP1_PARTIAL_MESSAGE | XP1_SUPPORT_BROADCAST + | XP1_SUPPORT_MULTIPOINT | XP1_MESSAGE_ORIENTED | XP1_CONNECTIONLESS, + .dwProviderFlags = PFL_MATCHES_PROTOCOL_ZERO, + .ProviderId = ProviderIdIPX, + .dwCatalogEntryId = 1030, + .ProtocolChain.ChainLen = 1, + .iVersion = 2, + .iAddressFamily = WS_AF_IPX, + .iMaxSockAddr = sizeof(struct WS_sockaddr), + .iMinSockAddr = sizeof(struct WS_sockaddr_ipx), + .iSocketType = WS_SOCK_DGRAM, + .iProtocol = WS_NSPROTO_IPX, + .iProtocolMaxOffset = 255, + .dwMessageSize = 0x240, + .szProtocol = {'I','P','X',0}, + }, + { + .dwServiceFlags1 = XP1_IFS_HANDLES | XP1_PSEUDO_STREAM | XP1_MESSAGE_ORIENTED + | XP1_GUARANTEED_ORDER | XP1_GUARANTEED_DELIVERY, + .dwProviderFlags = PFL_MATCHES_PROTOCOL_ZERO, + .ProviderId = ProviderIdSPX, + .dwCatalogEntryId = 1031, + .ProtocolChain.ChainLen = 1, + .iVersion = 2, + .iAddressFamily = WS_AF_IPX, + .iMaxSockAddr = sizeof(struct WS_sockaddr), + .iMinSockAddr = sizeof(struct WS_sockaddr_ipx), + .iSocketType = WS_SOCK_SEQPACKET, + .iProtocol = WS_NSPROTO_SPX, + .dwMessageSize = UINT_MAX, + .szProtocol = {'S','P','X',0}, + }, + { + .dwServiceFlags1 = XP1_IFS_HANDLES | XP1_GRACEFUL_CLOSE | XP1_PSEUDO_STREAM + | XP1_MESSAGE_ORIENTED | XP1_GUARANTEED_ORDER | XP1_GUARANTEED_DELIVERY, + .dwProviderFlags = PFL_MATCHES_PROTOCOL_ZERO, + .ProviderId = ProviderIdSPX, + .dwCatalogEntryId = 1033, + .ProtocolChain.ChainLen = 1, + .iVersion = 2, + .iAddressFamily = WS_AF_IPX, + .iMaxSockAddr = sizeof(struct WS_sockaddr), + .iMinSockAddr = sizeof(struct WS_sockaddr_ipx), + .iSocketType = WS_SOCK_SEQPACKET, + .iProtocol = WS_NSPROTO_SPXII, + .dwMessageSize = UINT_MAX, + .szProtocol = {'S','P','X',' ','I','I',0}, + }, +}; + static const INT valid_protocols[] = { WS_IPPROTO_TCP, @@ -1869,15 +1953,6 @@ static inline BOOL supported_pf(int pf) } }
-static inline BOOL supported_protocol(int protocol) -{ - int i; - for (i = 0; i < ARRAY_SIZE(valid_protocols); i++) - if (protocol == valid_protocols[i]) - return TRUE; - return FALSE; -} - /**********************************************************************/
/* Returns the length of the converted address if successful, 0 if it was too @@ -2345,54 +2420,6 @@ static BOOL WS_EnterSingleProtocolA( INT protocol, WSAPROTOCOL_INFOA* info ) return ret; }
-static INT WS_EnumProtocols( BOOL unicode, const INT *protocols, LPWSAPROTOCOL_INFOW buffer, LPDWORD len ) -{ - INT i = 0, items = 0; - DWORD size = 0; - union _info - { - LPWSAPROTOCOL_INFOA a; - LPWSAPROTOCOL_INFOW w; - } info; - info.w = buffer; - - if (!protocols) protocols = valid_protocols; - - while (protocols[i]) - { - if(supported_protocol(protocols[i++])) - items++; - } - - size = items * (unicode ? sizeof(WSAPROTOCOL_INFOW) : sizeof(WSAPROTOCOL_INFOA)); - - TRACE("unicode %d, protocols %p, buffer %p, length %p %d, items %d, required %d\n", - unicode, protocols, buffer, len, len ? *len : 0, items, size); - - if (*len < size || !buffer) - { - *len = size; - SetLastError(WSAENOBUFS); - return SOCKET_ERROR; - } - - for (i = items = 0; protocols[i]; i++) - { - if (!supported_protocol(protocols[i])) continue; - if (unicode) - { - if (WS_EnterSingleProtocolW( protocols[i], &info.w[items] )) - items++; - } - else - { - if (WS_EnterSingleProtocolA( protocols[i], &info.a[items] )) - items++; - } - } - return items; -} - static BOOL ws_protocol_info(SOCKET s, int unicode, WSAPROTOCOL_INFOW *buffer, int *size) { NTSTATUS status; @@ -9105,14 +9132,52 @@ INT WINAPI WSANSPIoctl( HANDLE hLookup, DWORD dwControlCode, LPVOID lpvInBuffer, return SOCKET_ERROR; }
+static BOOL protocol_matches_filter( const int *filter, int protocol ) +{ + if (!filter) return TRUE; + while (*filter) + { + if (protocol == *filter++) return TRUE; + } + return FALSE; +} + /***************************************************************************** * WSAEnumProtocolsA [WS2_32.@] * * see function WSAEnumProtocolsW */ -INT WINAPI WSAEnumProtocolsA( LPINT protocols, LPWSAPROTOCOL_INFOA buffer, LPDWORD len ) +int WINAPI WSAEnumProtocolsA( int *filter, WSAPROTOCOL_INFOA *protocols, DWORD *size ) { - return WS_EnumProtocols( FALSE, protocols, (LPWSAPROTOCOL_INFOW) buffer, len); + DWORD i, count = 0; + + TRACE("filter %p, protocols %p, size %p\n", filter, protocols, size); + + for (i = 0; i < ARRAY_SIZE(supported_protocols); ++i) + { + if (protocol_matches_filter( filter, supported_protocols[i].iProtocol )) + ++count; + } + + if (!protocols || *size < count * sizeof(WSAPROTOCOL_INFOA)) + { + *size = count * sizeof(WSAPROTOCOL_INFOA); + WSASetLastError( WSAENOBUFS ); + return SOCKET_ERROR; + } + + count = 0; + for (i = 0; i < ARRAY_SIZE(supported_protocols); ++i) + { + if (protocol_matches_filter( filter, supported_protocols[i].iProtocol )) + { + memcpy( &protocols[count], &supported_protocols[i], offsetof( WSAPROTOCOL_INFOW, szProtocol ) ); + WideCharToMultiByte( CP_ACP, 0, supported_protocols[i].szProtocol, -1, + protocols[count].szProtocol, sizeof(protocols[count].szProtocol), NULL, NULL ); + ++count; + } + } + return count; }
/***************************************************************************** @@ -9152,9 +9217,32 @@ INT WINAPI WSAEnumProtocolsA( LPINT protocols, LPWSAPROTOCOL_INFOA buffer, LPDWO * - there is no check that the operating system supports the returned * protocols */ -INT WINAPI WSAEnumProtocolsW( LPINT protocols, LPWSAPROTOCOL_INFOW buffer, LPDWORD len ) +int WINAPI WSAEnumProtocolsW( int *filter, WSAPROTOCOL_INFOW *protocols, DWORD *size ) { - return WS_EnumProtocols( TRUE, protocols, buffer, len); + DWORD i, count = 0; + + TRACE("filter %p, protocols %p, size %p\n", filter, protocols, size); + + for (i = 0; i < ARRAY_SIZE(supported_protocols); ++i) + { + if (protocol_matches_filter( filter, supported_protocols[i].iProtocol )) + ++count; + } + + if (!protocols || *size < count * sizeof(WSAPROTOCOL_INFOW)) + { + *size = count * sizeof(WSAPROTOCOL_INFOW); + WSASetLastError( WSAENOBUFS ); + return SOCKET_ERROR; + } + + count = 0; + for (i = 0; i < ARRAY_SIZE(supported_protocols); ++i) + { + if (protocol_matches_filter( filter, supported_protocols[i].iProtocol )) + protocols[count++] = supported_protocols[i]; + } + return count; }
/*****************************************************************************
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/ws2_32/socket.c | 43 +++++++++++++++++----------------------- dlls/ws2_32/tests/sock.c | 6 ++---- 2 files changed, 20 insertions(+), 29 deletions(-)
diff --git a/dlls/ws2_32/socket.c b/dlls/ws2_32/socket.c index 2316ab3929e..65edc077b43 100644 --- a/dlls/ws2_32/socket.c +++ b/dlls/ws2_32/socket.c @@ -284,16 +284,6 @@ static const WSAPROTOCOL_INFOW supported_protocols[] = }, };
-static const INT valid_protocols[] = -{ - WS_IPPROTO_TCP, - WS_IPPROTO_UDP, - WS_NSPROTO_IPX, - WS_NSPROTO_SPX, - WS_NSPROTO_SPXII, - 0 -}; - #define IS_IPX_PROTO(X) ((X) >= WS_NSPROTO_IPX && (X) <= WS_NSPROTO_IPX + 255)
#if defined(IP_UNICAST_IF) && defined(SO_ATTACH_FILTER) @@ -7681,25 +7671,29 @@ SOCKET WINAPI WSASocketW(int af, int type, int protocol, return INVALID_SOCKET; }
- if (!type) + if (!af && lpProtocolInfo) { - int autoproto = protocol; - WSAPROTOCOL_INFOW infow; + WSASetLastError(WSAEAFNOSUPPORT); + return INVALID_SOCKET; + }
- /* default to the first valid protocol */ - if (!autoproto) - autoproto = valid_protocols[0]; - else if(IS_IPX_PROTO(autoproto)) - autoproto = WS_NSPROTO_IPX; + if (!af || !type || !protocol) + { + unsigned int i;
- if (WS_EnterSingleProtocolW(autoproto, &infow)) + for (i = 0; i < ARRAY_SIZE(supported_protocols); ++i) { - type = infow.iSocketType; + const WSAPROTOCOL_INFOW *info = &supported_protocols[i]; + + if (af && af != info->iAddressFamily) continue; + if (type && type != info->iSocketType) continue; + if (protocol && (protocol < info->iProtocol || + protocol > info->iProtocol + info->iProtocolMaxOffset)) continue; + if (!protocol && !(info->dwProviderFlags & PFL_MATCHES_PROTOCOL_ZERO)) continue;
- /* after win2003 it's no longer possible to pass AF_UNSPEC - using the protocol info struct */ - if (!lpProtocolInfo && af == WS_AF_UNSPEC) - af = infow.iAddressFamily; + if (!af) af = supported_protocols[i].iAddressFamily; + if (!type) type = supported_protocols[i].iSocketType; + if (!protocol) protocol = supported_protocols[i].iProtocol; } }
@@ -7715,7 +7709,6 @@ SOCKET WINAPI WSASocketW(int af, int type, int protocol, unixaf = convert_af_w2u(af); unixtype = convert_socktype_w2u(type); protocol = convert_proto_w2u(protocol); - if (unixaf == AF_UNSPEC) unixaf = -1;
/* filter invalid parameters */ if (protocol < 0) diff --git a/dlls/ws2_32/tests/sock.c b/dlls/ws2_32/tests/sock.c index cbbc1db1ee0..7f3c6a9fb35 100644 --- a/dlls/ws2_32/tests/sock.c +++ b/dlls/ws2_32/tests/sock.c @@ -2529,16 +2529,14 @@ static void test_WSASocket(void) { WSAPROTOCOL_INFOA info;
- todo_wine_if (i == 19) ok(sock != INVALID_SOCKET, "Text %u: expected success\n", i); - if (sock == INVALID_SOCKET) continue; + ok(sock != INVALID_SOCKET, "Text %u: expected success\n", i);
size = sizeof(info); err = getsockopt( sock, SOL_SOCKET, SO_PROTOCOL_INFOA, (char *)&info, &size ); ok(!err, "Test %u: getsockopt failed, error %u\n", i, WSAGetLastError()); ok(info.iAddressFamily == tests[i].ret_family, "Test %u: got wrong family %d\n", i, info.iAddressFamily); ok(info.iSocketType == tests[i].ret_type, "Test %u: got wrong type %d\n", i, info.iSocketType); - todo_wine_if (i == 10 || i == 11 || i == 16) - ok(info.iProtocol == tests[i].ret_protocol, "Test %u: got wrong protocol %d\n", i, info.iProtocol); + ok(info.iProtocol == tests[i].ret_protocol, "Test %u: got wrong protocol %d\n", i, info.iProtocol);
closesocket( sock ); }
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/ws2_32/socket.c | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+)
diff --git a/dlls/ws2_32/socket.c b/dlls/ws2_32/socket.c index 65edc077b43..0e22416b66b 100644 --- a/dlls/ws2_32/socket.c +++ b/dlls/ws2_32/socket.c @@ -195,6 +195,7 @@ static const WCHAR NameUdpW[] = {'U', 'D', 'P', '/', 'I', 'P', '\0'}; /* Taken from Win2k */ static const GUID ProviderIdIP = { 0xe70f1aa0, 0xab8b, 0x11cf, { 0x8c, 0xa3, 0x00, 0x80, 0x5f, 0x48, 0xa1, 0x92 } }; +static const GUID ProviderIdIPv6 = {0xf9eab0c0, 0x26d4, 0x11d0, {0xbb, 0xbf, 0x00, 0xaa, 0x00, 0x6c, 0x34, 0xe4}}; static const GUID ProviderIdIPX = { 0x11058240, 0xbe47, 0x11cf, { 0x95, 0xc8, 0x00, 0x80, 0x5f, 0x48, 0xa1, 0x92 } }; static const GUID ProviderIdSPX = { 0x11058241, 0xbe47, 0x11cf, @@ -233,6 +234,37 @@ static const WSAPROTOCOL_INFOW supported_protocols[] = .dwMessageSize = 0xffbb, .szProtocol = {'U','D','P','/','I','P',0}, }, + { + .dwServiceFlags1 = XP1_IFS_HANDLES | XP1_EXPEDITED_DATA | XP1_GRACEFUL_CLOSE + | XP1_GUARANTEED_ORDER | XP1_GUARANTEED_DELIVERY, + .dwProviderFlags = PFL_MATCHES_PROTOCOL_ZERO, + .ProviderId = ProviderIdIPv6, + .dwCatalogEntryId = 1004, + .ProtocolChain.ChainLen = 1, + .iVersion = 2, + .iAddressFamily = WS_AF_INET6, + .iMaxSockAddr = sizeof(struct WS_sockaddr_in6), + .iMinSockAddr = sizeof(struct WS_sockaddr_in6), + .iSocketType = WS_SOCK_STREAM, + .iProtocol = WS_IPPROTO_TCP, + .szProtocol = {'T','C','P','/','I','P','v','6',0}, + }, + { + .dwServiceFlags1 = XP1_IFS_HANDLES | XP1_SUPPORT_BROADCAST + | XP1_SUPPORT_MULTIPOINT | XP1_MESSAGE_ORIENTED | XP1_CONNECTIONLESS, + .dwProviderFlags = PFL_MATCHES_PROTOCOL_ZERO, + .ProviderId = ProviderIdIPv6, + .dwCatalogEntryId = 1005, + .ProtocolChain.ChainLen = 1, + .iVersion = 2, + .iAddressFamily = WS_AF_INET6, + .iMaxSockAddr = sizeof(struct WS_sockaddr_in6), + .iMinSockAddr = sizeof(struct WS_sockaddr_in6), + .iSocketType = WS_SOCK_DGRAM, + .iProtocol = WS_IPPROTO_UDP, + .dwMessageSize = 0xffbb, + .szProtocol = {'U','D','P','/','I','P','v','6',0}, + }, { .dwServiceFlags1 = XP1_PARTIAL_MESSAGE | XP1_SUPPORT_BROADCAST | XP1_SUPPORT_MULTIPOINT | XP1_MESSAGE_ORIENTED | XP1_CONNECTIONLESS,
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=79373
Your paranoid android.
=== debiant (32 bit report) ===
ws2_32: sock.c:3027: Test succeeded inside todo block: Test[1]: expected 0, got 0
Signed-off-by: Zebediah Figura z.figura12@gmail.com --- dlls/ws2_32/socket.c | 175 ++++++------------------------------------- 1 file changed, 23 insertions(+), 152 deletions(-)
diff --git a/dlls/ws2_32/socket.c b/dlls/ws2_32/socket.c index 0e22416b66b..67c9155cdce 100644 --- a/dlls/ws2_32/socket.c +++ b/dlls/ws2_32/socket.c @@ -185,13 +185,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(winsock); WINE_DECLARE_DEBUG_CHANNEL(winediag);
-/* names of the protocols */ -static const WCHAR NameIpxW[] = {'I', 'P', 'X', '\0'}; -static const WCHAR NameSpxW[] = {'S', 'P', 'X', '\0'}; -static const WCHAR NameSpxIIW[] = {'S', 'P', 'X', ' ', 'I', 'I', '\0'}; -static const WCHAR NameTcpW[] = {'T', 'C', 'P', '/', 'I', 'P', '\0'}; -static const WCHAR NameUdpW[] = {'U', 'D', 'P', '/', 'I', 'P', '\0'}; - /* Taken from Win2k */ static const GUID ProviderIdIP = { 0xe70f1aa0, 0xab8b, 0x11cf, { 0x8c, 0xa3, 0x00, 0x80, 0x5f, 0x48, 0xa1, 0x92 } }; @@ -2305,149 +2298,13 @@ static INT WS_DuplicateSocket(BOOL unicode, SOCKET s, DWORD dwProcessId, LPWSAPR return 0; }
-/***************************************************************************** - * WS_EnterSingleProtocolW [internal] - * - * enters the protocol information of one given protocol into the given - * buffer. - * - * RETURNS - * TRUE if a protocol was entered into the buffer. - * - * BUGS - * - only implemented for IPX, SPX, SPXII, TCP, UDP - * - there is no check that the operating system supports the returned - * protocols - */ -static BOOL WS_EnterSingleProtocolW( INT protocol, WSAPROTOCOL_INFOW* info ) -{ - memset( info, 0, sizeof(WSAPROTOCOL_INFOW) ); - info->iProtocol = protocol; - - switch (protocol) - { - case WS_IPPROTO_TCP: - info->dwServiceFlags1 = XP1_IFS_HANDLES | XP1_EXPEDITED_DATA | - XP1_GRACEFUL_CLOSE | XP1_GUARANTEED_ORDER | - XP1_GUARANTEED_DELIVERY; - info->ProviderId = ProviderIdIP; - info->dwCatalogEntryId = 0x3e9; - info->dwProviderFlags = PFL_MATCHES_PROTOCOL_ZERO; - info->ProtocolChain.ChainLen = 1; - info->iVersion = 2; - info->iAddressFamily = WS_AF_INET; - info->iMaxSockAddr = 0x10; - info->iMinSockAddr = 0x10; - info->iSocketType = WS_SOCK_STREAM; - strcpyW( info->szProtocol, NameTcpW ); - break; - - case WS_IPPROTO_UDP: - info->dwServiceFlags1 = XP1_IFS_HANDLES | XP1_SUPPORT_BROADCAST | - XP1_SUPPORT_MULTIPOINT | XP1_MESSAGE_ORIENTED | - XP1_CONNECTIONLESS; - info->ProviderId = ProviderIdIP; - info->dwCatalogEntryId = 0x3ea; - info->dwProviderFlags = PFL_MATCHES_PROTOCOL_ZERO; - info->ProtocolChain.ChainLen = 1; - info->iVersion = 2; - info->iAddressFamily = WS_AF_INET; - info->iMaxSockAddr = 0x10; - info->iMinSockAddr = 0x10; - info->iSocketType = WS_SOCK_DGRAM; - info->dwMessageSize = 0xffbb; - strcpyW( info->szProtocol, NameUdpW ); - break; - - case WS_NSPROTO_IPX: - info->dwServiceFlags1 = XP1_PARTIAL_MESSAGE | XP1_SUPPORT_BROADCAST | - XP1_SUPPORT_MULTIPOINT | XP1_MESSAGE_ORIENTED | - XP1_CONNECTIONLESS; - info->ProviderId = ProviderIdIPX; - info->dwCatalogEntryId = 0x406; - info->dwProviderFlags = PFL_MATCHES_PROTOCOL_ZERO; - info->ProtocolChain.ChainLen = 1; - info->iVersion = 2; - info->iAddressFamily = WS_AF_IPX; - info->iMaxSockAddr = 0x10; - info->iMinSockAddr = 0x0e; - info->iSocketType = WS_SOCK_DGRAM; - info->iProtocolMaxOffset = 0xff; - info->dwMessageSize = 0x240; - strcpyW( info->szProtocol, NameIpxW ); - break; - - case WS_NSPROTO_SPX: - info->dwServiceFlags1 = XP1_IFS_HANDLES | XP1_PSEUDO_STREAM | - XP1_MESSAGE_ORIENTED | XP1_GUARANTEED_ORDER | - XP1_GUARANTEED_DELIVERY; - info->ProviderId = ProviderIdSPX; - info->dwCatalogEntryId = 0x407; - info->dwProviderFlags = PFL_MATCHES_PROTOCOL_ZERO; - info->ProtocolChain.ChainLen = 1; - info->iVersion = 2; - info->iAddressFamily = WS_AF_IPX; - info->iMaxSockAddr = 0x10; - info->iMinSockAddr = 0x0e; - info->iSocketType = WS_SOCK_SEQPACKET; - info->dwMessageSize = 0xffffffff; - strcpyW( info->szProtocol, NameSpxW ); - break; - - case WS_NSPROTO_SPXII: - info->dwServiceFlags1 = XP1_IFS_HANDLES | XP1_GRACEFUL_CLOSE | - XP1_PSEUDO_STREAM | XP1_MESSAGE_ORIENTED | - XP1_GUARANTEED_ORDER | XP1_GUARANTEED_DELIVERY; - info->ProviderId = ProviderIdSPX; - info->dwCatalogEntryId = 0x409; - info->dwProviderFlags = PFL_MATCHES_PROTOCOL_ZERO; - info->ProtocolChain.ChainLen = 1; - info->iVersion = 2; - info->iAddressFamily = WS_AF_IPX; - info->iMaxSockAddr = 0x10; - info->iMinSockAddr = 0x0e; - info->iSocketType = WS_SOCK_SEQPACKET; - info->dwMessageSize = 0xffffffff; - strcpyW( info->szProtocol, NameSpxIIW ); - break; - - default: - FIXME("unknown Protocol <0x%08x>\n", protocol); - return FALSE; - } - return TRUE; -} - -/***************************************************************************** - * WS_EnterSingleProtocolA [internal] - * - * see function WS_EnterSingleProtocolW - * - */ -static BOOL WS_EnterSingleProtocolA( INT protocol, WSAPROTOCOL_INFOA* info ) -{ - WSAPROTOCOL_INFOW infow; - INT ret; - memset( info, 0, sizeof(WSAPROTOCOL_INFOA) ); - - ret = WS_EnterSingleProtocolW( protocol, &infow ); - if (ret) - { - /* convert the structure from W to A */ - memcpy( info, &infow, FIELD_OFFSET( WSAPROTOCOL_INFOA, szProtocol ) ); - WideCharToMultiByte( CP_ACP, 0, infow.szProtocol, -1, - info->szProtocol, WSAPROTOCOL_LEN+1, NULL, NULL ); - } - - return ret; -} - static BOOL ws_protocol_info(SOCKET s, int unicode, WSAPROTOCOL_INFOW *buffer, int *size) { NTSTATUS status; int address_family; int socket_type; int protocol; + unsigned int i;
*size = unicode ? sizeof(WSAPROTOCOL_INFOW) : sizeof(WSAPROTOCOL_INFOA); memset(buffer, 0, *size); @@ -2472,14 +2329,28 @@ static BOOL ws_protocol_info(SOCKET s, int unicode, WSAPROTOCOL_INFOW *buffer, i return FALSE; }
- if (unicode) - WS_EnterSingleProtocolW( protocol, buffer); - else - WS_EnterSingleProtocolA( protocol, (WSAPROTOCOL_INFOA *)buffer); - buffer->iAddressFamily = address_family; - buffer->iSocketType = socket_type; - buffer->iProtocol = protocol; - + for (i = 0; i < ARRAY_SIZE(supported_protocols); ++i) + { + const WSAPROTOCOL_INFOW *info = &supported_protocols[i]; + if (address_family == info->iAddressFamily && + socket_type == info->iSocketType && + protocol >= info->iProtocol && protocol <= info->iProtocol + info->iProtocolMaxOffset) + { + if (unicode) + *buffer = *info; + else + { + WSAPROTOCOL_INFOA *bufferA = (WSAPROTOCOL_INFOA *)buffer; + memcpy( bufferA, info, offsetof( WSAPROTOCOL_INFOW, szProtocol ) ); + WideCharToMultiByte( CP_ACP, 0, info->szProtocol, -1, + bufferA->szProtocol, sizeof(bufferA->szProtocol), NULL, NULL ); + } + buffer->iProtocol = protocol; + return TRUE; + } + } + FIXME("Could not fill protocol information for family %d, type %d, protocol %d.\n", + address_family, socket_type, protocol); return TRUE; }
Zebediah Figura z.figura12@gmail.com writes:
Looking up protocol information by protocol number is not reliable, as protocol numbers for different families may overlap.
Signed-off-by: Zebediah Figura z.figura12@gmail.com
dlls/ws2_32/socket.c | 210 ++++++++++++++++++++++++++++++------------- 1 file changed, 149 insertions(+), 61 deletions(-)
clang doesn't like this:
../wine/dlls/ws2_32/socket.c:209:23: error: initializer element is not a compile-time constant .ProviderId = ProviderIdIP, ^~~~~~~~~~~~ 1 error generated. make: *** [Makefile:166412: dlls/ws2_32/socket.o] Error 1
On 9/28/20 2:16 PM, Alexandre Julliard wrote:
Zebediah Figura z.figura12@gmail.com writes:
Looking up protocol information by protocol number is not reliable, as protocol numbers for different families may overlap.
Signed-off-by: Zebediah Figura z.figura12@gmail.com
dlls/ws2_32/socket.c | 210 ++++++++++++++++++++++++++++++------------- 1 file changed, 149 insertions(+), 61 deletions(-)
clang doesn't like this:
../wine/dlls/ws2_32/socket.c:209:23: error: initializer element is not a compile-time constant .ProviderId = ProviderIdIP, ^~~~~~~~~~~~ 1 error generated. make: *** [Makefile:166412: dlls/ws2_32/socket.o] Error 1
Looks like this is https://bugs.llvm.org/show_bug.cgi?id=45157. Unfortunate; I guess I'll just copy the GUID struct verbatim instead...