Beginnings of costing and organizing into components and features.
[wine/dcerpc.git] / dlls / wsock32 / protocol.c
blobfe06829c677d5999e41c7d877af96c35254b7248
1 /*
2 * WSOCK32 specific functions
4 * Copyright (C) 2001 Stefan Leichter
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 /* All we need are a couple constants for EnumProtocols. Once it is
22 * moved to ws2_32 we may no longer need it
24 #define USE_WS_PREFIX
26 #include "config.h"
28 #include <stdarg.h>
29 #include <stdio.h>
30 #include <string.h>
32 #include <sys/types.h>
33 #ifdef HAVE_ARPA_INET_H
34 #include <arpa/inet.h>
35 #endif
36 #ifdef HAVE_NETDB_H
37 #include <netdb.h>
38 #endif
40 #include "windef.h"
41 #include "winbase.h"
42 #include "winnls.h"
43 #include "wtypes.h"
44 #include "nspapi.h"
45 #include "winsock2.h"
46 #include "wsipx.h"
47 #include "wshisotp.h"
49 #include "wine/unicode.h"
50 #include "wine/debug.h"
52 WINE_DEFAULT_DEBUG_CHANNEL(winsock);
54 /* name of the protocols
56 static const WCHAR NameIpx[] = {'I', 'P', 'X', '\0'};
57 static const WCHAR NameSpx[] = {'S', 'P', 'X', '\0'};
58 static const WCHAR NameSpxII[] = {'S', 'P', 'X', ' ', 'I', 'I', '\0'};
59 static const WCHAR NameTcp[] = {'T', 'C', 'P', '/', 'I', 'P', '\0'};
60 static const WCHAR NameUdp[] = {'U', 'D', 'P', '/', 'I', 'P', '\0'};
62 /*****************************************************************************
63 * WSOCK32_EnterSingleProtocol [internal]
65 * enters the protocol informations of one given protocol into the
66 * given buffer. If the given buffer is too small only the required size for
67 * the protocols are returned.
69 * RETURNS
70 * The number of protocols entered into the buffer
72 * BUGS
73 * - only implemented for IPX, SPX, SPXII, TCP, UDP
74 * - there is no check that the operating system supports the returned
75 * protocols
77 static INT WSOCK32_EnterSingleProtocol( INT iProtocol,
78 PROTOCOL_INFOA* lpBuffer,
79 LPDWORD lpSize, BOOL unicode)
80 { DWORD dwLength = 0, dwOldSize = *lpSize;
81 INT iAnz = 1;
82 const WCHAR* lpProtName = NULL;
84 *lpSize = sizeof( PROTOCOL_INFOA);
85 switch (iProtocol) {
86 case WS_IPPROTO_TCP :
87 dwLength = (unicode) ? sizeof(WCHAR) * (strlenW(NameTcp)+1) :
88 WideCharToMultiByte( CP_ACP, 0, NameTcp, -1,
89 NULL, 0, NULL, NULL);
90 break;
91 case WS_IPPROTO_UDP :
92 dwLength = (unicode) ? sizeof(WCHAR) * (strlenW(NameUdp)+1) :
93 WideCharToMultiByte( CP_ACP, 0, NameUdp, -1,
94 NULL, 0, NULL, NULL);
95 break;
96 case NSPROTO_IPX :
97 dwLength = (unicode) ? sizeof(WCHAR) * (strlenW(NameIpx)+1) :
98 WideCharToMultiByte( CP_ACP, 0, NameIpx, -1,
99 NULL, 0, NULL, NULL);
100 break;
101 case NSPROTO_SPX :
102 dwLength = (unicode) ? sizeof(WCHAR) * (strlenW(NameSpx)+1) :
103 WideCharToMultiByte( CP_ACP, 0, NameSpx, -1,
104 NULL, 0, NULL, NULL);
105 break;
106 case NSPROTO_SPXII :
107 dwLength = (unicode) ? sizeof(WCHAR) * (strlenW(NameSpxII)+1) :
108 WideCharToMultiByte( CP_ACP, 0, NameSpxII, -1,
109 NULL, 0, NULL, NULL);
110 break;
111 default:
112 *lpSize = 0;
113 if ((iProtocol == ISOPROTO_TP4) || (iProtocol == NSPROTO_SPX))
114 FIXME("Protocol <%s> not implemented\n",
115 (iProtocol == ISOPROTO_TP4) ? "ISOPROTO_TP4" : "NSPROTO_SPX");
116 else
117 FIXME("unknown Protocol <0x%08x>\n", iProtocol);
118 break;
120 *lpSize += dwLength;
122 if ( !lpBuffer || !*lpSize || (*lpSize > dwOldSize))
123 return 0;
125 memset( lpBuffer, 0, dwOldSize);
127 lpBuffer->lpProtocol = (LPSTR) &lpBuffer[ iAnz];
128 lpBuffer->iProtocol = iProtocol;
130 switch (iProtocol) {
131 case WS_IPPROTO_TCP :
132 lpBuffer->dwServiceFlags = XP_FRAGMENTATION | XP_EXPEDITED_DATA |
133 XP_GRACEFUL_CLOSE | XP_GUARANTEED_ORDER |
134 XP_GUARANTEED_DELIVERY;
135 lpBuffer->iAddressFamily = WS_AF_INET;
136 lpBuffer->iMaxSockAddr = 0x10; /* NT4 SP5 */
137 lpBuffer->iMinSockAddr = 0x10; /* NT4 SP5 */
138 lpBuffer->iSocketType = WS_SOCK_STREAM;
139 lpBuffer->dwMessageSize = 0;
140 lpProtName = NameTcp;
141 break;
142 case WS_IPPROTO_UDP :
143 lpBuffer->dwServiceFlags = XP_FRAGMENTATION | XP_SUPPORTS_BROADCAST |
144 XP_SUPPORTS_MULTICAST | XP_MESSAGE_ORIENTED |
145 XP_CONNECTIONLESS;
146 lpBuffer->iAddressFamily = WS_AF_INET;
147 lpBuffer->iMaxSockAddr = 0x10; /* NT4 SP5 */
148 lpBuffer->iMinSockAddr = 0x10; /* NT4 SP5 */
149 lpBuffer->iSocketType = WS_SOCK_DGRAM;
150 lpBuffer->dwMessageSize = 65457; /* NT4 SP5 */
151 lpProtName = NameUdp;
152 break;
153 case NSPROTO_IPX :
154 lpBuffer->dwServiceFlags = XP_FRAGMENTATION | XP_SUPPORTS_BROADCAST |
155 XP_SUPPORTS_MULTICAST | XP_MESSAGE_ORIENTED |
156 XP_CONNECTIONLESS;
157 lpBuffer->iAddressFamily = WS_AF_IPX;
158 lpBuffer->iMaxSockAddr = 0x10; /* NT4 SP5 */
159 lpBuffer->iMinSockAddr = 0x0e; /* NT4 SP5 */
160 lpBuffer->iSocketType = WS_SOCK_DGRAM;
161 lpBuffer->dwMessageSize = 576; /* NT4 SP5 */
162 lpProtName = NameIpx;
163 break;
164 case NSPROTO_SPX :
165 lpBuffer->dwServiceFlags = XP_FRAGMENTATION |
166 XP_PSEUDO_STREAM | XP_MESSAGE_ORIENTED |
167 XP_GUARANTEED_ORDER | XP_GUARANTEED_DELIVERY;
168 lpBuffer->iAddressFamily = WS_AF_IPX;
169 lpBuffer->iMaxSockAddr = 0x10; /* NT4 SP5 */
170 lpBuffer->iMinSockAddr = 0x0e; /* NT4 SP5 */
171 lpBuffer->iSocketType = 5;
172 lpBuffer->dwMessageSize = -1; /* NT4 SP5 */
173 lpProtName = NameSpx;
174 break;
175 case NSPROTO_SPXII :
176 lpBuffer->dwServiceFlags = XP_FRAGMENTATION | XP_GRACEFUL_CLOSE |
177 XP_PSEUDO_STREAM | XP_MESSAGE_ORIENTED |
178 XP_GUARANTEED_ORDER | XP_GUARANTEED_DELIVERY;
179 lpBuffer->iAddressFamily = WS_AF_IPX;
180 lpBuffer->iMaxSockAddr = 0x10; /* NT4 SP5 */
181 lpBuffer->iMinSockAddr = 0x0e; /* NT4 SP5 */
182 lpBuffer->iSocketType = 5;
183 lpBuffer->dwMessageSize = -1; /* NT4 SP5 */
184 lpProtName = NameSpxII;
185 break;
187 if (unicode)
188 strcpyW( (LPWSTR)lpBuffer->lpProtocol, lpProtName);
189 else
190 WideCharToMultiByte( CP_ACP, 0, lpProtName, -1, lpBuffer->lpProtocol,
191 dwOldSize - iAnz * sizeof( PROTOCOL_INFOA), NULL, NULL);
193 return iAnz;
196 /* FIXME: EnumProtocols should be moved to winsock2, and this should be
197 * implemented by calling out to WSAEnumProtocols. See:
198 * http://support.microsoft.com/support/kb/articles/Q129/3/15.asp
200 /*****************************************************************************
201 * WSOCK32_EnumProtocol [internal]
203 * Enters the information about installed protocols into a given buffer
205 * RETURNS
206 * SOCKET_ERROR if the buffer is to small for the requested protocol infos
207 * on success the number of protocols inside the buffer
209 * NOTE
210 * NT4SP5 does not return SPX if lpiProtocols == NULL
212 * BUGS
213 * - NT4SP5 returns in addition these list of NETBIOS protocols
214 * (address family 17), each entry two times one for socket type 2 and 5
216 * iProtocol lpProtocol
217 * 0x80000000 \Device\NwlnkNb
218 * 0xfffffffa \Device\NetBT_CBENT7
219 * 0xfffffffb \Device\Nbf_CBENT7
220 * 0xfffffffc \Device\NetBT_NdisWan5
221 * 0xfffffffd \Device\NetBT_El9202
222 * 0xfffffffe \Device\Nbf_El9202
223 * 0xffffffff \Device\Nbf_NdisWan4
225 * - there is no check that the operating system supports the returned
226 * protocols
228 static INT WSOCK32_EnumProtocol( LPINT lpiProtocols, PROTOCOL_INFOA* lpBuffer,
229 LPDWORD lpdwLength, BOOL unicode)
230 { DWORD dwCurSize, dwOldSize = *lpdwLength, dwTemp;
231 INT anz = 0, i;
232 INT iLocal[] = { WS_IPPROTO_TCP, WS_IPPROTO_UDP, NSPROTO_IPX, NSPROTO_SPXII, 0};
234 if (!lpiProtocols) lpiProtocols = iLocal;
236 *lpdwLength = 0;
237 while ( *lpiProtocols )
238 { dwCurSize = 0;
239 WSOCK32_EnterSingleProtocol( *lpiProtocols, NULL, &dwCurSize, unicode);
241 if ( lpBuffer && dwCurSize && ((*lpdwLength + dwCurSize) <= dwOldSize))
242 { /* reserve the required space for the current protocol_info after the
243 * last protocol_info before the start of the string buffer and adjust
244 * the references into the string buffer
246 memmove( &((char*)&lpBuffer[ anz])[dwCurSize],
247 &lpBuffer[ anz],
248 *lpdwLength - anz * sizeof( PROTOCOL_INFOA));
249 for (i=0; i < anz; i++)
250 lpBuffer[i].lpProtocol += dwCurSize;
252 dwTemp = dwCurSize;
253 anz += WSOCK32_EnterSingleProtocol( *lpiProtocols, &lpBuffer[anz],
254 &dwTemp, unicode);
257 *lpdwLength += dwCurSize;
258 lpiProtocols++;
261 if (dwOldSize < *lpdwLength) anz = SOCKET_ERROR;
263 return anz;
266 /*****************************************************************************
267 * EnumProtocolsA [WSOCK32.1111]
269 * see function WSOCK32_EnumProtocol for RETURNS, BUGS
271 INT WINAPI EnumProtocolsA( LPINT lpiProtocols, LPVOID lpBuffer,
272 LPDWORD lpdwLength)
274 return WSOCK32_EnumProtocol( lpiProtocols, (PROTOCOL_INFOA*) lpBuffer,
275 lpdwLength, FALSE);
278 /*****************************************************************************
279 * EnumProtocolsW [WSOCK32.1112]
281 * see function WSOCK32_EnumProtocol for RETURNS, BUGS
283 INT WINAPI EnumProtocolsW( LPINT lpiProtocols, LPVOID lpBuffer,
284 LPDWORD lpdwLength)
286 return WSOCK32_EnumProtocol( lpiProtocols, (PROTOCOL_INFOA*) lpBuffer,
287 lpdwLength, TRUE);
290 /*****************************************************************************
291 * inet_network [WSOCK32.1100]
293 UINT WINAPI WSOCK32_inet_network(const char *cp)
295 #ifdef HAVE_INET_NETWORK
296 return inet_network(cp);
297 #else
298 return 0;
299 #endif
302 /*****************************************************************************
303 * getnetbyname [WSOCK32.1101]
305 struct netent * WINAPI WSOCK32_getnetbyname(const char *name)
307 #ifdef HAVE_GETNETBYNAME
308 return getnetbyname(name);
309 #else
310 return NULL;
311 #endif