source: trunk/src/ws2_32/socket.cpp@ 9841

Last change on this file since 9841 was 9841, checked in by sandervl, 23 years ago

Implemented non-overlapped WSARecv & WSASend.

File size: 9.0 KB
Line 
1/* $Id: socket.cpp,v 1.15 2003-02-24 10:03:58 sandervl Exp $ */
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
19
20/*****************************************************************************
21 * Includes *
22 *****************************************************************************/
23
24#include <odin.h>
25#include <winsock2.h>
26#include <debugtools.h>
27#include <odinwrap.h>
28
29
30ODINDEBUGCHANNEL(WS2_32-SOCKET)
31
32
33/***********************************************************************
34 * WSACreateEvent() (WS2_32.???)
35 *
36 */
37ODINFUNCTION0(WSAEVENT, WSACreateEvent)
38{
39 /* Create a manual-reset event, with initial state: unsignealed */
40
41 return CreateEventA(NULL, TRUE, FALSE, NULL);
42}
43
44ODINFUNCTION1(BOOL, WSASetEvent,
45 WSAEVENT, hEvent)
46{
47 return SetEvent(hEvent);
48}
49
50/***********************************************************************
51 * WSACloseEvent() (WS2_32.???)
52 *
53 */
54ODINFUNCTION1(BOOL, WSACloseEvent,
55 WSAEVENT, hEvent)
56{
57 return CloseHandle(hEvent);
58}
59
60/***********************************************************************
61 * WSASocketA() (WS2_32.???)
62 *
63 */
64ODINFUNCTION6(SOCKET, WSASocketA,
65 int, af,
66 int, type,
67 int, protocol,
68 LPWSAPROTOCOL_INFOA, lpProtocolInfo,
69 GROUP, g,
70 DWORD, dwFlags)
71{
72 dprintf(("WSASocketA incorrectly implemented"));
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 */
88ODINFUNCTION6(SOCKET, WSASocketW,
89 int, af,
90 int, type,
91 int, protocol,
92 LPWSAPROTOCOL_INFOW, lpProtocolInfo,
93 GROUP, g,
94 DWORD, dwFlags)
95{
96 dprintf(("WSASocketW incorrectly implemented"));
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}
107/***********************************************************************
108 * WSAAccept (WS2_32.26)
109 */
110SOCKET WINAPI WSAAccept( SOCKET s, struct WS_sockaddr *addr, LPINT addrlen,
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)
148 addr = (struct WS_sockaddr *)memcpy(addr, &src_addr, (*addrlen > size) ? size : *addrlen );
149 return cs;
150 case CF_DEFER:
151 WSASetLastError(WSATRY_AGAIN);
152 return SOCKET_ERROR;
153 case CF_REJECT:
154 closesocket(cs);
155 WSASetLastError(WSAECONNREFUSED);
156 return SOCKET_ERROR;
157 default:
158 FIXME("Unknown return type from Condition function\n");
159 WSASetLastError(WSAENOTSOCK);
160 return SOCKET_ERROR;
161 }
162
163 WSASetLastError(WSAENOTSOCK);
164 return SOCKET_ERROR;
165}
166//******************************************************************************
167//******************************************************************************
168/***********************************************************************
169 * WSASendTo (WS2_32.74)
170 */
171INT WINAPI WSASendTo( SOCKET s, LPWSABUF lpBuffers, DWORD dwBufferCount,
172 LPDWORD lpNumberOfBytesSent, DWORD dwFlags,
173 const struct WS_sockaddr *to, int tolen,
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{
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) {
207 *lpNumberOfBytesSent += ret;
208 }
209 else {
210 ret = SOCKET_ERROR;
211 break;
212 }
213 }
214 return ret;
215 }
216 return WSASendTo ( s, lpBuffers, dwBufferCount, lpNumberOfBytesSent, dwFlags,
217 NULL, 0, lpOverlapped, lpCompletionRoutine );
218}
219/***********************************************************************
220 * WSARecvFrom (WS2_32.69)
221 */
222INT WINAPI WSARecvFrom( SOCKET s, LPWSABUF lpBuffers, DWORD dwBufferCount,
223 LPDWORD lpNumberOfBytesRecvd, LPDWORD lpFlags, struct WS_sockaddr *lpFrom,
224 LPINT lpFromlen, LPWSAOVERLAPPED lpOverlapped,
225 LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine )
226
227{
228 WSASetLastError(WSAENOTSOCK);
229 return SOCKET_ERROR;
230}
231/***********************************************************************
232 * WSARecv (WS2_32.67)
233 */
234int WINAPI WSARecv (SOCKET s, LPWSABUF lpBuffers, DWORD dwBufferCount,
235 LPDWORD lpNumberOfBytesReceived, LPDWORD lpFlags,
236 LPWSAOVERLAPPED lpOverlapped,
237 LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine)
238{
239 DWORD dwBytesReceived, tmpret, flags;
240 DWORD ret = NO_ERROR;
241
242 dprintf(("WSARecv %d %x %d %x %x %x %x", s, lpBuffers, dwBufferCount, lpNumberOfBytesReceived, lpFlags, lpOverlapped, lpCompletionRoutine));
243 if(lpBuffers == NULL) {
244 WSASetLastError(WSAEINVAL);
245 return SOCKET_ERROR;
246 }
247 if(lpNumberOfBytesReceived == NULL) {
248 lpNumberOfBytesReceived = &dwBytesReceived;
249 }
250 if(lpFlags == NULL) {
251 lpFlags = &flags;
252 flags = 0;
253 }
254 if(!lpOverlapped && !lpCompletionRoutine)
255 {
256 *lpNumberOfBytesReceived = 0;
257
258 for(int i=0;i<dwBufferCount;i++) {
259 tmpret = recv(s, lpBuffers[i].buf, lpBuffers[i].len, *lpFlags);
260 if(tmpret != SOCKET_ERROR) {
261 *lpNumberOfBytesReceived += ret;
262 }
263 else {
264 ret = SOCKET_ERROR;
265 break;
266 }
267 }
268 *lpFlags = 0; //what to do with this?
269 return ret;
270 }
271 return WSARecvFrom (s, lpBuffers, dwBufferCount, lpNumberOfBytesReceived, lpFlags,
272 NULL, NULL, lpOverlapped, lpCompletionRoutine);
273}
Note: See TracBrowser for help on using the repository browser.