Split signal blocking code out of SIGNAL_Reset into SIGNAL_Block.
[wine/multimedia.git] / dlls / wsock32 / protocol.c
blobd1f4abb0b7f0ee9907dd1d476a875a0a197622ef
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 <stdio.h>
29 #include <string.h>
31 #include <sys/types.h>
32 #ifdef HAVE_SYS_SOCKET_H
33 #include <sys/socket.h>
34 #endif
35 #ifdef HAVE_NETINET_IN_H
36 # include <netinet/in.h>
37 #endif
38 #ifdef HAVE_ARPA_INET_H
39 #include <arpa/inet.h>
40 #endif
41 #ifdef HAVE_NETDB_H
42 #include <netdb.h>
43 #endif
45 #include "winbase.h"
46 #include "winnls.h"
47 #include "wtypes.h"
48 #include "nspapi.h"
49 #include "winsock2.h"
50 #include "wsipx.h"
51 #include "wshisotp.h"
53 #include "wine/unicode.h"
54 #include "wine/debug.h"
56 WINE_DEFAULT_DEBUG_CHANNEL(winsock);
58 /* name of the protocols
60 static WCHAR NameIpx[] = {'I', 'P', 'X', '\0'};
61 static WCHAR NameSpx[] = {'S', 'P', 'X', '\0'};
62 static WCHAR NameSpxII[] = {'S', 'P', 'X', ' ', 'I', 'I', '\0'};
63 static WCHAR NameTcp[] = {'T', 'C', 'P', '/', 'I', 'P', '\0'};
64 static WCHAR NameUdp[] = {'U', 'D', 'P', '/', 'I', 'P', '\0'};
66 /*****************************************************************************
67 * WSOCK32_EnterSingleProtocol [internal]
69 * enters the protocol informations of one given protocol into the
70 * given buffer. If the given buffer is too small only the required size for
71 * the protocols are returned.
73 * RETURNS
74 * The number of protocols entered into the buffer
76 * BUGS
77 * - only implemented for IPX, SPX, SPXII, TCP, UDP
78 * - there is no check that the operating system supports the returned
79 * protocols
81 static INT WSOCK32_EnterSingleProtocol( INT iProtocol,
82 PROTOCOL_INFOA* lpBuffer,
83 LPDWORD lpSize, BOOL unicode)
84 { DWORD dwLength = 0, dwOldSize = *lpSize;
85 INT iAnz = 1;
86 WCHAR *lpProtName = NULL;
88 *lpSize = sizeof( PROTOCOL_INFOA);
89 switch (iProtocol) {
90 case WS_IPPROTO_TCP :
91 dwLength = (unicode) ? sizeof(WCHAR) * (strlenW(NameTcp)+1) :
92 WideCharToMultiByte( CP_ACP, 0, NameTcp, -1,
93 NULL, 0, NULL, NULL);
94 break;
95 case WS_IPPROTO_UDP :
96 dwLength = (unicode) ? sizeof(WCHAR) * (strlenW(NameUdp)+1) :
97 WideCharToMultiByte( CP_ACP, 0, NameUdp, -1,
98 NULL, 0, NULL, NULL);
99 break;
100 case NSPROTO_IPX :
101 dwLength = (unicode) ? sizeof(WCHAR) * (strlenW(NameIpx)+1) :
102 WideCharToMultiByte( CP_ACP, 0, NameIpx, -1,
103 NULL, 0, NULL, NULL);
104 break;
105 case NSPROTO_SPX :
106 dwLength = (unicode) ? sizeof(WCHAR) * (strlenW(NameSpx)+1) :
107 WideCharToMultiByte( CP_ACP, 0, NameSpx, -1,
108 NULL, 0, NULL, NULL);
109 break;
110 case NSPROTO_SPXII :
111 dwLength = (unicode) ? sizeof(WCHAR) * (strlenW(NameSpxII)+1) :
112 WideCharToMultiByte( CP_ACP, 0, NameSpxII, -1,
113 NULL, 0, NULL, NULL);
114 break;
115 default:
116 *lpSize = 0;
117 if ((iProtocol == ISOPROTO_TP4) || (iProtocol == NSPROTO_SPX))
118 FIXME("Protocol <%s> not implemented\n",
119 (iProtocol == ISOPROTO_TP4) ? "ISOPROTO_TP4" : "NSPROTO_SPX");
120 else
121 FIXME("unknown Protocol <0x%08x>\n", iProtocol);
122 break;
124 *lpSize += dwLength;
126 if ( !lpBuffer || !*lpSize || (*lpSize > dwOldSize))
127 return 0;
129 memset( lpBuffer, 0, dwOldSize);
131 lpBuffer->lpProtocol = (LPSTR) &lpBuffer[ iAnz];
132 lpBuffer->iProtocol = iProtocol;
134 switch (iProtocol) {
135 case WS_IPPROTO_TCP :
136 lpBuffer->dwServiceFlags = XP_FRAGMENTATION | XP_EXPEDITED_DATA |
137 XP_GRACEFUL_CLOSE | XP_GUARANTEED_ORDER |
138 XP_GUARANTEED_DELIVERY;
139 lpBuffer->iAddressFamily = WS_AF_INET;
140 lpBuffer->iMaxSockAddr = 0x10; /* NT4 SP5 */
141 lpBuffer->iMinSockAddr = 0x10; /* NT4 SP5 */
142 lpBuffer->iSocketType = SOCK_STREAM;
143 lpBuffer->dwMessageSize = 0;
144 lpProtName = NameTcp;
145 break;
146 case WS_IPPROTO_UDP :
147 lpBuffer->dwServiceFlags = XP_FRAGMENTATION | XP_SUPPORTS_BROADCAST |
148 XP_SUPPORTS_MULTICAST | XP_MESSAGE_ORIENTED |
149 XP_CONNECTIONLESS;
150 lpBuffer->iAddressFamily = WS_AF_INET;
151 lpBuffer->iMaxSockAddr = 0x10; /* NT4 SP5 */
152 lpBuffer->iMinSockAddr = 0x10; /* NT4 SP5 */
153 lpBuffer->iSocketType = SOCK_DGRAM;
154 lpBuffer->dwMessageSize = 65457; /* NT4 SP5 */
155 lpProtName = NameUdp;
156 break;
157 case NSPROTO_IPX :
158 lpBuffer->dwServiceFlags = XP_FRAGMENTATION | XP_SUPPORTS_BROADCAST |
159 XP_SUPPORTS_MULTICAST | XP_MESSAGE_ORIENTED |
160 XP_CONNECTIONLESS;
161 lpBuffer->iAddressFamily = WS_AF_IPX;
162 lpBuffer->iMaxSockAddr = 0x10; /* NT4 SP5 */
163 lpBuffer->iMinSockAddr = 0x0e; /* NT4 SP5 */
164 lpBuffer->iSocketType = SOCK_DGRAM;
165 lpBuffer->dwMessageSize = 576; /* NT4 SP5 */
166 lpProtName = NameIpx;
167 break;
168 case NSPROTO_SPX :
169 lpBuffer->dwServiceFlags = XP_FRAGMENTATION |
170 XP_PSEUDO_STREAM | XP_MESSAGE_ORIENTED |
171 XP_GUARANTEED_ORDER | XP_GUARANTEED_DELIVERY;
172 lpBuffer->iAddressFamily = WS_AF_IPX;
173 lpBuffer->iMaxSockAddr = 0x10; /* NT4 SP5 */
174 lpBuffer->iMinSockAddr = 0x0e; /* NT4 SP5 */
175 lpBuffer->iSocketType = 5;
176 lpBuffer->dwMessageSize = -1; /* NT4 SP5 */
177 lpProtName = NameSpx;
178 break;
179 case NSPROTO_SPXII :
180 lpBuffer->dwServiceFlags = XP_FRAGMENTATION | XP_GRACEFUL_CLOSE |
181 XP_PSEUDO_STREAM | XP_MESSAGE_ORIENTED |
182 XP_GUARANTEED_ORDER | XP_GUARANTEED_DELIVERY;
183 lpBuffer->iAddressFamily = WS_AF_IPX;
184 lpBuffer->iMaxSockAddr = 0x10; /* NT4 SP5 */
185 lpBuffer->iMinSockAddr = 0x0e; /* NT4 SP5 */
186 lpBuffer->iSocketType = 5;
187 lpBuffer->dwMessageSize = -1; /* NT4 SP5 */
188 lpProtName = NameSpxII;
189 break;
191 if (unicode)
192 strcpyW( (LPWSTR)lpBuffer->lpProtocol, lpProtName);
193 else
194 WideCharToMultiByte( CP_ACP, 0, lpProtName, -1, lpBuffer->lpProtocol,
195 dwOldSize - iAnz * sizeof( PROTOCOL_INFOA), NULL, NULL);
197 return iAnz;
200 /* FIXME: EnumProtocols should be moved to winsock2, and this should be
201 * implemented by calling out to WSAEnumProtocols. See:
202 * http://support.microsoft.com/support/kb/articles/Q129/3/15.asp
204 /*****************************************************************************
205 * WSOCK32_EnumProtocol [internal]
207 * Enters the information about installed protocols into a given buffer
209 * RETURNS
210 * SOCKET_ERROR if the buffer is to small for the requested protocol infos
211 * on success the number of protocols inside the buffer
213 * NOTE
214 * NT4SP5 does not return SPX if lpiProtocols == NULL
216 * BUGS
217 * - NT4SP5 returns in addition these list of NETBIOS protocols
218 * (address family 17), each entry two times one for socket type 2 and 5
220 * iProtocol lpProtocol
221 * 0x80000000 \Device\NwlnkNb
222 * 0xfffffffa \Device\NetBT_CBENT7
223 * 0xfffffffb \Device\Nbf_CBENT7
224 * 0xfffffffc \Device\NetBT_NdisWan5
225 * 0xfffffffd \Device\NetBT_El9202
226 * 0xfffffffe \Device\Nbf_El9202
227 * 0xffffffff \Device\Nbf_NdisWan4
229 * - there is no check that the operating system supports the returned
230 * protocols
232 static INT WSOCK32_EnumProtocol( LPINT lpiProtocols, PROTOCOL_INFOA* lpBuffer,
233 LPDWORD lpdwLength, BOOL unicode)
234 { DWORD dwCurSize, dwOldSize = *lpdwLength, dwTemp;
235 INT anz = 0, i;
236 INT iLocal[] = { WS_IPPROTO_TCP, WS_IPPROTO_UDP, NSPROTO_IPX, NSPROTO_SPXII, 0};
238 if (!lpiProtocols) lpiProtocols = iLocal;
240 *lpdwLength = 0;
241 while ( *lpiProtocols )
242 { dwCurSize = 0;
243 WSOCK32_EnterSingleProtocol( *lpiProtocols, NULL, &dwCurSize, unicode);
245 if ( lpBuffer && dwCurSize && ((*lpdwLength + dwCurSize) <= dwOldSize))
246 { /* reserve the required space for the current protocol_info after the
247 * last protocol_info before the start of the string buffer and adjust
248 * the references into the string buffer
250 memmove( &((char*)&lpBuffer[ anz])[dwCurSize],
251 &lpBuffer[ anz],
252 *lpdwLength - anz * sizeof( PROTOCOL_INFOA));
253 for (i=0; i < anz; i++)
254 lpBuffer[i].lpProtocol += dwCurSize;
256 dwTemp = dwCurSize;
257 anz += WSOCK32_EnterSingleProtocol( *lpiProtocols, &lpBuffer[anz],
258 &dwTemp, unicode);
261 *lpdwLength += dwCurSize;
262 lpiProtocols++;
265 if (dwOldSize < *lpdwLength) anz = SOCKET_ERROR;
267 return anz;
270 /*****************************************************************************
271 * EnumProtocolsA [WSOCK32.1111]
273 * see function WSOCK32_EnumProtocol for RETURNS, BUGS
275 INT WINAPI EnumProtocolsA( LPINT lpiProtocols, LPVOID lpBuffer,
276 LPDWORD lpdwLength)
278 return WSOCK32_EnumProtocol( lpiProtocols, (PROTOCOL_INFOA*) lpBuffer,
279 lpdwLength, FALSE);
282 /*****************************************************************************
283 * EnumProtocolsW [WSOCK32.1112]
285 * see function WSOCK32_EnumProtocol for RETURNS, BUGS
287 INT WINAPI EnumProtocolsW( LPINT lpiProtocols, LPVOID lpBuffer,
288 LPDWORD lpdwLength)
290 return WSOCK32_EnumProtocol( lpiProtocols, (PROTOCOL_INFOA*) lpBuffer,
291 lpdwLength, TRUE);
294 /*****************************************************************************
295 * inet_network [WSOCK32.1100]
297 UINT WINAPI WSOCK32_inet_network(const char *cp)
299 #ifdef HAVE_INET_NETWORK
300 return inet_network(cp);
301 #else
302 return 0;
303 #endif
306 /*****************************************************************************
307 * getnetbyname [WSOCK32.1101]
309 struct netent * WINAPI WSOCK32_getnetbyname(const char *name)
311 #ifdef HAVE_GETNETBYNAME
312 return getnetbyname(name);
313 #else
314 return NULL;
315 #endif