1 /* 2 * PROJECT: ReactOS api tests 3 * LICENSE: GPL - See COPYING in the top level directory 4 * PURPOSE: Test for WSARecv 5 * PROGRAMMERS: Peter Hater 6 */ 7 8 #include "ws2_32.h" 9 10 #define RECV_BUF 4 11 #define WSARecv_TIMEOUT 2000 12 13 static int count = 0; 14 15 void 16 CALLBACK completion( 17 DWORD dwError, 18 DWORD cbTransferred, 19 LPWSAOVERLAPPED lpOverlapped, 20 DWORD dwFlags) 21 { 22 //trace("completion called dwFlags %ld cbTransferred %ld lpOverlapped %p dwFlags %ld\n", dwError, cbTransferred, lpOverlapped, dwFlags); 23 count++; 24 ok(count == 1, "completion sould be called only once count = %d\n", count); 25 ok(dwError == 0, "dwError = %ld\n", dwError); 26 ok(cbTransferred == RECV_BUF, "cbTransferred %ld != %d\n", cbTransferred, RECV_BUF); 27 ok(lpOverlapped != NULL, "lpOverlapped %p\n", lpOverlapped); 28 if (lpOverlapped) 29 { 30 ok(lpOverlapped->hEvent != INVALID_HANDLE_VALUE, "lpOverlapped->hEvent %p\n", lpOverlapped->hEvent); 31 if (lpOverlapped->hEvent != INVALID_HANDLE_VALUE) 32 WSASetEvent(lpOverlapped->hEvent); 33 } 34 } 35 36 void Test_WSARecv() 37 { 38 const char szDummyBytes[RECV_BUF] = { 0xFF, 0x00, 0xFF, 0x00 }; 39 40 char szBuf[RECV_BUF]; 41 char szRecvBuf[RECV_BUF]; 42 int iResult, err; 43 SOCKET sck; 44 WSADATA wdata; 45 WSABUF buffers; 46 DWORD dwRecv, dwSent, dwFlags; 47 WSAOVERLAPPED overlapped; 48 char szGetRequest[] = "GET / HTTP/1.0\r\n\r\n"; 49 struct fd_set readable; 50 51 /* Start up Winsock */ 52 iResult = WSAStartup(MAKEWORD(2, 2), &wdata); 53 ok(iResult == 0, "WSAStartup failed, iResult == %d\n", iResult); 54 55 /* If we call recv without a socket, it should return with an error and do nothing. */ 56 memcpy(szBuf, szDummyBytes, RECV_BUF); 57 buffers.buf = szBuf; 58 buffers.len = sizeof(szBuf); 59 dwFlags = 0; 60 dwRecv = 0; 61 iResult = WSARecv(0, &buffers, 1, &dwRecv, &dwFlags, NULL, NULL); 62 ok(iResult == SOCKET_ERROR, "iRseult = %d\n", iResult); 63 ok(!memcmp(szBuf, szDummyBytes, RECV_BUF), "not equal\n"); 64 65 /* Create the socket */ 66 sck = WSASocketW(AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, WSA_FLAG_OVERLAPPED); 67 if(sck == INVALID_SOCKET) 68 { 69 WSACleanup(); 70 skip("CreateSocket failed. Aborting test.\n"); 71 return; 72 } 73 74 /* Now we can pass at least a socket, but we have no connection yet. Should return with an error and do nothing. */ 75 memcpy(szBuf, szDummyBytes, RECV_BUF); 76 buffers.buf = szBuf; 77 buffers.len = sizeof(szBuf); 78 dwFlags = 0; 79 dwRecv = 0; 80 iResult = WSARecv(sck, &buffers, 1, &dwRecv, &dwFlags, NULL, NULL); 81 ok(iResult == SOCKET_ERROR, "iResult = %d\n", iResult); 82 ok(!memcmp(szBuf, szDummyBytes, RECV_BUF), "not equal\n"); 83 84 /* Connect to "www.reactos.org" */ 85 if (!ConnectToReactOSWebsite(sck)) 86 { 87 WSACleanup(); 88 skip("ConnectToReactOSWebsite failed. Aborting test.\n"); 89 return; 90 } 91 92 /* prepare overlapped */ 93 memset(&overlapped, 0, sizeof(overlapped)); 94 overlapped.hEvent = WSACreateEvent(); 95 96 /* Send the GET request */ 97 buffers.buf = szGetRequest; 98 buffers.len = strlen(szGetRequest); 99 dwSent = 0; 100 iResult = WSASend(sck, &buffers, 1, &dwSent, 0, &overlapped, NULL); 101 err = WSAGetLastError(); 102 ok(iResult == 0 || (iResult == SOCKET_ERROR && err == WSA_IO_PENDING), "iResult = %d, %d\n", iResult, err); 103 if (err == WSA_IO_PENDING) 104 { 105 iResult = WSAWaitForMultipleEvents(1, &overlapped.hEvent, TRUE, WSARecv_TIMEOUT, TRUE); 106 ok(iResult == WSA_WAIT_EVENT_0, "WSAWaitForMultipleEvents failed %d\n", iResult); 107 ok(WSAGetOverlappedResult(sck, &overlapped, &dwSent, TRUE, &dwFlags), "WSAGetOverlappedResult failed %d\n", WSAGetLastError()); 108 } 109 ok(dwSent == strlen(szGetRequest), "dwSent %ld != %d\n", dwSent, strlen(szGetRequest)); 110 #if 0 /* break windows too */ 111 /* Shutdown the SEND connection */ 112 iResult = shutdown(sck, SD_SEND); 113 ok(iResult != SOCKET_ERROR, "iResult = %d\n", iResult); 114 #endif 115 /* Wait until we're ready to read */ 116 FD_ZERO(&readable); 117 FD_SET(sck, &readable); 118 119 iResult = select(0, &readable, NULL, NULL, NULL); 120 ok(iResult != SOCKET_ERROR, "iResult = %d\n", iResult); 121 122 /* Receive the data. */ 123 buffers.buf = szBuf; 124 buffers.len = sizeof(szBuf); 125 dwRecv = sizeof(szBuf); 126 iResult = WSARecv(sck, &buffers, 1, &dwRecv, &dwFlags, NULL, NULL); 127 ok(iResult != SOCKET_ERROR, "iResult = %d\n", iResult); 128 ok(dwRecv == sizeof(szBuf), "dwRecv %ld != %d\n", dwRecv, sizeof(szBuf)); 129 /* MSG_PEEK is invalid for overlapped (MSDN), but passes??? */ 130 buffers.buf = szRecvBuf; 131 buffers.len = sizeof(szRecvBuf); 132 dwFlags = MSG_PEEK; 133 dwRecv = sizeof(szRecvBuf); 134 ok(overlapped.hEvent != NULL, "WSACreateEvent failed %d\n", WSAGetLastError()); 135 iResult = WSARecv(sck, &buffers, 1, &dwRecv, &dwFlags, &overlapped, NULL); 136 err = WSAGetLastError(); 137 ok(iResult == 0 || (iResult == SOCKET_ERROR && err == WSA_IO_PENDING), "iResult = %d, %d\n", iResult, err); 138 if (err == WSA_IO_PENDING) 139 { 140 iResult = WSAWaitForMultipleEvents(1, &overlapped.hEvent, TRUE, WSARecv_TIMEOUT, TRUE); 141 ok(iResult == WSA_WAIT_EVENT_0, "WSAWaitForMultipleEvents failed %d\n", iResult); 142 ok(WSAGetOverlappedResult(sck, &overlapped, &dwRecv, TRUE, &dwFlags), "WSAGetOverlappedResult failed %d\n", WSAGetLastError()); 143 } 144 ok(dwRecv == sizeof(szRecvBuf), "dwRecv %ld != %d\n", dwRecv, sizeof(szRecvBuf)); 145 /* normal overlapped, no completion */ 146 buffers.buf = szBuf; 147 buffers.len = sizeof(szBuf); 148 dwFlags = 0; 149 dwRecv = sizeof(szBuf); 150 WSAResetEvent(overlapped.hEvent); 151 iResult = WSARecv(sck, &buffers, 1, &dwRecv, &dwFlags, &overlapped, NULL); 152 err = WSAGetLastError(); 153 ok(iResult == 0 || (iResult == SOCKET_ERROR && err == WSA_IO_PENDING), "iResult = %d, %d\n", iResult, err); 154 if (err == WSA_IO_PENDING) 155 { 156 iResult = WSAWaitForMultipleEvents(1, &overlapped.hEvent, TRUE, WSARecv_TIMEOUT, TRUE); 157 ok(iResult == WSA_WAIT_EVENT_0, "WSAWaitForMultipleEvents failed %d\n", iResult); 158 ok(WSAGetOverlappedResult(sck, &overlapped, &dwRecv, TRUE, &dwFlags), "WSAGetOverlappedResult failed %d\n", WSAGetLastError()); 159 } 160 ok(dwRecv == sizeof(szBuf), "dwRecv %ld != %d\n", dwRecv, sizeof(szBuf)); 161 ok(memcmp(szRecvBuf, szBuf, sizeof(szBuf)) == 0, "MSG_PEEK shouldn't have moved the pointer\n"); 162 /* overlapped with completion */ 163 dwFlags = 0; 164 dwRecv = sizeof(szBuf); 165 WSAResetEvent(overlapped.hEvent); 166 iResult = WSARecv(sck, &buffers, 1, &dwRecv, &dwFlags, &overlapped, &completion); 167 err = WSAGetLastError(); 168 ok(iResult == 0 || (iResult == SOCKET_ERROR && err == WSA_IO_PENDING), "iResult = %d, %d\n", iResult, err); 169 if (err == WSA_IO_PENDING) 170 { 171 iResult = WSAWaitForMultipleEvents(1, &overlapped.hEvent, TRUE, WSARecv_TIMEOUT, TRUE); 172 ok(iResult == WSA_WAIT_EVENT_0, "WSAWaitForMultipleEvents failed %d\n", iResult); 173 ok(WSAGetOverlappedResult(sck, &overlapped, &dwRecv, TRUE, &dwFlags), "WSAGetOverlappedResult failed %d\n", WSAGetLastError()); 174 } 175 ok(WSACloseEvent(overlapped.hEvent), "WSAGetOverlappedResult failed %d\n", WSAGetLastError()); 176 ok(dwRecv == sizeof(szBuf), "dwRecv %ld != %d\n", dwRecv, sizeof(szBuf)); 177 /* no overlapped with completion */ 178 dwFlags = 0; 179 dwRecv = sizeof(szBuf); 180 /* call doesn't fail, but completion is not called */ 181 iResult = WSARecv(sck, &buffers, 1, &dwRecv, &dwFlags, NULL, &completion); 182 err = WSAGetLastError(); 183 ok(iResult == 0 || (iResult == SOCKET_ERROR && err == WSA_IO_PENDING), "iResult = %d, %d\n", iResult, err); 184 ok(WSAGetLastError() == 0, "WSAGetLastError failed %d\n", WSAGetLastError()); 185 ok(dwRecv == sizeof(szBuf), "dwRecv %ld != %d and 0\n", dwRecv, sizeof(szBuf)); 186 187 closesocket(sck); 188 WSACleanup(); 189 return; 190 } 191 192 START_TEST(WSARecv) 193 { 194 Test_WSARecv(); 195 } 196 197