update for HEAD-2003021201
[reactos.git] / lib / msafd / misc / sndrcv.c
1 /*
2  * COPYRIGHT:   See COPYING in the top level directory
3  * PROJECT:     ReactOS Ancillary Function Driver DLL
4  * FILE:        misc/sndrcv.c
5  * PURPOSE:     Send/receive routines
6  * PROGRAMMERS: Casper S. Hornstrup (chorns@users.sourceforge.net)
7  * REVISIONS:
8  *   CSH 01/09-2000 Created
9  */
10 #include <string.h>
11 #include <msafd.h>
12
13 INT
14 WSPAPI
15 WSPAsyncSelect(
16     IN  SOCKET s, 
17     IN  HWND hWnd, 
18     IN  UINT wMsg, 
19     IN  LONG lEvent, 
20     OUT LPINT lpErrno)
21 {
22   UNIMPLEMENTED
23
24   return 0;
25 }
26
27
28 INT
29 WSPAPI
30 WSPRecv(
31     IN      SOCKET s,
32     IN OUT  LPWSABUF lpBuffers,
33     IN      DWORD dwBufferCount,
34     OUT     LPDWORD lpNumberOfBytesRecvd,
35     IN OUT  LPDWORD lpFlags,
36     IN      LPWSAOVERLAPPED lpOverlapped,
37     IN      LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine,
38     IN      LPWSATHREADID lpThreadId,
39     OUT     LPINT lpErrno)
40 {
41   PFILE_REQUEST_RECV Request;
42   FILE_REPLY_RECV Reply;
43   IO_STATUS_BLOCK Iosb;
44   NTSTATUS Status;
45   DWORD Size;
46
47   AFD_DbgPrint(MAX_TRACE, ("Called.\n"));
48
49   Size = dwBufferCount * sizeof(WSABUF);
50
51   Request = (PFILE_REQUEST_RECV)HeapAlloc(
52     GlobalHeap, 0, sizeof(FILE_REQUEST_RECV) + Size);
53   if (!Request) {
54     AFD_DbgPrint(MIN_TRACE, ("Insufficient resources.\n"));
55     *lpErrno = WSAENOBUFS;
56     return SOCKET_ERROR;
57   }
58
59   /* Put buffer pointers after request structure */
60   Request->Buffers     = (LPWSABUF)(Request + 1);
61   Request->BufferCount = dwBufferCount;
62   Request->Flags       = lpFlags;
63
64   RtlCopyMemory(Request->Buffers, lpBuffers, Size);
65
66   Status = NtDeviceIoControlFile(
67     (HANDLE)s,
68     NULL,
69                 NULL,
70                 NULL,   
71                 &Iosb,
72                 IOCTL_AFD_RECV,
73                 Request,
74                 sizeof(FILE_REQUEST_RECV) + Size,
75                 &Reply,
76                 sizeof(FILE_REPLY_RECV));
77
78   HeapFree(GlobalHeap, 0, Request);
79
80         if (Status == STATUS_PENDING) {
81     AFD_DbgPrint(MAX_TRACE, ("Waiting on transport.\n"));
82     /* FIXME: Wait only for blocking sockets */
83                 Status = NtWaitForSingleObject((HANDLE)s, FALSE, NULL);
84   }
85
86   if (!NT_SUCCESS(Status)) {
87     AFD_DbgPrint(MAX_TRACE, ("Status (0x%X).\n", Status));
88                 *lpErrno = WSAENOBUFS;
89     return SOCKET_ERROR;
90         }
91
92   AFD_DbgPrint(MAX_TRACE, ("Receive successful (0x%X).\n",
93     Reply.NumberOfBytesRecvd));
94
95   *lpNumberOfBytesRecvd = Reply.NumberOfBytesRecvd;
96   //*lpFlags = 0;
97
98   return 0;
99 }
100
101
102 INT
103 WSPAPI
104 WSPRecvDisconnect(
105     IN  SOCKET s,
106     OUT LPWSABUF lpInboundDisconnectData,
107     OUT LPINT lpErrno)
108 {
109   UNIMPLEMENTED
110
111   return 0;
112 }
113
114 INT
115 WSPAPI
116 WSPRecvFrom(
117     IN      SOCKET s,
118     IN OUT  LPWSABUF lpBuffers,
119     IN      DWORD dwBufferCount,
120     OUT     LPDWORD lpNumberOfBytesRecvd,
121     IN OUT  LPDWORD lpFlags,
122     OUT     LPSOCKADDR lpFrom,
123     IN OUT  LPINT lpFromLen,
124     IN      LPWSAOVERLAPPED lpOverlapped,
125     IN      LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine,
126     IN      LPWSATHREADID lpThreadId,
127     OUT     LPINT lpErrno)
128 {
129   PFILE_REQUEST_RECVFROM Request;
130   FILE_REPLY_RECVFROM Reply;
131   IO_STATUS_BLOCK Iosb;
132   NTSTATUS Status;
133   DWORD Size;
134
135   AFD_DbgPrint(MAX_TRACE, ("Called.\n"));
136
137   Size = dwBufferCount * sizeof(WSABUF);
138
139   Request = (PFILE_REQUEST_RECVFROM)HeapAlloc(
140     GlobalHeap, 0, sizeof(FILE_REQUEST_RECVFROM) + Size);
141   if (!Request) {
142     AFD_DbgPrint(MIN_TRACE, ("Insufficient resources.\n"));
143     *lpErrno = WSAENOBUFS;
144     return SOCKET_ERROR;
145   }
146
147   /* Put buffer pointers after request structure */
148   Request->Buffers     = (LPWSABUF)(Request + 1);
149   Request->BufferCount = dwBufferCount;
150   Request->Flags       = lpFlags;
151   Request->From        = lpFrom;
152   Request->FromLen     = lpFromLen;
153
154   RtlCopyMemory(Request->Buffers, lpBuffers, Size);
155
156   Status = NtDeviceIoControlFile(
157     (HANDLE)s,
158     NULL,
159                 NULL,
160                 NULL,   
161                 &Iosb,
162                 IOCTL_AFD_RECVFROM,
163                 Request,
164                 sizeof(FILE_REQUEST_RECVFROM) + Size,
165                 &Reply,
166                 sizeof(FILE_REPLY_RECVFROM));
167
168   HeapFree(GlobalHeap, 0, Request);
169
170         if (Status == STATUS_PENDING) {
171     AFD_DbgPrint(MAX_TRACE, ("Waiting on transport.\n"));
172     /* FIXME: Wait only for blocking sockets */
173                 Status = NtWaitForSingleObject((HANDLE)s, FALSE, NULL);
174   }
175
176   if (!NT_SUCCESS(Status)) {
177     AFD_DbgPrint(MAX_TRACE, ("Status (0x%X).\n", Status));
178                 *lpErrno = WSAENOBUFS;
179     return SOCKET_ERROR;
180         }
181
182   AFD_DbgPrint(MAX_TRACE, ("Receive successful (0x%X).\n",
183     Reply.NumberOfBytesRecvd));
184
185   *lpNumberOfBytesRecvd = Reply.NumberOfBytesRecvd;
186   //*lpFlags = 0;
187   ((PSOCKADDR_IN)lpFrom)->sin_family = AF_INET;
188   ((PSOCKADDR_IN)lpFrom)->sin_port = 0;
189   ((PSOCKADDR_IN)lpFrom)->sin_addr.S_un.S_addr = 0x0100007F;
190   *lpFromLen = sizeof(SOCKADDR_IN);
191
192   return 0;
193 }
194
195
196 INT
197 WSPAPI
198 WSPSend(
199     IN  SOCKET s,
200     IN  LPWSABUF lpBuffers,
201     IN  DWORD dwBufferCount,
202     OUT LPDWORD lpNumberOfBytesSent,
203     IN  DWORD dwFlags,
204     IN  LPWSAOVERLAPPED lpOverlapped,
205     IN  LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine,
206     IN  LPWSATHREADID lpThreadId,
207     OUT LPINT lpErrno)
208 {
209   PFILE_REQUEST_SENDTO Request;
210   FILE_REPLY_SENDTO Reply;
211   IO_STATUS_BLOCK Iosb;
212   NTSTATUS Status;
213   DWORD Size;
214
215   AFD_DbgPrint(MAX_TRACE, ("Called.\n"));
216
217   Size = dwBufferCount * sizeof(WSABUF);
218
219   Request = (PFILE_REQUEST_SENDTO)HeapAlloc(
220     GlobalHeap, 0, sizeof(FILE_REQUEST_SEND) + Size);
221   if (!Request) {
222     *lpErrno = WSAENOBUFS;
223     return SOCKET_ERROR;
224   }
225
226   /* Put buffer pointers after request structure */
227   Request->Buffers     = (LPWSABUF)(Request + 1);
228   Request->BufferCount = dwBufferCount;
229   Request->Flags       = dwFlags;
230
231   RtlCopyMemory(Request->Buffers, lpBuffers, Size);
232
233   Status = NtDeviceIoControlFile(
234     (HANDLE)s,
235     NULL,
236                 NULL,
237                 NULL,
238                 &Iosb,
239                 IOCTL_AFD_SEND,
240                 Request,
241                 sizeof(FILE_REQUEST_SEND) + Size,
242                 &Reply,
243                 sizeof(FILE_REPLY_SEND));
244
245   HeapFree(GlobalHeap, 0, Request);
246
247         if (Status == STATUS_PENDING) {
248     AFD_DbgPrint(MAX_TRACE, ("Waiting on transport.\n"));
249     /* FIXME: Wait only for blocking sockets */
250     Status = NtWaitForSingleObject((HANDLE)s, FALSE, NULL);
251   }
252
253   if (!NT_SUCCESS(Status)) {
254     AFD_DbgPrint(MAX_TRACE, ("Status (0x%X).\n", Status));
255     *lpErrno = WSAENOBUFS;
256     return SOCKET_ERROR;
257   }
258
259   AFD_DbgPrint(MAX_TRACE, ("Send successful.\n"));
260
261   return 0;
262 }
263
264
265 INT
266 WSPAPI
267 WSPSendDisconnect(
268     IN  SOCKET s,
269     IN  LPWSABUF lpOutboundDisconnectData,
270     OUT LPINT lpErrno)
271 {
272   UNIMPLEMENTED
273
274   return 0;
275 }
276
277
278 INT
279 WSPAPI
280 WSPSendTo(
281     IN  SOCKET s,
282     IN  LPWSABUF lpBuffers,
283     IN  DWORD dwBufferCount,
284     OUT LPDWORD lpNumberOfBytesSent,
285     IN  DWORD dwFlags,
286     IN  CONST LPSOCKADDR lpTo,
287     IN  INT iToLen,
288     IN  LPWSAOVERLAPPED lpOverlapped,
289     IN  LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine,
290     IN  LPWSATHREADID lpThreadId,
291     OUT LPINT lpErrno)
292 {
293   PFILE_REQUEST_SENDTO Request;
294   FILE_REPLY_SENDTO Reply;
295   IO_STATUS_BLOCK Iosb;
296   NTSTATUS Status;
297   DWORD Size;
298
299   AFD_DbgPrint(MAX_TRACE, ("Called.\n"));
300
301   Size = dwBufferCount * sizeof(WSABUF);
302
303   Request = (PFILE_REQUEST_SENDTO)HeapAlloc(
304     GlobalHeap, 0, sizeof(FILE_REQUEST_SENDTO) + Size);
305   if (!Request) {
306     *lpErrno = WSAENOBUFS;
307     return SOCKET_ERROR;
308   }
309
310   /* Put buffer pointers after request structure */
311   Request->Buffers     = (LPWSABUF)(Request + 1);
312   Request->BufferCount = dwBufferCount;
313   Request->Flags       = dwFlags;
314   Request->ToLen       = iToLen;
315
316   RtlCopyMemory(&Request->To, lpTo, sizeof(SOCKADDR));
317
318   RtlCopyMemory(Request->Buffers, lpBuffers, Size);
319
320   Status = NtDeviceIoControlFile(
321     (HANDLE)s,
322     NULL,
323                 NULL,
324                 NULL,
325                 &Iosb,
326                 IOCTL_AFD_SENDTO,
327                 Request,
328                 sizeof(FILE_REQUEST_SENDTO) + Size,
329                 &Reply,
330                 sizeof(FILE_REPLY_SENDTO));
331
332   HeapFree(GlobalHeap, 0, Request);
333
334         if (Status == STATUS_PENDING) {
335     AFD_DbgPrint(MAX_TRACE, ("Waiting on transport.\n"));
336     /* FIXME: Wait only for blocking sockets */
337     Status = NtWaitForSingleObject((HANDLE)s, FALSE, NULL);
338   }
339
340   if (!NT_SUCCESS(Status)) {
341     AFD_DbgPrint(MAX_TRACE, ("Status (0x%X).\n", Status));
342     *lpErrno = WSAENOBUFS;
343     return SOCKET_ERROR;
344   }
345
346   AFD_DbgPrint(MAX_TRACE, ("Send successful.\n"));
347
348   return 0;
349 }
350
351 /* EOF */