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