* Addendum to r58214.
[reactos.git] / 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 * PROGRAMMERS: Colin Finck
6 */
7
8 #include <stdio.h>
9 #include <wine/test.h>
10 #include <winternl.h>
11 #include "ws2_32.h"
12
13 #define RECV_BUF 4
14
15 /* For valid test results, the ReactOS Website needs to return at least 8 bytes on a "GET / HTTP/1.0" request.
16 Also the first 4 bytes and the last 4 bytes need to be different.
17 Both factors usually apply on standard HTTP responses. */
18
19 int Test_recv()
20 {
21 const char szDummyBytes[RECV_BUF] = {0xFF, 0x00, 0xFF, 0x00};
22
23 char szBuf1[RECV_BUF];
24 char szBuf2[RECV_BUF];
25 int iResult;
26 SOCKET sck;
27 WSADATA wdata;
28 NTSTATUS status;
29 IO_STATUS_BLOCK readIosb;
30 HANDLE readEvent;
31 LARGE_INTEGER readOffset;
32
33 /* Start up Winsock */
34 iResult = WSAStartup(MAKEWORD(2, 2), &wdata);
35 ok(iResult == 0, "WSAStartup failed, iResult == %d\n", iResult);
36
37 /* If we call recv without a socket, it should return with an error and do nothing. */
38 memcpy(szBuf1, szDummyBytes, RECV_BUF);
39 iResult = recv(0, szBuf1, RECV_BUF, 0);
40 ok(iResult == SOCKET_ERROR, "iRseult = %d\n", iResult);
41 ok(!memcmp(szBuf1, szDummyBytes, RECV_BUF), "not equal\n");
42
43 /* Create the socket */
44 if (!CreateSocket(&sck))
45 {
46 ok(0, "CreateSocket failed. Aborting test.\n");
47 return 0;
48 }
49
50 /* Now we can pass at least a socket, but we have no connection yet. Should return with an error and do nothing. */
51 memcpy(szBuf1, szDummyBytes, RECV_BUF);
52 iResult = recv(sck, szBuf1, RECV_BUF, 0);
53 ok(iResult == SOCKET_ERROR, "iResult = %d\n", iResult);
54 ok(!memcmp(szBuf1, szDummyBytes, RECV_BUF), "not equal\n");
55
56 /* Connect to "www.reactos.org" */
57 if (!ConnectToReactOSWebsite(sck))
58 {
59 ok(0, "ConnectToReactOSWebsite failed. Aborting test.\n");
60 return 0;
61 }
62
63 /* Send the GET request */
64 if (!GetRequestAndWait(sck))
65 {
66 ok(0, "GetRequestAndWait failed. Aborting test.\n");
67 return 0;
68 }
69
70 /* Receive the data.
71 MSG_PEEK will not change the internal number of bytes read, so that a subsequent request should return the same bytes again. */
72 SCKTEST(recv(sck, szBuf1, RECV_BUF, MSG_PEEK));
73 SCKTEST(recv(sck, szBuf2, RECV_BUF, 0));
74 ok(!memcmp(szBuf1, szBuf2, RECV_BUF), "not equal\n");
75
76 /* The last recv() call moved the internal file pointer, so that the next request should return different data. */
77 SCKTEST(recv(sck, szBuf1, RECV_BUF, 0));
78 ok(memcmp(szBuf1, szBuf2, RECV_BUF), "equal\n");
79
80 /* Create an event for NtReadFile */
81 readOffset.QuadPart = 0LL;
82 memcpy(szBuf1, szBuf2, RECV_BUF);
83 status = NtCreateEvent(&readEvent,
84 EVENT_ALL_ACCESS,
85 NULL,
86 NotificationEvent,
87 FALSE);
88 if (status != 0)
89 {
90 ok(0, "Failed to create event\n");
91 return 0;
92 }
93
94 /* Try reading the socket using the NT file API */
95 status = NtReadFile((HANDLE)sck,
96 readEvent,
97 NULL,
98 NULL,
99 &readIosb,
100 szBuf1,
101 RECV_BUF,
102 &readOffset,
103 NULL);
104 if (status == STATUS_PENDING)
105 {
106 WaitForSingleObject(readEvent, INFINITE);
107 status = readIosb.Status;
108 }
109
110 ok(status == 0, "Read failed with status 0x%x\n", (unsigned int)status);
111 ok(memcmp(szBuf2, szBuf1, RECV_BUF), "equal\n");
112 ok(readIosb.Information == RECV_BUF, "Short read\n");
113
114 NtClose(readEvent);
115 closesocket(sck);
116 WSACleanup();
117 return 1;
118 }
119
120 START_TEST(recv)
121 {
122 Test_recv();
123 }
124