' ########################################################################################
' Microsoft Windows
' File: WS2tcpip.inc
' Copyright (c) 2011 Jos? Roca
' Portions Copyright (c) Microsoft Corporation.
' All Rights Reserved.
' THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER
' EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
' MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.
' ########################################################################################
#IF NOT %DEF(PBX_WS2tcpip_PBI)
#DEFINE PBX_WS2tcpip_PBI
%EQUATE `WS2TCPIP_INC = 1
'/*
'** WS2TCPIP.H - WinSock2 Extension for TCP/IP protocols
'**
'** This file contains TCP/IP specific information for use
'** by WinSock2 compatible applications.
'**
'** Copyright (c) Microsoft Corporation. All rights reserved.
'**
'** To provide the backward compatibility, all the TCP/IP
'** specific definitions that were included in the WINSOCK.H
'** file are now included in WINSOCK2.H file. WS2TCPIP.H
'** file includes only the definitions introduced in the
'** "WinSock 2 Protocol-Specific Annex" document.
'**
'** Rev 0.3 Nov 13, 1995
'** Rev 0.4 Dec 15, 1996
'*/
#INCLUDE ONCE "Legacy/Platform/WinSock2.inc"
#INCLUDE ONCE "Legacy/System/ws2ipdef.inc"
#INCLUDE ONCE "Legacy/System/MSTcpIP.inc"
'#INCLUDE ONCE "limits.inc"
'/* Option to use with [gs]etsockopt at the IPPROTO_UDP level */
%EQUATE `UDP_NOCHECKSUM = 1
%EQUATE `UDP_CHECKSUM_COVERAGE = 20 ' /* Set/get UDP-Lite checksum coverage */
'/* Error codes from getaddrinfo() */
%EQUATE `EAI_AGAIN = %WSATRY_AGAIN
%EQUATE `EAI_BADFLAGS = %WSAEINVAL
%EQUATE `EAI_FAIL = %WSANO_RECOVERY
%EQUATE `EAI_FAMILY = %WSAEAFNOSUPPORT
%EQUATE `EAI_MEMORY = %WSA_NOT_ENOUGH_MEMORY
%EQUATE `EAI_NOSECURENAME = %WSA_SECURE_HOST_NOT_FOUND
'//#define EAI_NODATA WSANO_DATA
%EQUATE `EAI_NONAME = %WSAHOST_NOT_FOUND
%EQUATE `EAI_SERVICE = %WSATYPE_NOT_FOUND
%EQUATE `EAI_SOCKTYPE = %WSAESOCKTNOSUPPORT
%EQUATE `EAI_IPSECPOLICY = %WSA_IPSEC_NAME_POLICY_ERROR
'//
'// DCR_FIX: EAI_NODATA remove or fix
'//
'// EAI_NODATA was removed from rfc2553bis
'// need to find out from the authors why and
'// determine the error for "no records of this type"
'// temporarily, we'll keep #define to avoid changing
'// code that could change back; use NONAME
'//
%EQUATE `EAI_NODATA = %EAI_NONAME
DECLARE FUNCTION getaddrinfoA LIB "ws2_32.dll" ALIAS "getaddrinfo" ( BYREF nodename AS ASCIIZ , BYREF servname AS ASCIIZ , BYREF hints AS ADDRINFOA , BYREF res AS QUAD ) AS LONG ' int
'#if (NTDDI_VERSION >= NTDDI_WINXPSP2) || (_WIN32_WINNT >= 0x0502)
DECLARE FUNCTION GetAddrInfoW LIB "ws2_32.dll" ALIAS "GetAddrInfoW" ( BYREF pNodeName AS WSTRINGZ , BYREF pServiceName AS WSTRINGZ , BYREF pHints AS ADDRINFOW , BYREF ppResult AS QUAD ) AS LONG ' int
'#endif
#IF %DEF(%UNICODE)
 MACRO getaddrinfo = getaddrinfoW
#ELSE
 MACRO getaddrinfo = getaddrinfoA
#ENDIF
'#if (_WIN32_WINNT >= 0x0600)
'typedef
'void
'(CALLBACK * LPLOOKUPSERVICE_COMPLETION_ROUTINE)(
' );
DECLARE FUNCTION GetAddrInfoExA LIB "ws2_32.dll" ALIAS "GetAddrInfoExA" ( BYREF pName AS ASCIIZ , BYREF pServiceName AS ASCIIZ , BYVAL dwNameSpace AS QUAD , BYREF lpNspId AS GUID , BYREF hints AS ADDRINFOEXA , BYREF ppResult AS ADDRINFOEXA , BYREF timeout AS TIMEVAL , BYREF lpOverlapped AS OVERLAPPED , BYVAL lpCompletionRoutine AS QUAD , BYREF lpNameHandle AS QUAD ) AS LONG ' int
DECLARE FUNCTION GetAddrInfoExW LIB "ws2_32.dll" ALIAS "GetAddrInfoExW" ( BYREF pName AS WSTRINGZ , BYREF pServiceName AS WSTRINGZ , BYVAL dwNameSpace AS QUAD , BYREF lpNspId AS GUID , BYREF hints AS ADDRINFOEXW , BYREF ppResult AS ADDRINFOEXW , BYREF timeout AS TIMEVAL , BYREF lpOverlapped AS OVERLAPPED , BYVAL lpCompletionRoutine AS QUAD , BYREF lpNameHandle AS QUAD ) AS LONG ' int
#IF %DEF(%UNICODE)
 MACRO GetAddrInfoEx = GetAddrInfoExW
#ELSE
 MACRO GetAddrInfoEx = GetAddrInfoExA
#ENDIF
'#endif
'#if (_WIN32_WINNT >= 0x0600)
DECLARE FUNCTION SetAddrInfoExA LIB "ws2_32.dll" ALIAS "SetAddrInfoExA" ( BYREF pName AS ASCIIZ , BYREF pServiceName AS ASCIIZ , BYREF pAddresses AS SOCKET_ADDRESS , BYVAL dwAddressCount AS QUAD , BYREF lpBlob AS BLOB , BYVAL dwFlags AS QUAD , BYVAL dwNameSpace AS QUAD , BYREF lpNspId AS GUID , BYREF timeout AS TIMEVAL , BYREF lpOverlapped AS OVERLAPPED , BYVAL lpCompletionRoutine AS QUAD , BYREF lpNameHandle AS QUAD ) AS LONG ' int
DECLARE FUNCTION SetAddrInfoExW LIB "ws2_32.dll" ALIAS "SetAddrInfoExW" ( BYREF pName AS WSTRINGZ , BYREF pServiceName AS WSTRINGZ , BYREF pAddresses AS SOCKET_ADDRESS , BYVAL dwAddressCount AS QUAD , BYREF lpBlob AS BLOB , BYVAL dwFlags AS QUAD , BYVAL dwNameSpace AS QUAD , BYREF lpNspId AS GUID , BYREF timeout AS TIMEVAL , BYREF lpOverlapped AS OVERLAPPED , BYVAL lpCompletionRoutine AS QUAD , BYREF lpNameHandle AS QUAD ) AS LONG ' int
#IF %DEF(%UNICODE)
 MACRO SetAddrInfoEx = SetAddrInfoExW
#ELSE
 MACRO SetAddrInfoEx = SetAddrInfoExA
#ENDIF
'#endif
DECLARE SUB freeaddrinfoA LIB "ws2_32.dll" ALIAS "freeaddrinfo" ( BYREF pAddrInfo AS ADDRINFOA ) ' void
#IF (%NTDDI_VERSION >= %NTDDI_WINXPSP2) OR (%WIN32_WINNT >= &H0502)
DECLARE SUB FreeAddrInfoW LIB "ws2_32.dll" ALIAS "FreeAddrInfoW" ( BYREF pAddrInfo AS ADDRINFOW ) ' void
 #IF %DEF(%UNICODE)
 MACRO freeaddrinfo = freeaddrinfoW
 #ELSE
 MACRO freeaddrinfo = freeaddrinfoA
 #ENDIF
#ELSE
 MACRO freeaddrinfo = freeaddrinfoA
#ENDIF
'#if (_WIN32_WINNT >= 0x0600)
DECLARE SUB FreeAddrInfoExA LIB "ws2_32.dll" ALIAS "FreeAddrInfoEx" ( BYREF pAddrInfoEx AS ADDRINFOEXA ) ' void
DECLARE SUB FreeAddrInfoExW LIB "ws2_32.dll" ALIAS "FreeAddrInfoExW" ( BYREF pAddrInfoEx AS ADDRINFOEXW ) ' void
#IF %DEF(%UNICODE)
 MACRO FreeAddrInfoEx = FreeAddrInfoExW
#ELSE
 MACRO FreeAddrInfoEx = FreeAddrInfoExA
#ENDIF
'#endif
'typedef int socklen_t;
DECLARE FUNCTION getnameinfoA LIB "ws2_32.dll" ALIAS "getnameinfo" ( BYREF sa AS SOCKADDR , BYVAL salen AS LONG , BYREF host AS ASCIIZ , BYVAL hostlen AS QUAD , BYREF serv AS ASCIIZ , BYVAL servlen AS QUAD , BYVAL flags AS LONG ) AS LONG ' int
#IF (%NTDDI_VERSION >= %NTDDI_WINXPSP2) OR (%WIN32_WINNT >= &H0502)
DECLARE FUNCTION GetNameInfoW LIB "ws2_32.dll" ALIAS "GetNameInfoW" ( BYREF pSockaddr AS SOCKADDR , BYVAL SockaddrLength AS LONG , BYREF pNodeBuffer AS WSTRINGZ , BYVAL NodeBufferSize AS QUAD , BYREF pServiceBuffer AS WSTRINGZ , BYVAL ServiceBufferSize AS QUAD , BYVAL Flags AS LONG ) AS LONG ' int
 #IF %DEF(%UNICODE)
 MACRO getnameinfo = GetNameInfoW
 #ELSE
 MACRO getnameinfo = getnameinfoA
 #ENDIF
#ELSE
 MACRO getnameinfo = getnameinfoA
#ENDIF
#IF (%NTDDI_VERSION >= %NTDDI_VISTA)
DECLARE FUNCTION inet_pton LIB "ws2_32.dll" ALIAS "inet_pton" ( BYVAL Family AS LONG , BYREF pszAddrString AS ASCIIZ , BYREF pAddrBuf AS ANY ) AS LONG ' int
DECLARE FUNCTION InetPtonW LIB "ws2_32.dll" ALIAS "InetPtonW" ( BYVAL Family AS LONG , BYREF pszAddrString AS WSTRINGZ , BYREF pAddrBuf AS ANY ) AS LONG ' int
DECLARE FUNCTION inet_ntop LIB "ws2_32.dll" ALIAS "inet_ntop" ( BYVAL Family AS QUAD , BYVAL pAddr AS QUAD , BYREF pStringBuf AS ASCIIZ , BYVAL StringBufSize AS QUAD ) AS QUAD
DECLARE FUNCTION InetNtopW LIB "ws2_32.dll" ALIAS "InetNtopW" ( BYVAL Family AS QUAD
 , BYVAL pAddr AS DWORD
 , BYREF pStringBuf AS WSTRINGZ
 , BYVAL StringBufSize AS DWORD
 ) AS DWORD
#ENDIF ' // (NTDDI_VERSION >= NTDDI_VISTA)
'// WARNING: The gai_strerror inline functions below use static buffers,
'// and hence are not thread-safe. We'll use buffers long enough to hold
'// 1k characters. Any system error messages longer than this will be
'// returned as empty strings. However 1k should work for the error codes
'// used by getaddrinfo().
%EQUATE `GAI_STRERROR_BUFFER_SIZE = 1024
'WS2TCPIP_INLINE
'char *
'gai_strerrorA(
'{
' DWORD dwMsgLen;
' static char buff[GAI_STRERROR_BUFFER_SIZE + 1];
' dwMsgLen = FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM
' |FORMAT_MESSAGE_IGNORE_INSERTS
' |FORMAT_MESSAGE_MAX_WIDTH_MASK,
' NULL,
' ecode,
' MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
' (LPSTR)buff,
' GAI_STRERROR_BUFFER_SIZE,
' NULL);
' return buff;
'}
FUNCTION gai_strerrorA (BYVAL ecode AS LONG) AS STRING
 LOCAL dwMsgLen AS DWORD
 LOCAL buff AS ASCIIZ * %GAI_STRERROR_BUFFER_SIZE + 1
 dwMsgLen = FormatMessageA(%FORMAT_MESSAGE_FROM_SYSTEM OR %FORMAT_MESSAGE_IGNORE_INSERTS OR %FORMAT_MESSAGE_MAX_WIDTH_MASK, BYVAL %NULL, ecode, MAKELANGID(%LANG_NEUTRAL, %SUBLANG_DEFAULT), buff, %GAI_STRERROR_BUFFER_SIZE, BYVAL %NULL)
 FUNCTION = buff
END FUNCTION
'WS2TCPIP_INLINE
'WCHAR *
'gai_strerrorW(
' )
'{
' DWORD dwMsgLen;
' static WCHAR buff[GAI_STRERROR_BUFFER_SIZE + 1];
' dwMsgLen = FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM
' |FORMAT_MESSAGE_IGNORE_INSERTS
' |FORMAT_MESSAGE_MAX_WIDTH_MASK,
' NULL,
' ecode,
' MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
' (LPWSTR)buff,
' GAI_STRERROR_BUFFER_SIZE,
' NULL);
' return buff;
'}
FUNCTION gai_strerrorW (BYVAL ecode AS LONG) AS WSTRING
 LOCAL dwMsgLen AS DWORD
 LOCAL buff AS WSTRINGZ * (%GAI_STRERROR_BUFFER_SIZE + 1)
 dwMsgLen = FormatMessageW(%FORMAT_MESSAGE_FROM_SYSTEM OR %FORMAT_MESSAGE_IGNORE_INSERTS OR %FORMAT_MESSAGE_MAX_WIDTH_MASK, BYVAL %NULL, ecode, MAKELANGID(%LANG_NEUTRAL, %SUBLANG_DEFAULT), buff, %GAI_STRERROR_BUFFER_SIZE, BYVAL %NULL)
 FUNCTION = buff
END FUNCTION
#IF %DEF(%UNICODE)
 MACRO gai_strerror(ecode) = gai_strerrorW(ecode)
#ELSE
 MACRO gai_strerror(ecode) = gai_strerrorA(ecode)
#ENDIF
'#endif /* INCL_WINSOCK_API_PROTOTYPES */
'/* Multicast source filter APIs from RFC 3678. */
'WS2TCPIP_INLINE
'int
'setipv4sourcefilter(
' )
'{
' int Error;
' DWORD Size, Returned;
' PIP_MSFILTER Filter;
' if (SourceCount >
' (((ULONG) (ULONG_MAX - sizeof(*Filter))) / sizeof(*SourceList))) {
' WSASetLastError(WSAENOBUFS);
' return SOCKET_ERROR;
' }
' Size = IP_MSFILTER_SIZE(SourceCount);
' Filter = (PIP_MSFILTER) HeapAlloc(GetProcessHeap(), 0, Size);
' if (Filter == NULL) {
' WSASetLastError(WSAENOBUFS);
' return SOCKET_ERROR;
' }
' Filter->imsf_multiaddr = Group;
' Filter->imsf_interface = Interface;
' Filter->imsf_fmode = FilterMode;
' Filter->imsf_numsrc = SourceCount;
' if (SourceCount > 0) {
' CopyMemory(Filter->imsf_slist, SourceList,
' SourceCount * sizeof(*SourceList));
' }
' Error = WSAIoctl(Socket, SIOCSIPMSFILTER, Filter, Size, NULL, 0,
' &Returned, NULL, NULL);
' HeapFree(GetProcessHeap(), 0, Filter);
' return Error;
'}
'WS2TCPIP_INLINE
'int
'getipv4sourcefilter(
' )
'{
' int Error;
' DWORD Size, Returned;
' PIP_MSFILTER Filter;
' if (*SourceCount >
' (((ULONG) (ULONG_MAX - sizeof(*Filter))) / sizeof(*SourceList))) {
' WSASetLastError(WSAENOBUFS);
' return SOCKET_ERROR;
' }
' Size = IP_MSFILTER_SIZE(*SourceCount);
' Filter = (PIP_MSFILTER) HeapAlloc(GetProcessHeap(), 0, Size);
' if (Filter == NULL) {
' WSASetLastError(WSAENOBUFS);
' return SOCKET_ERROR;
' }
' Filter->imsf_multiaddr = Group;
' Filter->imsf_interface = Interface;
' Filter->imsf_numsrc = *SourceCount;
' Error = WSAIoctl(Socket, SIOCGIPMSFILTER, Filter, Size, Filter, Size,
' &Returned, NULL, NULL);
' if (Error == 0) {
' if (*SourceCount > 0) {
' CopyMemory(SourceList, Filter->imsf_slist,
' *SourceCount * sizeof(*SourceList));
' *SourceCount = Filter->imsf_numsrc;
' }
' *FilterMode = Filter->imsf_fmode;
' }
' HeapFree(GetProcessHeap(), 0, Filter);
' return Error;
'}
'#if (NTDDI_VERSION >= NTDDI_WINXP)
'WS2TCPIP_INLINE
'int
'setsourcefilter(
' )
'{
' int Error;
' DWORD Size, Returned;
' PGROUP_FILTER Filter;
' if (SourceCount >=
' (((ULONG) (ULONG_MAX - sizeof(*Filter))) / sizeof(*SourceList))) {
' WSASetLastError(WSAENOBUFS);
' return SOCKET_ERROR;
' }
' Size = GROUP_FILTER_SIZE(SourceCount);
' Filter = (PGROUP_FILTER) HeapAlloc(GetProcessHeap(), 0, Size);
' if (Filter == NULL) {
' WSASetLastError(WSAENOBUFS);
' return SOCKET_ERROR;
' }
' Filter->gf_interface = Interface;
' ZeroMemory(&Filter->gf_group, sizeof(Filter->gf_group));
' CopyMemory(&Filter->gf_group, Group, GroupLength);
' Filter->gf_fmode = FilterMode;
' Filter->gf_numsrc = SourceCount;
' if (SourceCount > 0) {
' CopyMemory(Filter->gf_slist, SourceList,
' SourceCount * sizeof(*SourceList));
' }
' Error = WSAIoctl(Socket, SIOCSMSFILTER, Filter, Size, NULL, 0,
' &Returned, NULL, NULL);
' HeapFree(GetProcessHeap(), 0, Filter);
' return Error;
'}
'WS2TCPIP_INLINE
'int
'getsourcefilter(
' )
'{
' int Error;
' DWORD Size, Returned;
' PGROUP_FILTER Filter;
' if (*SourceCount >
' (((ULONG) (ULONG_MAX - sizeof(*Filter))) / sizeof(*SourceList))) {
' WSASetLastError(WSAENOBUFS);
' return SOCKET_ERROR;
' }
' Size = GROUP_FILTER_SIZE(*SourceCount);
' Filter = (PGROUP_FILTER) HeapAlloc(GetProcessHeap(), 0, Size);
' if (Filter == NULL) {
' WSASetLastError(WSAENOBUFS);
' return SOCKET_ERROR;
' }
' Filter->gf_interface = Interface;
' ZeroMemory(&Filter->gf_group, sizeof(Filter->gf_group));
' CopyMemory(&Filter->gf_group, Group, GroupLength);
' Filter->gf_numsrc = *SourceCount;
' Error = WSAIoctl(Socket, SIOCGMSFILTER, Filter, Size, Filter, Size,
' &Returned, NULL, NULL);
' if (Error == 0) {
' if (*SourceCount > 0) {
' CopyMemory(SourceList, Filter->gf_slist,
' *SourceCount * sizeof(*SourceList));
' *SourceCount = Filter->gf_numsrc;
' }
' *FilterMode = Filter->gf_fmode;
' }
' HeapFree(GetProcessHeap(), 0, Filter);
' return Error;
'}
'#endif
'#ifdef IDEAL_SEND_BACKLOG_IOCTLS
'//
'// Wrapper functions for the ideal send backlog query and change notification
'// ioctls
'//
'WS2TCPIP_INLINE
'int
'idealsendbacklogquery(
' )
'{
' DWORD bytes;
' return WSAIoctl(s, SIO_IDEAL_SEND_BACKLOG_QUERY,
' NULL, 0, pISB, sizeof(*pISB), &bytes, NULL, NULL);
'}
'WS2TCPIP_INLINE
'int
'idealsendbacklognotify(
' )
'{
' DWORD bytes;
' return WSAIoctl(s, SIO_IDEAL_SEND_BACKLOG_CHANGE,
' NULL, 0, NULL, 0, &bytes,
' lpOverlapped, lpCompletionRoutine);
'}
'#endif
'#if (_WIN32_WINNT >= 0x0600)
'#ifdef _SECURE_SOCKET_TYPES_DEFINED_
'//
'// Secure socket API definitions
'//
DECLARE FUNCTION WSASetSocketSecurity LIB "fwpuclnt.dll" ALIAS "WSASetSocketSecurity" ( BYVAL Socket AS QUAD , BYREF SecuritySettings AS SOCKET_SECURITY_SETTINGS , BYVAL SecuritySettingsLen AS QUAD , BYREF Overlapped AS WSAOVERLAPPED , BYVAL CompletionRoutine AS QUAD ) AS LONG ' INT
DECLARE FUNCTION WSAQuerySocketSecurity LIB "fwpuclnt.dll" ALIAS "WSAQuerySocketSecurity" ( BYVAL Socket AS QUAD , BYREF SecurityQueryTemplate AS SOCKET_SECURITY_QUERY_TEMPLATE , BYVAL SecurityQueryTemplateLen AS QUAD , BYREF SecurityQueryInfo AS ANY , BYREF SecurityQueryInfoLen AS QUAD , BYREF Overlapped AS WSAOVERLAPPED , BYVAL CompletionRoutine AS QUAD ) AS LONG ' INT
DECLARE FUNCTION WSASetSocketPeerTargetName LIB "fwpuclnt.dll" ALIAS "WSASetSocketPeerTargetName" ( BYVAL Socket AS QUAD , BYREF PeerTargetName AS SOCKET_PEER_TARGET_NAME , BYVAL PeerTargetNameLen AS QUAD , BYREF Overlapped AS WSAOVERLAPPED , BYVAL CompletionRoutine AS QUAD ) AS LONG ' INT
DECLARE FUNCTION WSADeleteSocketPeerTargetName LIB "fwpuclnt.dll" ALIAS "WSADeleteSocketPeerTargetName" ( BYVAL Socket AS QUAD , BYREF PeerAddr AS SOCKADDR , BYVAL PeerAddrLen AS QUAD , BYREF Overlapped AS WSAOVERLAPPED , BYVAL CompletionRoutine AS QUAD ) AS LONG ' INT
DECLARE FUNCTION WSAImpersonateSocketPeer LIB "fwpuclnt.dll" ALIAS "WSAImpersonateSocketPeer" ( BYVAL Socket AS QUAD , BYREF PeerAddr AS SOCKADDR , BYVAL PeerAddrLen AS QUAD ) AS LONG ' INT
DECLARE FUNCTION WSARevertImpersonation LIB "fwpuclnt.dll" ALIAS "WSARevertImpersonation" ( ) AS LONG ' INT
'#endif //_SECURE_SOCKET_TYPES_DEFINED_
'#endif //(_WIN32_WINNT >= 0x0600)
'//
'// Unless the build environment is explicitly targeting only
'// platforms that include built-in getaddrinfo() support, include
'// the backwards-compatibility version of the relevant APIs.
'//
'#if !defined(_WIN32_WINNT) || (_WIN32_WINNT <= 0x0500)
'#include <wspiapi.h>
'#endif
#ENDIF
