source: trunk/src/ws2_32/socket.cpp

Last change on this file was 21552, checked in by abwillis, 15 years ago

Ticket #25 WSALookupServiceBeginA and W stubs.

File size: 11.8 KB
RevLine 
[9843]1/* $Id: socket.cpp,v 1.16 2003-02-24 11:14:30 sandervl Exp $ */
[5743]2/*
3 * based on Windows Sockets 1.1 specs
4 * (ftp.microsoft.com:/Advsys/winsock/spec11/WINSOCK.TXT)
5 *
6 * (C) 1993,1994,1996,1997 John Brezak, Erik Bos, Alex Korobka.
7 *
8 * NOTE: If you make any changes to fix a particular app, make sure
9 * they don't break something else like Netscape or telnet and ftp
10 * clients and servers (www.winsite.com got a lot of those).
11 *
12 * NOTE 2: Many winsock structs such as servent, hostent, protoent, ...
13 * are used with 1-byte alignment for Win16 programs and 4-byte alignment
14 * for Win32 programs in winsock.h. winsock2.h uses forced 4-byte alignment.
15 * So we have non-forced (just as MSDN) ws_XXXXent (winsock.h), 4-byte forced
16 * ws_XXXXent32 (winsock2.h) and 1-byte forced ws_XXXXent16 (winsock16.h).
17 */
18
[6995]19
20/*****************************************************************************
21 * Includes *
22 *****************************************************************************/
23
[5743]24#include <odin.h>
25#include <winsock2.h>
26#include <debugtools.h>
[6995]27#include <odinwrap.h>
[5743]28
[6995]29
30ODINDEBUGCHANNEL(WS2_32-SOCKET)
31
32
[5743]33/***********************************************************************
34 * WSACreateEvent() (WS2_32.???)
35 *
36 */
[6995]37ODINFUNCTION0(WSAEVENT, WSACreateEvent)
[5743]38{
39 /* Create a manual-reset event, with initial state: unsignealed */
40
41 return CreateEventA(NULL, TRUE, FALSE, NULL);
42}
43
[6995]44ODINFUNCTION1(BOOL, WSASetEvent,
45 WSAEVENT, hEvent)
[5751]46{
47 return SetEvent(hEvent);
48}
49
[5743]50/***********************************************************************
51 * WSACloseEvent() (WS2_32.???)
52 *
53 */
[6995]54ODINFUNCTION1(BOOL, WSACloseEvent,
55 WSAEVENT, hEvent)
[5743]56{
[6200]57 return CloseHandle(hEvent);
[5743]58}
59
60/***********************************************************************
61 * WSASocketA() (WS2_32.???)
62 *
63 */
[6995]64ODINFUNCTION6(SOCKET, WSASocketA,
65 int, af,
66 int, type,
67 int, protocol,
68 LPWSAPROTOCOL_INFOA, lpProtocolInfo,
69 GROUP, g,
70 DWORD, dwFlags)
[5743]71{
[6995]72 dprintf(("WSASocketA incorrectly implemented"));
[5743]73 /*
74 FIXME: The "advanced" parameters of WSASocketA (lpProtocolInfo,
75 g, dwFlags) are ignored.
76 */
77
78 TRACE("WSASocketA af=%d type=%d protocol=%d protocol_info=%p group=%d flags=0x%lx\n",
79 af, type, protocol, lpProtocolInfo, g, dwFlags );
80
81 return ( socket (af, type, protocol) );
82}
83
84/***********************************************************************
85 * WSASocketA() (WS2_32.???)
86 *
87 */
[6995]88ODINFUNCTION6(SOCKET, WSASocketW,
89 int, af,
90 int, type,
91 int, protocol,
92 LPWSAPROTOCOL_INFOW, lpProtocolInfo,
93 GROUP, g,
94 DWORD, dwFlags)
[5743]95{
[6995]96 dprintf(("WSASocketW incorrectly implemented"));
[5743]97 /*
98 FIXME: The "advanced" parameters of WSASocketA (lpProtocolInfo,
99 g, dwFlags) are ignored.
100 */
101
102 TRACE("WSASocketW af=%d type=%d protocol=%d protocol_info=%p group=%d flags=0x%lx\n",
103 af, type, protocol, lpProtocolInfo, g, dwFlags );
104
105 return ( socket (af, type, protocol) );
106}
[8370]107/***********************************************************************
108 * WSAAccept (WS2_32.26)
109 */
[21420]110SOCKET WINAPI WSAAccept( SOCKET s, struct sockaddr *addr, LPINT addrlen,
[8370]111 LPCONDITIONPROC lpfnCondition, DWORD dwCallbackData)
112{
113
114 int ret = 0, size = 0;
115 WSABUF CallerId, CallerData, CalleeId, CalleeData;
116 /* QOS SQOS, GQOS; */
117 GROUP g;
118 SOCKET cs;
119 SOCKADDR src_addr, dst_addr;
120
121 TRACE("Socket %u, sockaddr %p, addrlen %p, fnCondition %p, dwCallbackData %ld\n",
122 s, addr, addrlen, lpfnCondition, dwCallbackData);
123
124
125 size = sizeof(src_addr);
126 cs = accept(s, &src_addr, &size);
127
128 if (cs == SOCKET_ERROR) return SOCKET_ERROR;
129
130 CallerId.buf = (char *)&src_addr;
131 CallerId.len = sizeof(src_addr);
132
133 CallerData.buf = NULL;
134 CallerData.len = (ULONG)NULL;
135
136 getsockname(cs, &dst_addr, &size);
137
138 CalleeId.buf = (char *)&dst_addr;
139 CalleeId.len = sizeof(dst_addr);
140
141 ret = (*lpfnCondition)(&CallerId, &CallerData, NULL, NULL,
142 &CalleeId, &CalleeData, &g, dwCallbackData);
143
144 switch (ret)
145 {
146 case CF_ACCEPT:
147 if (addr && addrlen)
[21420]148 addr = (struct sockaddr *)memcpy(addr, &src_addr, (*addrlen > size) ? size : *addrlen );
[8370]149 return cs;
150 case CF_DEFER:
[9836]151 WSASetLastError(WSATRY_AGAIN);
[8370]152 return SOCKET_ERROR;
153 case CF_REJECT:
154 closesocket(cs);
[9836]155 WSASetLastError(WSAECONNREFUSED);
[8370]156 return SOCKET_ERROR;
157 default:
158 FIXME("Unknown return type from Condition function\n");
[9836]159 WSASetLastError(WSAENOTSOCK);
[8370]160 return SOCKET_ERROR;
161 }
162
[9836]163 WSASetLastError(WSAENOTSOCK);
[8370]164 return SOCKET_ERROR;
165}
[7088]166//******************************************************************************
167//******************************************************************************
[9836]168/***********************************************************************
169 * WSASendTo (WS2_32.74)
170 */
171INT WINAPI WSASendTo( SOCKET s, LPWSABUF lpBuffers, DWORD dwBufferCount,
172 LPDWORD lpNumberOfBytesSent, DWORD dwFlags,
[21420]173 const struct sockaddr *to, int tolen,
[9836]174 LPWSAOVERLAPPED lpOverlapped,
175 LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine )
176{
177 WSASetLastError(WSAENOTSOCK);
178 return SOCKET_ERROR;
179}
180/***********************************************************************
181 * WSASend (WS2_32.72)
182 */
183INT WINAPI WSASend( SOCKET s, LPWSABUF lpBuffers, DWORD dwBufferCount,
184 LPDWORD lpNumberOfBytesSent, DWORD dwFlags,
185 LPWSAOVERLAPPED lpOverlapped,
186 LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine )
187{
[9841]188 DWORD dwBytesSent, tmpret;
189 DWORD ret = NO_ERROR;
190
191 dprintf(("WSASend %d %x %d %x %x %x %x", s, lpBuffers, dwBufferCount, lpNumberOfBytesSent, dwFlags, lpOverlapped, lpCompletionRoutine));
192
193 if(lpBuffers == NULL) {
194 WSASetLastError(WSAEINVAL);
195 return SOCKET_ERROR;
196 }
197 if(lpNumberOfBytesSent == NULL) {
198 lpNumberOfBytesSent = &dwBytesSent;
199 }
200 if(!lpOverlapped && !lpCompletionRoutine)
201 {
202 *lpNumberOfBytesSent = 0;
203
204 for(int i=0;i<dwBufferCount;i++) {
205 tmpret = send(s, lpBuffers[i].buf, lpBuffers[i].len, dwFlags);
206 if(tmpret != SOCKET_ERROR) {
[9843]207 *lpNumberOfBytesSent += tmpret;
[9841]208 }
209 else {
210 ret = SOCKET_ERROR;
211 break;
212 }
213 }
[9843]214 if(*lpNumberOfBytesSent) {
215 WSASetLastError(NO_ERROR);
216 ret = NO_ERROR;
217 }
[9841]218 return ret;
219 }
[9836]220 return WSASendTo ( s, lpBuffers, dwBufferCount, lpNumberOfBytesSent, dwFlags,
221 NULL, 0, lpOverlapped, lpCompletionRoutine );
222}
223/***********************************************************************
224 * WSARecvFrom (WS2_32.69)
225 */
226INT WINAPI WSARecvFrom( SOCKET s, LPWSABUF lpBuffers, DWORD dwBufferCount,
[21420]227 LPDWORD lpNumberOfBytesRecvd, LPDWORD lpFlags, struct sockaddr *lpFrom,
[9836]228 LPINT lpFromlen, LPWSAOVERLAPPED lpOverlapped,
229 LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine )
230
231{
232 WSASetLastError(WSAENOTSOCK);
233 return SOCKET_ERROR;
234}
235/***********************************************************************
236 * WSARecv (WS2_32.67)
237 */
238int WINAPI WSARecv (SOCKET s, LPWSABUF lpBuffers, DWORD dwBufferCount,
[9841]239 LPDWORD lpNumberOfBytesReceived, LPDWORD lpFlags,
[9836]240 LPWSAOVERLAPPED lpOverlapped,
241 LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine)
242{
[9841]243 DWORD dwBytesReceived, tmpret, flags;
244 DWORD ret = NO_ERROR;
245
246 dprintf(("WSARecv %d %x %d %x %x %x %x", s, lpBuffers, dwBufferCount, lpNumberOfBytesReceived, lpFlags, lpOverlapped, lpCompletionRoutine));
247 if(lpBuffers == NULL) {
248 WSASetLastError(WSAEINVAL);
249 return SOCKET_ERROR;
250 }
251 if(lpNumberOfBytesReceived == NULL) {
252 lpNumberOfBytesReceived = &dwBytesReceived;
253 }
254 if(lpFlags == NULL) {
255 lpFlags = &flags;
256 flags = 0;
257 }
258 if(!lpOverlapped && !lpCompletionRoutine)
259 {
260 *lpNumberOfBytesReceived = 0;
261
262 for(int i=0;i<dwBufferCount;i++) {
263 tmpret = recv(s, lpBuffers[i].buf, lpBuffers[i].len, *lpFlags);
264 if(tmpret != SOCKET_ERROR) {
[9843]265 *lpNumberOfBytesReceived += tmpret;
[9841]266 }
267 else {
268 ret = SOCKET_ERROR;
269 break;
270 }
271 }
[9843]272 if(*lpNumberOfBytesReceived) {
273 WSASetLastError(NO_ERROR);
274 ret = NO_ERROR;
275 }
276 dprintf(("WSARecv returned %d (read %x)", ret, *lpNumberOfBytesReceived));
[9841]277 *lpFlags = 0; //what to do with this?
278 return ret;
279 }
280 return WSARecvFrom (s, lpBuffers, dwBufferCount, lpNumberOfBytesReceived, lpFlags,
[9836]281 NULL, NULL, lpOverlapped, lpCompletionRoutine);
282}
[21322]283
284/***********************************************************************
285 * WSAAddressToStringA (WS2_32.27)
286 *
287 * See WSAAddressToStringW
288 */
289INT WINAPI WSAAddressToStringA( LPSOCKADDR sockaddr, DWORD len,
290 LPWSAPROTOCOL_INFOA info, LPSTR string,
291 LPDWORD lenstr )
292{
293 INT size;
294 CHAR buffer[22]; /* 12 digits + 3 dots + ':' + 5 digits + '\0' */
295 CHAR *p;
296
297 TRACE( "(%p, %d, %p, %p, %p)\n", sockaddr, len, info, string, lenstr );
298
299 if (!sockaddr || len < sizeof(SOCKADDR_IN)) return SOCKET_ERROR;
300 if (!string || !lenstr) return SOCKET_ERROR;
301
302 /* sin_family is guaranteed to be the first u_short */
303 if (((SOCKADDR_IN *)sockaddr)->sin_family != AF_INET) return SOCKET_ERROR;
304
305 sprintf( buffer, "%u.%u.%u.%u:%u",
306 (unsigned int)(ntohl( ((SOCKADDR_IN *)sockaddr)->sin_addr.s_addr ) >> 24 & 0xff),
307 (unsigned int)(ntohl( ((SOCKADDR_IN *)sockaddr)->sin_addr.s_addr ) >> 16 & 0xff),
308 (unsigned int)(ntohl( ((SOCKADDR_IN *)sockaddr)->sin_addr.s_addr ) >> 8 & 0xff),
309 (unsigned int)(ntohl( ((SOCKADDR_IN *)sockaddr)->sin_addr.s_addr ) & 0xff),
310 ntohs( ((SOCKADDR_IN *)sockaddr)->sin_port ) );
311
312 p = strchr( buffer, ':' );
313 if (!((SOCKADDR_IN *)sockaddr)->sin_port) *p = 0;
314
315 size = strlen( buffer );
316
317 if (*lenstr < size)
318 {
319 *lenstr = size;
320 WSASetLastError(WSAEFAULT);
321 return SOCKET_ERROR;
322 }
323
324 strcpy( string, buffer );
325 return 0;
326}
[21552]327
328/***********************************************************************
329 * WSALookupServiceBeginA (WS2_32.59)
330 */
331INT WINAPI WSALookupServiceBeginA( LPWSAQUERYSETA lpqsRestrictions,
332 DWORD dwControlFlags,
333 LPHANDLE lphLookup)
334{
335 FIXME("(%p 0x%08lx %p) Stub!\n", lpqsRestrictions, dwControlFlags,
336 lphLookup);
337 WSASetLastError(WSA_NOT_ENOUGH_MEMORY);
338 return SOCKET_ERROR;
339}
340
341/***********************************************************************
342 * WSALookupServiceBeginW (WS2_32.60)
343 */
344INT WINAPI WSALookupServiceBeginW( LPWSAQUERYSETW lpqsRestrictions,
345 DWORD dwControlFlags,
346 LPHANDLE lphLookup)
347{
348 FIXME("(%p 0x%08lx %p) Stub!\n", lpqsRestrictions, dwControlFlags,
349 lphLookup);
350 WSASetLastError(WSA_NOT_ENOUGH_MEMORY);
351 return SOCKET_ERROR;
352}
Note: See TracBrowser for help on using the repository browser.