wineqtdecoder: Use the ARRAY_SIZE() macro.
[wine.git] / dlls / wsock32 / protocol.c
blob16109e38577b2147182dffc0b2c565dbd85ed4c8
1 /*
2 * WSOCK32 specific functions
4 * Copyright (C) 2001 Stefan Leichter
5 * Copyright (C) 2008 Hans Leidekker
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
22 #define USE_WS_PREFIX
24 #include "config.h"
26 #include <stdarg.h>
27 #include <stdio.h>
28 #include <string.h>
30 #ifdef HAVE_ARPA_INET_H
31 #include <arpa/inet.h>
32 #endif
33 #ifdef HAVE_NETDB_H
34 #include <netdb.h>
35 #endif
37 #include "windef.h"
38 #include "winbase.h"
39 #include "winsock2.h"
40 #include "nspapi.h"
42 #include "wine/debug.h"
43 #include "wine/unicode.h"
45 WINE_DEFAULT_DEBUG_CHANNEL(winsock);
47 /*****************************************************************************
48 * inet_network [WSOCK32.1100]
50 UINT WINAPI WSOCK32_inet_network(const char *cp)
52 #ifdef HAVE_INET_NETWORK
53 return inet_network(cp);
54 #elif defined(HAVE_INET_ADDR)
55 return ntohl( inet_addr( cp ) );
56 #else
57 return 0;
58 #endif
61 /*****************************************************************************
62 * getnetbyname [WSOCK32.1101]
64 struct netent * WINAPI WSOCK32_getnetbyname(const char *name)
66 #ifdef HAVE_GETNETBYNAME
67 return getnetbyname(name);
68 #else
69 return NULL;
70 #endif
73 static DWORD map_service(DWORD wsaflags)
75 DWORD flags = 0;
77 if (wsaflags & XP1_CONNECTIONLESS) flags |= XP_CONNECTIONLESS;
78 if (wsaflags & XP1_GUARANTEED_DELIVERY) flags |= XP_GUARANTEED_DELIVERY;
79 if (wsaflags & XP1_GUARANTEED_ORDER) flags |= XP_GUARANTEED_ORDER;
80 if (wsaflags & XP1_MESSAGE_ORIENTED) flags |= XP_MESSAGE_ORIENTED;
81 if (wsaflags & XP1_PSEUDO_STREAM) flags |= XP_PSEUDO_STREAM;
82 if (wsaflags & XP1_GRACEFUL_CLOSE) flags |= XP_GRACEFUL_CLOSE;
83 if (wsaflags & XP1_EXPEDITED_DATA) flags |= XP_EXPEDITED_DATA;
84 if (wsaflags & XP1_CONNECT_DATA) flags |= XP_CONNECT_DATA;
85 if (wsaflags & XP1_DISCONNECT_DATA) flags |= XP_DISCONNECT_DATA;
86 if (wsaflags & XP1_SUPPORT_BROADCAST) flags |= XP_SUPPORTS_BROADCAST;
87 if (wsaflags & XP1_SUPPORT_MULTIPOINT) flags |= XP_SUPPORTS_MULTICAST;
88 if (wsaflags & XP1_QOS_SUPPORTED) flags |= XP_BANDWIDTH_ALLOCATION;
89 if (wsaflags & XP1_PARTIAL_MESSAGE) flags |= XP_FRAGMENTATION;
90 return flags;
93 /*****************************************************************************
94 * EnumProtocolsA [WSOCK32.1111]
96 INT WINAPI EnumProtocolsA(LPINT protocols, LPVOID buffer, LPDWORD buflen)
98 INT ret;
99 DWORD size, string_size = WSAPROTOCOL_LEN + 1;
101 TRACE("%p, %p, %p\n", protocols, buffer, buflen);
103 if (!buflen) return SOCKET_ERROR;
105 size = 0;
106 ret = WSAEnumProtocolsA(protocols, NULL, &size);
108 if (ret == SOCKET_ERROR && WSAGetLastError() == WSAENOBUFS)
110 DWORD num_protocols = size / sizeof(WSAPROTOCOL_INFOA);
111 if (*buflen < num_protocols * (sizeof(PROTOCOL_INFOA) + string_size))
113 *buflen = num_protocols * (sizeof(PROTOCOL_INFOA) + string_size);
114 return SOCKET_ERROR;
116 if (buffer)
118 WSAPROTOCOL_INFOA *wsabuf;
119 PROTOCOL_INFOA *pi = buffer;
120 unsigned int string_offset;
121 INT i;
123 if (!(wsabuf = HeapAlloc(GetProcessHeap(), 0, size))) return SOCKET_ERROR;
125 ret = WSAEnumProtocolsA(protocols, wsabuf, &size);
126 string_offset = ret * sizeof(PROTOCOL_INFOA);
128 for (i = 0; i < ret; i++)
130 pi[i].dwServiceFlags = map_service(wsabuf[i].dwServiceFlags1);
131 pi[i].iAddressFamily = wsabuf[i].iAddressFamily;
132 pi[i].iMaxSockAddr = wsabuf[i].iMaxSockAddr;
133 pi[i].iMinSockAddr = wsabuf[i].iMinSockAddr;
134 pi[i].iSocketType = wsabuf[i].iSocketType;
135 pi[i].iProtocol = wsabuf[i].iProtocol;
136 pi[i].dwMessageSize = wsabuf[i].dwMessageSize;
138 memcpy((char *)buffer + string_offset, wsabuf[i].szProtocol, string_size);
139 pi[i].lpProtocol = (char *)buffer + string_offset;
140 string_offset += string_size;
142 HeapFree(GetProcessHeap(), 0, wsabuf);
145 return ret;
148 /*****************************************************************************
149 * EnumProtocolsW [WSOCK32.1112]
151 INT WINAPI EnumProtocolsW(LPINT protocols, LPVOID buffer, LPDWORD buflen)
153 INT ret;
154 DWORD size, string_size = (WSAPROTOCOL_LEN + 1) * sizeof(WCHAR);
156 TRACE("%p, %p, %p\n", protocols, buffer, buflen);
158 if (!buflen) return SOCKET_ERROR;
160 size = 0;
161 ret = WSAEnumProtocolsW(protocols, NULL, &size);
163 if (ret == SOCKET_ERROR && WSAGetLastError() == WSAENOBUFS)
165 DWORD num_protocols = size / sizeof(WSAPROTOCOL_INFOW);
166 if (*buflen < num_protocols * (sizeof(PROTOCOL_INFOW) + string_size))
168 *buflen = num_protocols * (sizeof(PROTOCOL_INFOW) + string_size);
169 return SOCKET_ERROR;
171 if (buffer)
173 WSAPROTOCOL_INFOW *wsabuf;
174 PROTOCOL_INFOW *pi = buffer;
175 unsigned int string_offset;
176 INT i;
178 if (!(wsabuf = HeapAlloc(GetProcessHeap(), 0, size))) return SOCKET_ERROR;
180 ret = WSAEnumProtocolsW(protocols, wsabuf, &size);
181 string_offset = ret * sizeof(PROTOCOL_INFOW);
183 for (i = 0; i < ret; i++)
185 pi[i].dwServiceFlags = map_service(wsabuf[i].dwServiceFlags1);
186 pi[i].iAddressFamily = wsabuf[i].iAddressFamily;
187 pi[i].iMaxSockAddr = wsabuf[i].iMaxSockAddr;
188 pi[i].iMinSockAddr = wsabuf[i].iMinSockAddr;
189 pi[i].iSocketType = wsabuf[i].iSocketType;
190 pi[i].iProtocol = wsabuf[i].iProtocol;
191 pi[i].dwMessageSize = wsabuf[i].dwMessageSize;
193 memcpy((char *)buffer + string_offset, wsabuf[i].szProtocol, string_size);
194 pi[i].lpProtocol = (WCHAR *)((char *)buffer + string_offset);
195 string_offset += string_size;
197 HeapFree(GetProcessHeap(), 0, wsabuf);
200 return ret;