Fix the Solaris and FreeBSD compilation errors introduced by the
[wine.git] / dlls / wsock32 / protocol.c
blob5d18c60aeb22ac20a8f156b9f7749487bd874656
1 /*
2 * WSOCK32 specific functions
4 * Copyright (C) 2001 Stefan Leichter
5 */
7 /* All we need are a couple constants for EnumProtocols. Once it is
8 * moved to ws2_32 we may no longer need it
9 */
10 #define USE_WS_PREFIX
12 #include "config.h"
14 #include <stdio.h>
15 #include <string.h>
17 #include <sys/types.h>
18 #ifdef HAVE_SYS_SOCKET_H
19 #include <sys/socket.h>
20 #endif
21 #ifdef HAVE_NETINET_IN_H
22 # include <netinet/in.h>
23 #endif
24 #ifdef HAVE_ARPA_INET_H
25 #include <arpa/inet.h>
26 #endif
27 #ifdef HAVE_NETDB_H
28 #include <netdb.h>
29 #endif
31 #include "winbase.h"
32 #include "winnls.h"
33 #include "wine/unicode.h"
34 #include "nspapi.h"
35 #include "winsock2.h"
36 #include "wsipx.h"
37 #include "wshisotp.h"
39 #include "debugtools.h"
41 DEFAULT_DEBUG_CHANNEL(winsock);
43 /* name of the protocols
45 static WCHAR NameIpx[] = {'I', 'P', 'X', '\0'};
46 static WCHAR NameSpx[] = {'S', 'P', 'X', '\0'};
47 static WCHAR NameSpxII[] = {'S', 'P', 'X', ' ', 'I', 'I', '\0'};
48 static WCHAR NameTcp[] = {'T', 'C', 'P', '/', 'I', 'P', '\0'};
49 static WCHAR NameUdp[] = {'U', 'D', 'P', '/', 'I', 'P', '\0'};
51 /*****************************************************************************
52 * WSOCK32_EnterSingleProtocol [internal]
54 * enters the protocol informations of one given protocol into the
55 * given buffer. If the given buffer is too small only the required size for
56 * the protocols are returned.
58 * RETURNS
59 * The number of protocols entered into the buffer
61 * BUGS
62 * - only implemented for IPX, SPX, SPXII, TCP, UDP
63 * - there is no check that the operating system supports the returned
64 * protocols
66 static INT WSOCK32_EnterSingleProtocol( INT iProtocol,
67 PROTOCOL_INFOA* lpBuffer,
68 LPDWORD lpSize, BOOL unicode)
69 { DWORD dwLength = 0, dwOldSize = *lpSize;
70 INT iAnz = 1;
71 WCHAR *lpProtName = NULL;
73 *lpSize = sizeof( PROTOCOL_INFOA);
74 switch (iProtocol) {
75 case WS_IPPROTO_TCP :
76 dwLength = (unicode) ? sizeof(WCHAR) * (strlenW(NameTcp)+1) :
77 WideCharToMultiByte( CP_ACP, 0, NameTcp, -1,
78 NULL, 0, NULL, NULL);
79 break;
80 case WS_IPPROTO_UDP :
81 dwLength = (unicode) ? sizeof(WCHAR) * (strlenW(NameUdp)+1) :
82 WideCharToMultiByte( CP_ACP, 0, NameUdp, -1,
83 NULL, 0, NULL, NULL);
84 break;
85 case NSPROTO_IPX :
86 dwLength = (unicode) ? sizeof(WCHAR) * (strlenW(NameIpx)+1) :
87 WideCharToMultiByte( CP_ACP, 0, NameIpx, -1,
88 NULL, 0, NULL, NULL);
89 break;
90 case NSPROTO_SPX :
91 dwLength = (unicode) ? sizeof(WCHAR) * (strlenW(NameSpx)+1) :
92 WideCharToMultiByte( CP_ACP, 0, NameSpx, -1,
93 NULL, 0, NULL, NULL);
94 break;
95 case NSPROTO_SPXII :
96 dwLength = (unicode) ? sizeof(WCHAR) * (strlenW(NameSpxII)+1) :
97 WideCharToMultiByte( CP_ACP, 0, NameSpxII, -1,
98 NULL, 0, NULL, NULL);
99 break;
100 default:
101 *lpSize = 0;
102 if ((iProtocol == ISOPROTO_TP4) || (iProtocol == NSPROTO_SPX))
103 FIXME("Protocol <%s> not implemented\n",
104 (iProtocol == ISOPROTO_TP4) ? "ISOPROTO_TP4" : "NSPROTO_SPX");
105 else
106 FIXME("unknown Protocol <0x%08x>\n", iProtocol);
107 break;
109 *lpSize += dwLength;
111 if ( !lpBuffer || !*lpSize || (*lpSize > dwOldSize))
112 return 0;
114 memset( lpBuffer, 0, dwOldSize);
116 lpBuffer->lpProtocol = (LPSTR) &lpBuffer[ iAnz];
117 lpBuffer->iProtocol = iProtocol;
119 switch (iProtocol) {
120 case WS_IPPROTO_TCP :
121 lpBuffer->dwServiceFlags = XP_FRAGMENTATION | XP_EXPEDITED_DATA |
122 XP_GRACEFUL_CLOSE | XP_GUARANTEED_ORDER |
123 XP_GUARANTEED_DELIVERY;
124 lpBuffer->iAddressFamily = WS_AF_INET;
125 lpBuffer->iMaxSockAddr = 0x10; /* NT4 SP5 */
126 lpBuffer->iMinSockAddr = 0x10; /* NT4 SP5 */
127 lpBuffer->iSocketType = SOCK_STREAM;
128 lpBuffer->dwMessageSize = 0;
129 lpProtName = NameTcp;
130 break;
131 case WS_IPPROTO_UDP :
132 lpBuffer->dwServiceFlags = XP_FRAGMENTATION | XP_SUPPORTS_BROADCAST |
133 XP_SUPPORTS_MULTICAST | XP_MESSAGE_ORIENTED |
134 XP_CONNECTIONLESS;
135 lpBuffer->iAddressFamily = WS_AF_INET;
136 lpBuffer->iMaxSockAddr = 0x10; /* NT4 SP5 */
137 lpBuffer->iMinSockAddr = 0x10; /* NT4 SP5 */
138 lpBuffer->iSocketType = SOCK_DGRAM;
139 lpBuffer->dwMessageSize = 65457; /* NT4 SP5 */
140 lpProtName = NameUdp;
141 break;
142 case NSPROTO_IPX :
143 lpBuffer->dwServiceFlags = XP_FRAGMENTATION | XP_SUPPORTS_BROADCAST |
144 XP_SUPPORTS_MULTICAST | XP_MESSAGE_ORIENTED |
145 XP_CONNECTIONLESS;
146 lpBuffer->iAddressFamily = WS_AF_IPX;
147 lpBuffer->iMaxSockAddr = 0x10; /* NT4 SP5 */
148 lpBuffer->iMinSockAddr = 0x0e; /* NT4 SP5 */
149 lpBuffer->iSocketType = SOCK_DGRAM;
150 lpBuffer->dwMessageSize = 576; /* NT4 SP5 */
151 lpProtName = NameIpx;
152 break;
153 case NSPROTO_SPX :
154 lpBuffer->dwServiceFlags = XP_FRAGMENTATION |
155 XP_PSEUDO_STREAM | XP_MESSAGE_ORIENTED |
156 XP_GUARANTEED_ORDER | XP_GUARANTEED_DELIVERY;
157 lpBuffer->iAddressFamily = WS_AF_IPX;
158 lpBuffer->iMaxSockAddr = 0x10; /* NT4 SP5 */
159 lpBuffer->iMinSockAddr = 0x0e; /* NT4 SP5 */
160 lpBuffer->iSocketType = 5;
161 lpBuffer->dwMessageSize = -1; /* NT4 SP5 */
162 lpProtName = NameSpx;
163 break;
164 case NSPROTO_SPXII :
165 lpBuffer->dwServiceFlags = XP_FRAGMENTATION | XP_GRACEFUL_CLOSE |
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 = NameSpxII;
174 break;
176 if (unicode)
177 strcpyW( (LPWSTR)lpBuffer->lpProtocol, lpProtName);
178 else
179 WideCharToMultiByte( CP_ACP, 0, lpProtName, -1, lpBuffer->lpProtocol,
180 dwOldSize - iAnz * sizeof( PROTOCOL_INFOA), NULL, NULL);
182 return iAnz;
185 /* FIXME: EnumProtocols should be moved to winsock2, and this should be
186 * implemented by calling out to WSAEnumProtocols. See:
187 * http://support.microsoft.com/support/kb/articles/Q129/3/15.asp
189 /*****************************************************************************
190 * WSOCK32_EnumProtocol [internal]
192 * Enters the information about installed protocols into a given buffer
194 * RETURNS
195 * SOCKET_ERROR if the buffer is to small for the requested protocol infos
196 * on success the number of protocols inside the buffer
198 * NOTE
199 * NT4SP5 does not return SPX if lpiProtocols == NULL
201 * BUGS
202 * - NT4SP5 returns in addition these list of NETBIOS protocols
203 * (address family 17), each entry two times one for socket type 2 and 5
205 * iProtocol lpProtocol
206 * 0x80000000 \Device\NwlnkNb
207 * 0xfffffffa \Device\NetBT_CBENT7
208 * 0xfffffffb \Device\Nbf_CBENT7
209 * 0xfffffffc \Device\NetBT_NdisWan5
210 * 0xfffffffd \Device\NetBT_El9202
211 * 0xfffffffe \Device\Nbf_El9202
212 * 0xffffffff \Device\Nbf_NdisWan4
214 * - there is no check that the operating system supports the returned
215 * protocols
217 static INT WSOCK32_EnumProtocol( LPINT lpiProtocols, PROTOCOL_INFOA* lpBuffer,
218 LPDWORD lpdwLength, BOOL unicode)
219 { DWORD dwCurSize, dwOldSize = *lpdwLength, dwTemp;
220 INT anz = 0, i;
221 INT iLocal[] = { WS_IPPROTO_TCP, WS_IPPROTO_UDP, NSPROTO_IPX, NSPROTO_SPXII, 0};
223 if (!lpiProtocols) lpiProtocols = iLocal;
225 *lpdwLength = 0;
226 while ( *lpiProtocols )
227 { dwCurSize = 0;
228 WSOCK32_EnterSingleProtocol( *lpiProtocols, NULL, &dwCurSize, unicode);
230 if ( lpBuffer && dwCurSize && ((*lpdwLength + dwCurSize) <= dwOldSize))
231 { /* reserve the required space for the current protocol_info after the
232 * last protocol_info before the start of the string buffer and adjust
233 * the references into the string buffer
235 memmove( &((char*)&lpBuffer[ anz])[dwCurSize],
236 &lpBuffer[ anz],
237 *lpdwLength - anz * sizeof( PROTOCOL_INFOA));
238 for (i=0; i < anz; i++)
239 lpBuffer[i].lpProtocol += dwCurSize;
241 dwTemp = dwCurSize;
242 anz += WSOCK32_EnterSingleProtocol( *lpiProtocols, &lpBuffer[anz],
243 &dwTemp, unicode);
246 *lpdwLength += dwCurSize;
247 lpiProtocols++;
250 if (dwOldSize < *lpdwLength) anz = SOCKET_ERROR;
252 return anz;
255 /*****************************************************************************
256 * EnumProtocolsA [WSOCK32.1111]
258 * see function WSOCK32_EnumProtocol for RETURNS, BUGS
260 INT WINAPI EnumProtocolsA( LPINT lpiProtocols, LPVOID lpBuffer,
261 LPDWORD lpdwLength)
263 return WSOCK32_EnumProtocol( lpiProtocols, (PROTOCOL_INFOA*) lpBuffer,
264 lpdwLength, FALSE);
267 /*****************************************************************************
268 * EnumProtocolsW [WSOCK32.1112]
270 * see function WSOCK32_EnumProtocol for RETURNS, BUGS
272 INT WINAPI EnumProtocolsW( LPINT lpiProtocols, LPVOID lpBuffer,
273 LPDWORD lpdwLength)
275 return WSOCK32_EnumProtocol( lpiProtocols, (PROTOCOL_INFOA*) lpBuffer,
276 lpdwLength, TRUE);
279 /*****************************************************************************
280 * inet_network [WSOCK32.1100]
282 UINT WINAPI WSOCK32_inet_network(const char *cp)
284 return inet_network(cp);
287 /*****************************************************************************
288 * getnetbyname [WSOCK32.1101]
290 struct netent * WINAPI WSOCK32_getnetbyname(const char *name)
292 return getnetbyname(name);