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