xref: /reactos/dll/win32/ws2_32/src/send.c (revision b0a03a7c)
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