[SHELL32] *.rc: Strip all unneeded WS_DISABLED in dlg style (#6675)
[reactos.git] / modules / rostests / apitests / ws2_32 / recv.c
1 /*
2 * PROJECT: ReactOS API Tests
3 * LICENSE: GPL - See COPYING in the top level directory
4 * PURPOSE: Test for recv
5 * COPYRIGHT: Copyright 2008 Colin Finck (colin@reactos.org)
6 * Copyright 2010 Timo Kreuzer (timo.kreuzer@reactos.org)
7 * Copyright 2012 Cameron Gutman (cameron.gutman@reactos.org)
8 * Copyright 2023 Thomas Faber (thomas.faber@reactos.org)
9 */
10
11 #include "ws2_32.h"
12
13 #include <ndk/exfuncs.h>
14 #include <ndk/iofuncs.h>
15 #include <ndk/obfuncs.h>
16
17 #define RECV_BUF 4
18
19 /* For valid test results, the ReactOS Website needs to return at least 8 bytes on a "GET / HTTP/1.0" request.
20 Also the first 4 bytes and the last 4 bytes need to be different.
21 Both factors usually apply on standard HTTP responses. */
22
23 int Test_recv()
24 {
25 const char szDummyBytes[RECV_BUF] = {0xFF, 0x00, 0xFF, 0x00};
26
27 char szBuf1[RECV_BUF];
28 char szBuf2[RECV_BUF];
29 int iResult;
30 SOCKET sck;
31 WSADATA wdata;
32 NTSTATUS status;
33 IO_STATUS_BLOCK readIosb;
34 HANDLE readEvent;
35 LARGE_INTEGER readOffset;
36
37 /* Start up Winsock */
38 iResult = WSAStartup(MAKEWORD(2, 2), &wdata);
39 ok(iResult == 0, "WSAStartup failed, iResult == %d\n", iResult);
40
41 /* If we call recv without a socket, it should return with an error and do nothing. */
42 memcpy(szBuf1, szDummyBytes, RECV_BUF);
43 iResult = recv(0, szBuf1, RECV_BUF, 0);
44 ok(iResult == SOCKET_ERROR, "iRseult = %d\n", iResult);
45 ok(!memcmp(szBuf1, szDummyBytes, RECV_BUF), "not equal\n");
46
47 /* Create the socket */
48 if (!CreateSocket(&sck))
49 {
50 ok(0, "CreateSocket failed. Aborting test.\n");
51 return 0;
52 }
53
54 /* Now we can pass at least a socket, but we have no connection yet. Should return with an error and do nothing. */
55 memcpy(szBuf1, szDummyBytes, RECV_BUF);
56 iResult = recv(sck, szBuf1, RECV_BUF, 0);
57 ok(iResult == SOCKET_ERROR, "iResult = %d\n", iResult);
58 ok(!memcmp(szBuf1, szDummyBytes, RECV_BUF), "not equal\n");
59
60 /* Connect to "www.reactos.org" */
61 if (!ConnectToReactOSWebsite(sck))
62 {
63 ok(0, "ConnectToReactOSWebsite failed. Aborting test.\n");
64 return 0;
65 }
66
67 /* Send the GET request */
68 if (!GetRequestAndWait(sck))
69 {
70 ok(0, "GetRequestAndWait failed. Aborting test.\n");
71 return 0;
72 }
73
74 /* Receive the data.
75 MSG_PEEK will not change the internal number of bytes read, so that a subsequent request should return the same bytes again. */
76 SCKTEST(recv(sck, szBuf1, RECV_BUF, MSG_PEEK));
77 SCKTEST(recv(sck, szBuf2, RECV_BUF, 0));
78 ok(!memcmp(szBuf1, szBuf2, RECV_BUF), "not equal\n");
79
80 /* The last recv() call moved the internal file pointer, so that the next request should return different data. */
81 SCKTEST(recv(sck, szBuf1, RECV_BUF, 0));
82 ok(memcmp(szBuf1, szBuf2, RECV_BUF), "equal\n");
83
84 /* Create an event for NtReadFile */
85 readOffset.QuadPart = 0LL;
86 memcpy(szBuf1, szBuf2, RECV_BUF);
87 status = NtCreateEvent(&readEvent,
88 EVENT_ALL_ACCESS,
89 NULL,
90 NotificationEvent,
91 FALSE);
92 if (status != 0)
93 {
94 ok(0, "Failed to create event\n");
95 return 0;
96 }
97
98 /* Try reading the socket using the NT file API */
99 status = NtReadFile((HANDLE)sck,
100 readEvent,
101 NULL,
102 NULL,
103 &readIosb,
104 szBuf1,
105 RECV_BUF,
106 &readOffset,
107 NULL);
108 if (status == STATUS_PENDING)
109 {
110 WaitForSingleObject(readEvent, INFINITE);
111 status = readIosb.Status;
112 }
113
114 ok(status == 0, "Read failed with status 0x%x\n", (unsigned int)status);
115 ok(memcmp(szBuf2, szBuf1, RECV_BUF), "equal\n");
116 ok(readIosb.Information == RECV_BUF, "Short read\n");
117
118 NtClose(readEvent);
119 closesocket(sck);
120 WSACleanup();
121 return 1;
122 }
123
124 static void Test_Overread(void)
125 {
126 WSADATA wsaData;
127 SOCKET ListeningSocket = INVALID_SOCKET;
128 SOCKET ServerSocket = INVALID_SOCKET;
129 SOCKET ClientSocket = INVALID_SOCKET;
130 SOCKADDR_IN address;
131 char buffer[32];
132 int ret;
133 int error;
134 int len;
135 struct
136 {
137 char buffer[32];
138 DWORD flags;
139 WSAOVERLAPPED overlapped;
140 } receivers[4] = { 0 };
141 DWORD bytesTransferred;
142 DWORD flags;
143 WSABUF wsaBuf;
144 size_t i;
145
146 ret = WSAStartup(MAKEWORD(2, 2), &wsaData);
147 if (ret != 0)
148 {
149 skip("Failed to initialize WinSock, error %d\n", ret);
150 goto Exit;
151 }
152
153 ListeningSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
154 if (ListeningSocket == INVALID_SOCKET)
155 {
156 skip("Failed to create listening socket, error %d\n", WSAGetLastError());
157 goto Exit;
158 }
159
160 /* Bind to random port */
161 address.sin_family = AF_INET;
162 address.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
163 address.sin_port = 0;
164 ret = bind(ListeningSocket, (SOCKADDR *)&address, sizeof(address));
165 if (ret == SOCKET_ERROR)
166 {
167 skip("Failed to bind socket, error %d\n", WSAGetLastError());
168 goto Exit;
169 }
170
171 ret = listen(ListeningSocket, 1);
172 if (ret == SOCKET_ERROR)
173 {
174 skip("Failed to listen on socket, error %d\n", WSAGetLastError());
175 goto Exit;
176 }
177
178 len = sizeof(address);
179 ret = getsockname(ListeningSocket, (SOCKADDR *)&address, &len);
180 if (ret == SOCKET_ERROR)
181 {
182 skip("Failed to get listening port on socket, error %d\n", WSAGetLastError());
183 goto Exit;
184 }
185 ok(len == sizeof(address), "getsocketname length %d\n", len);
186
187 /**************************************************************************
188 * Test 1: non-overlapped client socket
189 *************************************************************************/
190 ClientSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
191 if (ClientSocket == INVALID_SOCKET)
192 {
193 skip("Failed to create client socket, error %d\n", WSAGetLastError());
194 goto Exit;
195 }
196
197 ret = connect(ClientSocket, (SOCKADDR *)&address, sizeof(address));
198 if (ret == SOCKET_ERROR)
199 {
200 skip("Failed to connect to socket, error %d\n", WSAGetLastError());
201 goto Exit;
202 }
203
204 ServerSocket = accept(ListeningSocket, NULL, NULL);
205 if (ServerSocket == INVALID_SOCKET)
206 {
207 skip("Failed to accept client socket, error %d\n", WSAGetLastError());
208 goto Exit;
209 }
210
211 ret = send(ServerSocket, "blah", 4, 0);
212 if (ret == SOCKET_ERROR)
213 {
214 skip("Failed to send to socket, error %d\n", WSAGetLastError());
215 goto Exit;
216 }
217
218 ret = closesocket(ServerSocket);
219 ServerSocket = INVALID_SOCKET;
220 ok(ret == 0, "Failed to close socket with %d\n", WSAGetLastError());
221
222 memset(buffer, 0, sizeof(buffer));
223 ret = recv(ClientSocket, buffer, sizeof(buffer), 0);
224 error = WSAGetLastError();
225 ok(ret == 4, "recv (1) returned %d\n", ret);
226 ok(error == NO_ERROR, "recv (1) returned error %d\n", error);
227 buffer[4] = 0;
228 ok(!strcmp(buffer, "blah"), "recv (1) returned data: %s\n", buffer);
229
230 ret = recv(ClientSocket, buffer, sizeof(buffer), 0);
231 error = WSAGetLastError();
232 ok(ret == 0, "recv (2) returned %d\n", ret);
233 ok(error == NO_ERROR, "recv (2) returned error %d\n", error);
234
235 ret = recv(ClientSocket, buffer, sizeof(buffer), 0);
236 error = WSAGetLastError();
237 ok(ret == 0, "recv (3) returned %d\n", ret);
238 ok(error == NO_ERROR, "recv (3) returned error %d\n", error);
239
240 closesocket(ClientSocket);
241
242 /**************************************************************************
243 * Test 2: overlapped client socket with multiple pending receives
244 *************************************************************************/
245 ClientSocket = WSASocketW(AF_INET,
246 SOCK_STREAM,
247 IPPROTO_TCP,
248 NULL,
249 0,
250 WSA_FLAG_OVERLAPPED);
251 if (ClientSocket == INVALID_SOCKET)
252 {
253 skip("Failed to create overlapped client socket, error %d\n", WSAGetLastError());
254 goto Exit;
255 }
256
257 ret = connect(ClientSocket, (SOCKADDR *)&address, sizeof(address));
258 if (ret == SOCKET_ERROR)
259 {
260 skip("Failed to connect to socket, error %d\n", WSAGetLastError());
261 goto Exit;
262 }
263
264 ServerSocket = accept(ListeningSocket, NULL, NULL);
265 if (ServerSocket == INVALID_SOCKET)
266 {
267 skip("Failed to accept client socket, error %d\n", WSAGetLastError());
268 goto Exit;
269 }
270
271 /* Start overlapping receive calls */
272 for (i = 0; i < RTL_NUMBER_OF(receivers); i++)
273 {
274 wsaBuf.len = sizeof(receivers[i].buffer);
275 wsaBuf.buf = receivers[i].buffer;
276 receivers[i].flags = 0;
277 receivers[i].overlapped.hEvent = WSACreateEvent();
278 ret = WSARecv(ClientSocket,
279 &wsaBuf,
280 1,
281 NULL,
282 &receivers[i].flags,
283 &receivers[i].overlapped,
284 NULL);
285 error = WSAGetLastError();
286 ok(ret == SOCKET_ERROR, "[%Iu] WSARecv returned %d\n", i, ret);
287 ok(error == WSA_IO_PENDING, "[%Iu] WSARecv returned error %d\n", i, error);
288 }
289
290 /* They should all be pending */
291 for (i = 0; i < RTL_NUMBER_OF(receivers); i++)
292 {
293 ret = WSAGetOverlappedResult(ClientSocket,
294 &receivers[i].overlapped,
295 &bytesTransferred,
296 FALSE,
297 &flags);
298 error = WSAGetLastError();
299 ok(ret == FALSE, "[%Iu] WSAGetOverlappedResult returned %d\n", i, ret);
300 ok(error == WSA_IO_INCOMPLETE, "[%Iu] WSAGetOverlappedResult returned error %d\n", i, error);
301 }
302
303 /* Sending some data should complete the first receive */
304 ret = send(ServerSocket, "blah", 4, 0);
305 if (ret == SOCKET_ERROR)
306 {
307 skip("Failed to send to socket, error %d\n", WSAGetLastError());
308 goto Exit;
309 }
310
311 flags = 0x55555555;
312 bytesTransferred = 0x55555555;
313 ret = WSAGetOverlappedResult(ClientSocket,
314 &receivers[0].overlapped,
315 &bytesTransferred,
316 FALSE,
317 &flags);
318 error = WSAGetLastError();
319 ok(ret == TRUE, "WSAGetOverlappedResult returned %d\n", ret);
320 ok(flags == 0, "WSAGetOverlappedResult returned flags 0x%lx\n", flags);
321 ok(bytesTransferred == 4, "WSAGetOverlappedResult returned %lu bytes\n", bytesTransferred);
322 receivers[0].buffer[4] = 0;
323 ok(!strcmp(receivers[0].buffer, "blah"), "WSARecv returned data: %s\n", receivers[0].buffer);
324
325 /* Others should still be in progress */
326 for (i = 1; i < RTL_NUMBER_OF(receivers); i++)
327 {
328 ret = WSAGetOverlappedResult(ClientSocket,
329 &receivers[i].overlapped,
330 &bytesTransferred,
331 FALSE,
332 &flags);
333 error = WSAGetLastError();
334 ok(ret == FALSE, "[%Iu] WSAGetOverlappedResult returned %d\n", i, ret);
335 ok(error == WSA_IO_INCOMPLETE, "[%Iu] WSAGetOverlappedResult returned error %d\n", i, error);
336 }
337
338 /* Closing the server end should make all receives complete */
339 ret = closesocket(ServerSocket);
340 ServerSocket = INVALID_SOCKET;
341 ok(ret == 0, "Failed to close socket with %d\n", WSAGetLastError());
342
343 for (i = 1; i < RTL_NUMBER_OF(receivers); i++)
344 {
345 flags = 0x55555555;
346 bytesTransferred = 0x55555555;
347 ret = WSAGetOverlappedResult(ClientSocket,
348 &receivers[i].overlapped,
349 &bytesTransferred,
350 FALSE,
351 &flags);
352 error = WSAGetLastError();
353 ok(ret == TRUE, "[%Iu] WSAGetOverlappedResult returned %d\n", i, ret);
354 ok(flags == 0, "[%Iu] WSAGetOverlappedResult returned flags 0x%lx\n", i, flags);
355 ok(bytesTransferred == 0, "[%Iu] WSAGetOverlappedResult returned %lu bytes\n", i, bytesTransferred);
356 }
357
358 /* Start two more receives -- they should immediately return success */
359 ret = recv(ClientSocket, receivers[0].buffer, sizeof(receivers[0].buffer), 0);
360 error = WSAGetLastError();
361 ok(ret == 0, "recv (N+1) returned %d\n", ret);
362 ok(error == NO_ERROR, "recv (N+1) returned error %d\n", error);
363
364 ret = recv(ClientSocket, receivers[0].buffer, sizeof(receivers[0].buffer), 0);
365 error = WSAGetLastError();
366 ok(ret == 0, "recv (N+2) returned %d\n", ret);
367 ok(error == NO_ERROR, "recv (N+2) returned error %d\n", error);
368
369 Exit:
370 for (i = 0; i < RTL_NUMBER_OF(receivers); i++)
371 {
372 if (receivers[i].overlapped.hEvent != NULL)
373 {
374 WSACloseEvent(receivers[i].overlapped.hEvent);
375 }
376 }
377
378 if (ListeningSocket != INVALID_SOCKET)
379 {
380 ret = closesocket(ListeningSocket);
381 ok(ret == 0, "closesocket (1) failed with %d\n", WSAGetLastError());
382 }
383 if (ClientSocket != INVALID_SOCKET)
384 {
385 ret = closesocket(ClientSocket);
386 ok(ret == 0, "closesocket (2) failed with %d\n", WSAGetLastError());
387 }
388 if (ServerSocket != INVALID_SOCKET)
389 {
390 ret = closesocket(ServerSocket);
391 ok(ret == 0, "closesocket (3) failed with %d\n", WSAGetLastError());
392 }
393 ret = WSACleanup();
394 ok(ret == 0, "WSACleanup failed with %d\n", WSAGetLastError());
395 }
396
397 START_TEST(recv)
398 {
399 Test_recv();
400 Test_Overread();
401 }
402