2 * WSOCK32 specific functions
4 * Copyright (C) 2001 Stefan Leichter
11 #include "debugtools.h"
18 DEFAULT_DEBUG_CHANNEL(winsock);
20 /* name of the protocols
22 static WCHAR NameIpx[] = {'I', 'P', 'X', '\0'};
23 static WCHAR NameSpx[] = {'S', 'P', 'X', '\0'};
24 static WCHAR NameSpxII[] = {'S', 'P', 'X', ' ', 'I', 'I', '\0'};
25 static WCHAR NameTcp[] = {'T', 'C', 'P', '/', 'I', 'P', '\0'};
26 static WCHAR NameUdp[] = {'U', 'D', 'P', '/', 'I', 'P', '\0'};
28 /*****************************************************************************
29 * WSOCK32_EnterSingleProtocol [internal]
31 * enters the protocol informations of one given protocol into the
32 * given buffer. If the given buffer is too small only the required size for
33 * the protocols are returned.
36 * The number of protocols entered into the buffer
39 * - only implemented for IPX, SPX, SPXII, TCP, UDP
40 * - there is no check that the operating system supports the returned
43 static INT WSOCK32_EnterSingleProtocol( INT iProtocol,
44 PROTOCOL_INFOA* lpBuffer,
45 LPDWORD lpSize, BOOL unicode)
46 { DWORD dwLength = 0, dwOldSize = *lpSize;
48 WCHAR *lpProtName = NULL;
50 *lpSize = sizeof( PROTOCOL_INFOA);
53 dwLength = (unicode) ? sizeof(WCHAR) * (strlenW(NameTcp)+1) :
54 WideCharToMultiByte( CP_ACP, 0, NameTcp, -1,
58 dwLength = (unicode) ? sizeof(WCHAR) * (strlenW(NameUdp)+1) :
59 WideCharToMultiByte( CP_ACP, 0, NameUdp, -1,
63 dwLength = (unicode) ? sizeof(WCHAR) * (strlenW(NameIpx)+1) :
64 WideCharToMultiByte( CP_ACP, 0, NameIpx, -1,
68 dwLength = (unicode) ? sizeof(WCHAR) * (strlenW(NameSpx)+1) :
69 WideCharToMultiByte( CP_ACP, 0, NameSpx, -1,
73 dwLength = (unicode) ? sizeof(WCHAR) * (strlenW(NameSpxII)+1) :
74 WideCharToMultiByte( CP_ACP, 0, NameSpxII, -1,
79 if ((iProtocol == ISOPROTO_TP4) || (iProtocol == NSPROTO_SPX))
80 FIXME("Protocol <%s> not implemented\n",
81 (iProtocol == ISOPROTO_TP4) ? "ISOPROTO_TP4" : "NSPROTO_SPX");
83 FIXME("unknown Protocol <0x%08x>\n", iProtocol);
88 if ( !lpBuffer || !*lpSize || (*lpSize > dwOldSize))
91 memset( lpBuffer, 0, dwOldSize);
93 lpBuffer->lpProtocol = (LPSTR) &lpBuffer[ iAnz];
94 lpBuffer->iProtocol = iProtocol;
98 lpBuffer->dwServiceFlags = XP_FRAGMENTATION | XP_EXPEDITED_DATA |
99 XP_GRACEFUL_CLOSE | XP_GUARANTEED_ORDER |
100 XP_GUARANTEED_DELIVERY;
101 lpBuffer->iAddressFamily = WS_AF_INET;
102 lpBuffer->iMaxSockAddr = 0x10; /* NT4 SP5 */
103 lpBuffer->iMinSockAddr = 0x10; /* NT4 SP5 */
104 lpBuffer->iSocketType = SOCK_STREAM;
105 lpBuffer->dwMessageSize = 0;
106 lpProtName = NameTcp;
109 lpBuffer->dwServiceFlags = XP_FRAGMENTATION | XP_SUPPORTS_BROADCAST |
110 XP_SUPPORTS_MULTICAST | XP_MESSAGE_ORIENTED |
112 lpBuffer->iAddressFamily = WS_AF_INET;
113 lpBuffer->iMaxSockAddr = 0x10; /* NT4 SP5 */
114 lpBuffer->iMinSockAddr = 0x10; /* NT4 SP5 */
115 lpBuffer->iSocketType = SOCK_DGRAM;
116 lpBuffer->dwMessageSize = 65457; /* NT4 SP5 */
117 lpProtName = NameUdp;
120 lpBuffer->dwServiceFlags = XP_FRAGMENTATION | XP_SUPPORTS_BROADCAST |
121 XP_SUPPORTS_MULTICAST | XP_MESSAGE_ORIENTED |
123 lpBuffer->iAddressFamily = WS_AF_IPX;
124 lpBuffer->iMaxSockAddr = 0x10; /* NT4 SP5 */
125 lpBuffer->iMinSockAddr = 0x0e; /* NT4 SP5 */
126 lpBuffer->iSocketType = SOCK_DGRAM;
127 lpBuffer->dwMessageSize = 576; /* NT4 SP5 */
128 lpProtName = NameIpx;
131 lpBuffer->dwServiceFlags = XP_FRAGMENTATION |
132 XP_PSEUDO_STREAM | XP_MESSAGE_ORIENTED |
133 XP_GUARANTEED_ORDER | XP_GUARANTEED_DELIVERY;
134 lpBuffer->iAddressFamily = WS_AF_IPX;
135 lpBuffer->iMaxSockAddr = 0x10; /* NT4 SP5 */
136 lpBuffer->iMinSockAddr = 0x0e; /* NT4 SP5 */
137 lpBuffer->iSocketType = 5;
138 lpBuffer->dwMessageSize = -1; /* NT4 SP5 */
139 lpProtName = NameSpx;
142 lpBuffer->dwServiceFlags = XP_FRAGMENTATION | XP_GRACEFUL_CLOSE |
143 XP_PSEUDO_STREAM | XP_MESSAGE_ORIENTED |
144 XP_GUARANTEED_ORDER | XP_GUARANTEED_DELIVERY;
145 lpBuffer->iAddressFamily = WS_AF_IPX;
146 lpBuffer->iMaxSockAddr = 0x10; /* NT4 SP5 */
147 lpBuffer->iMinSockAddr = 0x0e; /* NT4 SP5 */
148 lpBuffer->iSocketType = 5;
149 lpBuffer->dwMessageSize = -1; /* NT4 SP5 */
150 lpProtName = NameSpxII;
154 strcpyW( (LPWSTR)lpBuffer->lpProtocol, lpProtName);
156 WideCharToMultiByte( CP_ACP, 0, lpProtName, -1, lpBuffer->lpProtocol,
157 dwOldSize - iAnz * sizeof( PROTOCOL_INFOA), NULL, NULL);
162 /*****************************************************************************
163 * WSOCK32_EnumProtocol [internal]
165 * Enters the information about installed protocols into a given buffer
168 * SOCKET_ERROR if the buffer is to small for the requested protocol infos
169 * on success the number of protocols inside the buffer
172 * NT4SP5 does not return SPX if lpiProtocols == NULL
175 * - NT4SP5 returns in addition these list of NETBIOS protocols
176 * (address family 17), each entry two times one for socket type 2 and 5
178 * iProtocol lpProtocol
179 * 0x80000000 \Device\NwlnkNb
180 * 0xfffffffa \Device\NetBT_CBENT7
181 * 0xfffffffb \Device\Nbf_CBENT7
182 * 0xfffffffc \Device\NetBT_NdisWan5
183 * 0xfffffffd \Device\NetBT_El9202
184 * 0xfffffffe \Device\Nbf_El9202
185 * 0xffffffff \Device\Nbf_NdisWan4
187 * - there is no check that the operating system supports the returned
190 static INT WSOCK32_EnumProtocol( LPINT lpiProtocols, PROTOCOL_INFOA* lpBuffer,
191 LPDWORD lpdwLength, BOOL unicode)
192 { DWORD dwCurSize, dwOldSize = *lpdwLength, dwTemp;
194 INT iLocal[] = { IPPROTO_TCP, IPPROTO_UDP, NSPROTO_IPX, NSPROTO_SPXII, 0};
196 if (!lpiProtocols) lpiProtocols = iLocal;
199 while ( *lpiProtocols )
201 WSOCK32_EnterSingleProtocol( *lpiProtocols, NULL, &dwCurSize, unicode);
203 if ( lpBuffer && dwCurSize && ((*lpdwLength + dwCurSize) <= dwOldSize))
204 { /* reserve the required space for the current protocol_info after the
205 * last protocol_info before the start of the string buffer and adjust
206 * the references into the string buffer
208 memmove( &((char*)&lpBuffer[ anz])[dwCurSize],
210 *lpdwLength - anz * sizeof( PROTOCOL_INFOA));
211 for (i=0; i < anz; i++)
212 lpBuffer[i].lpProtocol += dwCurSize;
215 anz += WSOCK32_EnterSingleProtocol( *lpiProtocols, &lpBuffer[anz],
219 *lpdwLength += dwCurSize;
223 if (dwOldSize < *lpdwLength) anz = SOCKET_ERROR;
228 /*****************************************************************************
229 * EnumProtocolsA [WSOCK32.1111]
231 * see function WSOCK32_EnumProtocol for RETURNS, BUGS
233 INT WINAPI EnumProtocolsA( LPINT lpiProtocols, LPVOID lpBuffer,
236 return WSOCK32_EnumProtocol( lpiProtocols, (PROTOCOL_INFOA*) lpBuffer,
240 /*****************************************************************************
241 * EnumProtocolsW [WSOCK32.1112]
243 * see function WSOCK32_EnumProtocol for RETURNS, BUGS
245 INT WINAPI EnumProtocolsW( LPINT lpiProtocols, LPVOID lpBuffer,
248 return WSOCK32_EnumProtocol( lpiProtocols, (PROTOCOL_INFOA*) lpBuffer,