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 <wine/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 127