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