Rewrite msvcrt_{argvtos,valisttos} to be more efficient.
[wine/gsoc_dplay.git] / dlls / wsock32 / protocol.c
blob5b819f1dbc43699fd74b1f6eff12a37a051e07be
1 /*
2 * WSOCK32 specific functions
4 * Copyright (C) 2001 Stefan Leichter
5 */
7 #include "config.h"
9 #include <stdio.h>
10 #include <string.h>
11 #include "winbase.h"
12 #include "winnls.h"
13 #include "wine/unicode.h"
14 #include "nspapi.h"
15 #include "winsock2.h"
16 #include "wsipx.h"
17 #include "wshisotp.h"
19 #include "debugtools.h"
21 DEFAULT_DEBUG_CHANNEL(winsock);
23 /* name of the protocols
25 static WCHAR NameIpx[] = {'I', 'P', 'X', '\0'};
26 static WCHAR NameSpx[] = {'S', 'P', 'X', '\0'};
27 static WCHAR NameSpxII[] = {'S', 'P', 'X', ' ', 'I', 'I', '\0'};
28 static WCHAR NameTcp[] = {'T', 'C', 'P', '/', 'I', 'P', '\0'};
29 static WCHAR NameUdp[] = {'U', 'D', 'P', '/', 'I', 'P', '\0'};
31 /*****************************************************************************
32 * WSOCK32_EnterSingleProtocol [internal]
34 * enters the protocol informations of one given protocol into the
35 * given buffer. If the given buffer is too small only the required size for
36 * the protocols are returned.
38 * RETURNS
39 * The number of protocols entered into the buffer
41 * BUGS
42 * - only implemented for IPX, SPX, SPXII, TCP, UDP
43 * - there is no check that the operating system supports the returned
44 * protocols
46 static INT WSOCK32_EnterSingleProtocol( INT iProtocol,
47 PROTOCOL_INFOA* lpBuffer,
48 LPDWORD lpSize, BOOL unicode)
49 { DWORD dwLength = 0, dwOldSize = *lpSize;
50 INT iAnz = 1;
51 WCHAR *lpProtName = NULL;
53 *lpSize = sizeof( PROTOCOL_INFOA);
54 switch (iProtocol) {
55 case IPPROTO_TCP :
56 dwLength = (unicode) ? sizeof(WCHAR) * (strlenW(NameTcp)+1) :
57 WideCharToMultiByte( CP_ACP, 0, NameTcp, -1,
58 NULL, 0, NULL, NULL);
59 break;
60 case IPPROTO_UDP :
61 dwLength = (unicode) ? sizeof(WCHAR) * (strlenW(NameUdp)+1) :
62 WideCharToMultiByte( CP_ACP, 0, NameUdp, -1,
63 NULL, 0, NULL, NULL);
64 break;
65 case NSPROTO_IPX :
66 dwLength = (unicode) ? sizeof(WCHAR) * (strlenW(NameIpx)+1) :
67 WideCharToMultiByte( CP_ACP, 0, NameIpx, -1,
68 NULL, 0, NULL, NULL);
69 break;
70 case NSPROTO_SPX :
71 dwLength = (unicode) ? sizeof(WCHAR) * (strlenW(NameSpx)+1) :
72 WideCharToMultiByte( CP_ACP, 0, NameSpx, -1,
73 NULL, 0, NULL, NULL);
74 break;
75 case NSPROTO_SPXII :
76 dwLength = (unicode) ? sizeof(WCHAR) * (strlenW(NameSpxII)+1) :
77 WideCharToMultiByte( CP_ACP, 0, NameSpxII, -1,
78 NULL, 0, NULL, NULL);
79 break;
80 default:
81 *lpSize = 0;
82 if ((iProtocol == ISOPROTO_TP4) || (iProtocol == NSPROTO_SPX))
83 FIXME("Protocol <%s> not implemented\n",
84 (iProtocol == ISOPROTO_TP4) ? "ISOPROTO_TP4" : "NSPROTO_SPX");
85 else
86 FIXME("unknown Protocol <0x%08x>\n", iProtocol);
87 break;
89 *lpSize += dwLength;
91 if ( !lpBuffer || !*lpSize || (*lpSize > dwOldSize))
92 return 0;
94 memset( lpBuffer, 0, dwOldSize);
96 lpBuffer->lpProtocol = (LPSTR) &lpBuffer[ iAnz];
97 lpBuffer->iProtocol = iProtocol;
99 switch (iProtocol) {
100 case IPPROTO_TCP :
101 lpBuffer->dwServiceFlags = XP_FRAGMENTATION | XP_EXPEDITED_DATA |
102 XP_GRACEFUL_CLOSE | XP_GUARANTEED_ORDER |
103 XP_GUARANTEED_DELIVERY;
104 lpBuffer->iAddressFamily = WS_AF_INET;
105 lpBuffer->iMaxSockAddr = 0x10; /* NT4 SP5 */
106 lpBuffer->iMinSockAddr = 0x10; /* NT4 SP5 */
107 lpBuffer->iSocketType = SOCK_STREAM;
108 lpBuffer->dwMessageSize = 0;
109 lpProtName = NameTcp;
110 break;
111 case IPPROTO_UDP :
112 lpBuffer->dwServiceFlags = XP_FRAGMENTATION | XP_SUPPORTS_BROADCAST |
113 XP_SUPPORTS_MULTICAST | XP_MESSAGE_ORIENTED |
114 XP_CONNECTIONLESS;
115 lpBuffer->iAddressFamily = WS_AF_INET;
116 lpBuffer->iMaxSockAddr = 0x10; /* NT4 SP5 */
117 lpBuffer->iMinSockAddr = 0x10; /* NT4 SP5 */
118 lpBuffer->iSocketType = SOCK_DGRAM;
119 lpBuffer->dwMessageSize = 65457; /* NT4 SP5 */
120 lpProtName = NameUdp;
121 break;
122 case NSPROTO_IPX :
123 lpBuffer->dwServiceFlags = XP_FRAGMENTATION | XP_SUPPORTS_BROADCAST |
124 XP_SUPPORTS_MULTICAST | XP_MESSAGE_ORIENTED |
125 XP_CONNECTIONLESS;
126 lpBuffer->iAddressFamily = WS_AF_IPX;
127 lpBuffer->iMaxSockAddr = 0x10; /* NT4 SP5 */
128 lpBuffer->iMinSockAddr = 0x0e; /* NT4 SP5 */
129 lpBuffer->iSocketType = SOCK_DGRAM;
130 lpBuffer->dwMessageSize = 576; /* NT4 SP5 */
131 lpProtName = NameIpx;
132 break;
133 case NSPROTO_SPX :
134 lpBuffer->dwServiceFlags = XP_FRAGMENTATION |
135 XP_PSEUDO_STREAM | XP_MESSAGE_ORIENTED |
136 XP_GUARANTEED_ORDER | XP_GUARANTEED_DELIVERY;
137 lpBuffer->iAddressFamily = WS_AF_IPX;
138 lpBuffer->iMaxSockAddr = 0x10; /* NT4 SP5 */
139 lpBuffer->iMinSockAddr = 0x0e; /* NT4 SP5 */
140 lpBuffer->iSocketType = 5;
141 lpBuffer->dwMessageSize = -1; /* NT4 SP5 */
142 lpProtName = NameSpx;
143 break;
144 case NSPROTO_SPXII :
145 lpBuffer->dwServiceFlags = XP_FRAGMENTATION | XP_GRACEFUL_CLOSE |
146 XP_PSEUDO_STREAM | XP_MESSAGE_ORIENTED |
147 XP_GUARANTEED_ORDER | XP_GUARANTEED_DELIVERY;
148 lpBuffer->iAddressFamily = WS_AF_IPX;
149 lpBuffer->iMaxSockAddr = 0x10; /* NT4 SP5 */
150 lpBuffer->iMinSockAddr = 0x0e; /* NT4 SP5 */
151 lpBuffer->iSocketType = 5;
152 lpBuffer->dwMessageSize = -1; /* NT4 SP5 */
153 lpProtName = NameSpxII;
154 break;
156 if (unicode)
157 strcpyW( (LPWSTR)lpBuffer->lpProtocol, lpProtName);
158 else
159 WideCharToMultiByte( CP_ACP, 0, lpProtName, -1, lpBuffer->lpProtocol,
160 dwOldSize - iAnz * sizeof( PROTOCOL_INFOA), NULL, NULL);
162 return iAnz;
165 /*****************************************************************************
166 * WSOCK32_EnumProtocol [internal]
168 * Enters the information about installed protocols into a given buffer
170 * RETURNS
171 * SOCKET_ERROR if the buffer is to small for the requested protocol infos
172 * on success the number of protocols inside the buffer
174 * NOTE
175 * NT4SP5 does not return SPX if lpiProtocols == NULL
177 * BUGS
178 * - NT4SP5 returns in addition these list of NETBIOS protocols
179 * (address family 17), each entry two times one for socket type 2 and 5
181 * iProtocol lpProtocol
182 * 0x80000000 \Device\NwlnkNb
183 * 0xfffffffa \Device\NetBT_CBENT7
184 * 0xfffffffb \Device\Nbf_CBENT7
185 * 0xfffffffc \Device\NetBT_NdisWan5
186 * 0xfffffffd \Device\NetBT_El9202
187 * 0xfffffffe \Device\Nbf_El9202
188 * 0xffffffff \Device\Nbf_NdisWan4
190 * - there is no check that the operating system supports the returned
191 * protocols
193 static INT WSOCK32_EnumProtocol( LPINT lpiProtocols, PROTOCOL_INFOA* lpBuffer,
194 LPDWORD lpdwLength, BOOL unicode)
195 { DWORD dwCurSize, dwOldSize = *lpdwLength, dwTemp;
196 INT anz = 0, i;
197 INT iLocal[] = { IPPROTO_TCP, IPPROTO_UDP, NSPROTO_IPX, NSPROTO_SPXII, 0};
199 if (!lpiProtocols) lpiProtocols = iLocal;
201 *lpdwLength = 0;
202 while ( *lpiProtocols )
203 { dwCurSize = 0;
204 WSOCK32_EnterSingleProtocol( *lpiProtocols, NULL, &dwCurSize, unicode);
206 if ( lpBuffer && dwCurSize && ((*lpdwLength + dwCurSize) <= dwOldSize))
207 { /* reserve the required space for the current protocol_info after the
208 * last protocol_info before the start of the string buffer and adjust
209 * the references into the string buffer
211 memmove( &((char*)&lpBuffer[ anz])[dwCurSize],
212 &lpBuffer[ anz],
213 *lpdwLength - anz * sizeof( PROTOCOL_INFOA));
214 for (i=0; i < anz; i++)
215 lpBuffer[i].lpProtocol += dwCurSize;
217 dwTemp = dwCurSize;
218 anz += WSOCK32_EnterSingleProtocol( *lpiProtocols, &lpBuffer[anz],
219 &dwTemp, unicode);
222 *lpdwLength += dwCurSize;
223 lpiProtocols++;
226 if (dwOldSize < *lpdwLength) anz = SOCKET_ERROR;
228 return anz;
231 /*****************************************************************************
232 * EnumProtocolsA [WSOCK32.1111]
234 * see function WSOCK32_EnumProtocol for RETURNS, BUGS
236 INT WINAPI EnumProtocolsA( LPINT lpiProtocols, LPVOID lpBuffer,
237 LPDWORD lpdwLength)
239 return WSOCK32_EnumProtocol( lpiProtocols, (PROTOCOL_INFOA*) lpBuffer,
240 lpdwLength, FALSE);
243 /*****************************************************************************
244 * EnumProtocolsW [WSOCK32.1112]
246 * see function WSOCK32_EnumProtocol for RETURNS, BUGS
248 INT WINAPI EnumProtocolsW( LPINT lpiProtocols, LPVOID lpBuffer,
249 LPDWORD lpdwLength)
251 return WSOCK32_EnumProtocol( lpiProtocols, (PROTOCOL_INFOA*) lpBuffer,
252 lpdwLength, TRUE);
255 /*****************************************************************************
256 * inet_network [WSOCK32.1100]
258 UINT WINAPI WSOCK32_inet_network(const char *cp)
260 return inet_network(cp);
263 /*****************************************************************************
264 * getnetbyname [WSOCK32.1101]
266 struct netent * WINAPI WSOCK32_getnetbyname(const char *name)
268 return getnetbyname(name);