1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS WinSock 2 API
4 * FILE: dll/win32/ws2_32/src/send.c
5 * PURPOSE: Socket Sending Support.
6 * PROGRAMMER: Alex Ionescu (alex@relsoft.net)
7 */
8
9 /* INCLUDES ******************************************************************/
10
11 #include <ws2_32.h>
12
13 #define NDEBUG
14 #include <debug.h>
15
16 /* FUNCTIONS *****************************************************************/
17
18 /*
19 * @implemented
20 */
21 INT
22 WSAAPI
send(IN SOCKET s,IN CONST CHAR FAR * buf,IN INT len,IN INT flags)23 send(IN SOCKET s,
24 IN CONST CHAR FAR* buf,
25 IN INT len,
26 IN INT flags)
27 {
28 PWSSOCKET Socket;
29 INT Status;
30 INT ErrorCode;
31 LPWSATHREADID ThreadId;
32 WSABUF Buffers;
33 DWORD BytesSent;
34 DPRINT("send: %lx, %lx, %lx, %p\n", s, flags, len, buf);
35
36 /* Check for WSAStartup */
37 if ((ErrorCode = WsQuickPrologTid(&ThreadId)) == ERROR_SUCCESS)
38 {
39 /* Get the Socket Context */
40 if ((Socket = WsSockGetSocket(s)))
41 {
42 /* Setup the buffers */
43 Buffers.buf = (PCHAR)buf;
44 Buffers.len = len;
45
46 /* Make the call */
47 Status = Socket->Provider->Service.lpWSPSend(s,
48 &Buffers,
49 1,
50 &BytesSent,
51 (DWORD)flags,
52 NULL,
53 NULL,
54 ThreadId,
55 &ErrorCode);
56 /* Deference the Socket Context */
57 WsSockDereference(Socket);
58
59 /* Return Provider Value */
60 if (Status == ERROR_SUCCESS) return BytesSent;
61
62 /* If everything seemed fine, then the WSP call failed itself */
63 if (ErrorCode == NO_ERROR) ErrorCode = WSASYSCALLFAILURE;
64 }
65 else
66 {
67 /* No Socket Context Found */
68 ErrorCode = WSAENOTSOCK;
69 }
70 }
71
72 /* Return with an Error */
73 SetLastError(ErrorCode);
74 return SOCKET_ERROR;
75 }
76
77 /*
78 * @implemented
79 */
80 INT
81 WSAAPI
sendto(IN SOCKET s,IN CONST CHAR FAR * buf,IN INT len,IN INT flags,IN CONST struct sockaddr * to,IN INT tolen)82 sendto(IN SOCKET s,
83 IN CONST CHAR FAR* buf,
84 IN INT len,
85 IN INT flags,
86 IN CONST struct sockaddr *to,
87 IN INT tolen)
88 {
89 PWSSOCKET Socket;
90 INT Status;
91 INT ErrorCode;
92 LPWSATHREADID ThreadId;
93 WSABUF Buffers;
94 DWORD BytesSent;
95 DPRINT("sendto: %lx, %lx, %lx, %p\n", s, flags, len, buf);
96
97 /* Check for WSAStartup */
98 if ((ErrorCode = WsQuickPrologTid(&ThreadId)) == ERROR_SUCCESS)
99 {
100 /* Get the Socket Context */
101 if ((Socket = WsSockGetSocket(s)))
102 {
103 /* Setup the buffers */
104 Buffers.buf = (PCHAR)buf;
105 Buffers.len = len;
106
107 /* Make the call */
108 Status = Socket->Provider->Service.lpWSPSendTo(s,
109 &Buffers,
110 1,
111 &BytesSent,
112 (DWORD)flags,
113 to,
114 tolen,
115 NULL,
116 NULL,
117 ThreadId,
118 &ErrorCode);
119 /* Deference the Socket Context */
120 WsSockDereference(Socket);
121
122 /* Return Provider Value */
123 if (Status == ERROR_SUCCESS) return BytesSent;
124
125 /* If everything seemed fine, then the WSP call failed itself */
126 if (ErrorCode == NO_ERROR) ErrorCode = WSASYSCALLFAILURE;
127 }
128 else
129 {
130 /* No Socket Context Found */
131 ErrorCode = WSAENOTSOCK;
132 }
133 }
134
135 /* Return with an Error */
136 SetLastError(ErrorCode);
137 return SOCKET_ERROR;
138 }
139
140 /*
141 * @implemented
142 */
143 INT
144 WSAAPI
WSASend(IN SOCKET s,IN LPWSABUF lpBuffers,IN DWORD dwBufferCount,OUT LPDWORD lpNumberOfBytesSent,IN DWORD dwFlags,IN LPWSAOVERLAPPED lpOverlapped,IN LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine)145 WSASend(IN SOCKET s,
146 IN LPWSABUF lpBuffers,
147 IN DWORD dwBufferCount,
148 OUT LPDWORD lpNumberOfBytesSent,
149 IN DWORD dwFlags,
150 IN LPWSAOVERLAPPED lpOverlapped,
151 IN LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine)
152 {
153 PWSSOCKET Socket;
154 INT Status;
155 INT ErrorCode;
156 LPWSATHREADID ThreadId;
157 DPRINT("WSASend: %lx, %lx, %lx, %p\n", s, dwFlags, dwBufferCount, lpBuffers);
158
159 /* Check for WSAStartup */
160 if ((ErrorCode = WsQuickPrologTid(&ThreadId)) == ERROR_SUCCESS)
161 {
162 /* Get the Socket Context */
163 if ((Socket = WsSockGetSocket(s)))
164 {
165 /* Make the call */
166 Status = Socket->Provider->Service.lpWSPSend(s,
167 lpBuffers,
168 dwBufferCount,
169 lpNumberOfBytesSent,
170 dwFlags,
171 lpOverlapped,
172 lpCompletionRoutine,
173 ThreadId,
174 &ErrorCode);
175 /* Deference the Socket Context */
176 WsSockDereference(Socket);
177
178 /* Return Provider Value */
179 if (Status == ERROR_SUCCESS) return Status;
180
181 /* If everything seemed fine, then the WSP call failed itself */
182 if (ErrorCode == NO_ERROR) ErrorCode = WSASYSCALLFAILURE;
183 }
184 else
185 {
186 /* No Socket Context Found */
187 ErrorCode = WSAENOTSOCK;
188 }
189 }
190
191 /* Return with an Error */
192 SetLastError(ErrorCode);
193 return SOCKET_ERROR;
194 }
195
196 /*
197 * @implemented
198 */
199 INT
200 WSAAPI
WSASendDisconnect(IN SOCKET s,IN LPWSABUF lpOutboundDisconnectData)201 WSASendDisconnect(IN SOCKET s,
202 IN LPWSABUF lpOutboundDisconnectData)
203 {
204 PWSPROCESS Process;
205 PWSTHREAD Thread;
206 PWSSOCKET Socket;
207 INT ErrorCode;
208 INT Status;
209 DPRINT("WSASendDisconnect: %lx %p\n", s, lpOutboundDisconnectData);
210
211 /* Enter prolog */
212 if ((ErrorCode = WsApiProlog(&Process, &Thread)) == ERROR_SUCCESS)
213 {
214 /* Get the Socket Context */
215 if ((Socket = WsSockGetSocket(s)))
216 {
217 /* Make the call */
218 Status = Socket->Provider->Service.lpWSPSendDisconnect(s,
219 lpOutboundDisconnectData,
220 &ErrorCode);
221 /* Deference the Socket Context */
222 WsSockDereference(Socket);
223
224 /* Return Provider Value */
225 if (Status == ERROR_SUCCESS) return ERROR_SUCCESS;
226
227 /* If everything seemed fine, then the WSP call failed itself */
228 if (ErrorCode == NO_ERROR) ErrorCode = WSASYSCALLFAILURE;
229 }
230 else
231 {
232 /* No Socket Context Found */
233 ErrorCode = WSAENOTSOCK;
234 }
235 }
236
237 /* Return with an Error */
238 SetLastError(ErrorCode);
239 return SOCKET_ERROR;
240 }
241
242 /*
243 * @implemented
244 */
245 INT
246 WSAAPI
WSASendTo(IN SOCKET s,IN LPWSABUF lpBuffers,IN DWORD dwBufferCount,OUT LPDWORD lpNumberOfBytesSent,IN DWORD dwFlags,IN CONST struct sockaddr * lpTo,IN INT iToLen,IN LPWSAOVERLAPPED lpOverlapped,IN LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine)247 WSASendTo(IN SOCKET s,
248 IN LPWSABUF lpBuffers,
249 IN DWORD dwBufferCount,
250 OUT LPDWORD lpNumberOfBytesSent,
251 IN DWORD dwFlags,
252 IN CONST struct sockaddr *lpTo,
253 IN INT iToLen,
254 IN LPWSAOVERLAPPED lpOverlapped,
255 IN LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine)
256 {
257 PWSSOCKET Socket;
258 INT Status;
259 INT ErrorCode;
260 LPWSATHREADID ThreadId;
261 DPRINT("WSASendTo: %lx, %lx, %lx, %p\n", s, dwFlags, dwBufferCount, lpBuffers);
262
263 /* Check for WSAStartup */
264 if ((ErrorCode = WsQuickPrologTid(&ThreadId)) == ERROR_SUCCESS)
265 {
266 /* Get the Socket Context */
267 if ((Socket = WsSockGetSocket(s)))
268 {
269 /* Make the call */
270 Status = Socket->Provider->Service.lpWSPSendTo(s,
271 lpBuffers,
272 dwBufferCount,
273 lpNumberOfBytesSent,
274 dwFlags,
275 lpTo,
276 iToLen,
277 lpOverlapped,
278 lpCompletionRoutine,
279 ThreadId,
280 &ErrorCode);
281 /* Deference the Socket Context */
282 WsSockDereference(Socket);
283
284 /* Return Provider Value */
285 if (Status == ERROR_SUCCESS) return Status;
286
287 /* If everything seemed fine, then the WSP call failed itself */
288 if (ErrorCode == NO_ERROR) ErrorCode = WSASYSCALLFAILURE;
289 }
290 else
291 {
292 /* No Socket Context Found */
293 ErrorCode = WSAENOTSOCK;
294 }
295 }
296
297 /* Return with an Error */
298 SetLastError(ErrorCode);
299 return SOCKET_ERROR;
300 }
301