Increase debug buffer size up to 1024 bytes.
[wine.git] / dlls / wsock32 / protocol.c
blob8432bffa87fa9204469124e34ae2b0f25611e18a
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 "debugtools.h"
13 #include "heap.h"
14 #include "nspapi.h"
15 #include "winsock.h"
16 #include "wsipx.h"
17 #include "wshisotp.h"
19 DEFAULT_DEBUG_CHANNEL(winsock);
21 /* name of the protocols
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'};
29 /*****************************************************************************
30 * WSOCK32_EnterSingleProtocol [internal]
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.
36 * RETURNS
37 * The number of protocols entered into the buffer
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
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;
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;
87 *lpSize += dwLength;
89 if ( !lpBuffer || !*lpSize || (*lpSize > dwOldSize))
90 return 0;
92 memset( lpBuffer, 0, dwOldSize);
94 lpBuffer->lpProtocol = (LPSTR) &lpBuffer[ iAnz];
95 lpBuffer->iProtocol = iProtocol;
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;
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);
160 return iAnz;
163 /*****************************************************************************
164 * WSOCK32_EnumProtocol [internal]
166 * Enters the information about installed protocols into a given buffer
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
172 * NOTE
173 * NT4SP5 does not return SPX if lpiProtocols == NULL
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
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
188 * - there is no check that the operating system supports the returned
189 * protocols
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};
197 if (!lpiProtocols) lpiProtocols = iLocal;
199 *lpdwLength = 0;
200 while ( *lpiProtocols )
201 { dwCurSize = 0;
202 WSOCK32_EnterSingleProtocol( *lpiProtocols, NULL, &dwCurSize, unicode);
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
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;
215 dwTemp = dwCurSize;
216 anz += WSOCK32_EnterSingleProtocol( *lpiProtocols, &lpBuffer[anz],
217 &dwTemp, unicode);
220 *lpdwLength += dwCurSize;
221 lpiProtocols++;
224 if (dwOldSize < *lpdwLength) anz = SOCKET_ERROR;
226 return anz;
229 /*****************************************************************************
230 * EnumProtocolsA [WSOCK32.1111]
232 * see function WSOCK32_EnumProtocol for RETURNS, BUGS
234 INT WINAPI EnumProtocolsA( LPINT lpiProtocols, LPVOID lpBuffer,
235 LPDWORD lpdwLength)
237 return WSOCK32_EnumProtocol( lpiProtocols, (PROTOCOL_INFOA*) lpBuffer,
238 lpdwLength, FALSE);
241 /*****************************************************************************
242 * EnumProtocolsW [WSOCK32.1112]
244 * see function WSOCK32_EnumProtocol for RETURNS, BUGS
246 INT WINAPI EnumProtocolsW( LPINT lpiProtocols, LPVOID lpBuffer,
247 LPDWORD lpdwLength)
249 return WSOCK32_EnumProtocol( lpiProtocols, (PROTOCOL_INFOA*) lpBuffer,
250 lpdwLength, TRUE);