xref: /reactos/dll/win32/ws2_32/src/send.c (revision 8a978a17)
1 /*
2  * COPYRIGHT:   See COPYING in the top level directory
3  * PROJECT:     ReactOS WinSock 2 API
4  * FILE:        dll/win32/ws2_32_new/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
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("sendto: %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
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
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("WSARecvFrom: %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
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
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