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 BOOL ret; 51 52 /* Start up Winsock */ 53 iResult = WSAStartup(MAKEWORD(2, 2), &wdata); 54 ok(iResult == 0, "WSAStartup failed, iResult == %d\n", iResult); 55 56 /* If we call recv without a socket, it should return with an error and do nothing. */ 57 memcpy(szBuf, szDummyBytes, RECV_BUF); 58 buffers.buf = szBuf; 59 buffers.len = sizeof(szBuf); 60 dwFlags = 0; 61 dwRecv = 0; 62 iResult = WSARecv(0, &buffers, 1, &dwRecv, &dwFlags, NULL, NULL); 63 ok(iResult == SOCKET_ERROR, "iRseult = %d\n", iResult); 64 ok(!memcmp(szBuf, szDummyBytes, RECV_BUF), "not equal\n"); 65 66 /* Create the socket */ 67 sck = WSASocketW(AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, WSA_FLAG_OVERLAPPED); 68 if(sck == INVALID_SOCKET) 69 { 70 WSACleanup(); 71 skip("CreateSocket failed. Aborting test.\n"); 72 return; 73 } 74 75 /* Now we can pass at least a socket, but we have no connection yet. Should return with an error and do nothing. */ 76 memcpy(szBuf, szDummyBytes, RECV_BUF); 77 buffers.buf = szBuf; 78 buffers.len = sizeof(szBuf); 79 dwFlags = 0; 80 dwRecv = 0; 81 iResult = WSARecv(sck, &buffers, 1, &dwRecv, &dwFlags, NULL, NULL); 82 ok(iResult == SOCKET_ERROR, "iResult = %d\n", iResult); 83 ok(!memcmp(szBuf, szDummyBytes, RECV_BUF), "not equal\n"); 84 85 /* Connect to "www.reactos.org" */ 86 if (!ConnectToReactOSWebsite(sck)) 87 { 88 WSACleanup(); 89 skip("ConnectToReactOSWebsite failed. Aborting test.\n"); 90 return; 91 } 92 93 /* prepare overlapped */ 94 memset(&overlapped, 0, sizeof(overlapped)); 95 overlapped.hEvent = WSACreateEvent(); 96 97 /* Send the GET request */ 98 buffers.buf = szGetRequest; 99 buffers.len = lstrlenA(szGetRequest); 100 dwSent = 0; 101 WSASetLastError(0xdeadbeef); 102 iResult = WSASend(sck, &buffers, 1, &dwSent, 0, &overlapped, NULL); 103 err = WSAGetLastError(); 104 ok(iResult == 0 || (iResult == SOCKET_ERROR && err == WSA_IO_PENDING), "iResult = %d, %d\n", iResult, err); 105 if (err == WSA_IO_PENDING) 106 { 107 iResult = WSAWaitForMultipleEvents(1, &overlapped.hEvent, TRUE, WSARecv_TIMEOUT, TRUE); 108 ok(iResult == WSA_WAIT_EVENT_0, "WSAWaitForMultipleEvents failed %d\n", iResult); 109 ret = WSAGetOverlappedResult(sck, &overlapped, &dwSent, TRUE, &dwFlags); 110 ok(ret, "WSAGetOverlappedResult failed %d\n", WSAGetLastError()); 111 } 112 ok(dwSent == strlen(szGetRequest), "dwSent %ld != %d\n", dwSent, strlen(szGetRequest)); 113 #if 0 /* break windows too */ 114 /* Shutdown the SEND connection */ 115 iResult = shutdown(sck, SD_SEND); 116 ok(iResult != SOCKET_ERROR, "iResult = %d\n", iResult); 117 #endif 118 /* Wait until we're ready to read */ 119 FD_ZERO(&readable); 120 FD_SET(sck, &readable); 121 122 iResult = select(0, &readable, NULL, NULL, NULL); 123 ok(iResult != SOCKET_ERROR, "iResult = %d\n", iResult); 124 125 /* Receive the data. */ 126 buffers.buf = szBuf; 127 buffers.len = sizeof(szBuf); 128 dwRecv = sizeof(szBuf); 129 iResult = WSARecv(sck, &buffers, 1, &dwRecv, &dwFlags, NULL, NULL); 130 ok(iResult != SOCKET_ERROR, "iResult = %d\n", iResult); 131 ok(dwRecv == sizeof(szBuf), "dwRecv %ld != %d\n", dwRecv, sizeof(szBuf)); 132 /* MSG_PEEK is invalid for overlapped (MSDN), but passes??? */ 133 buffers.buf = szRecvBuf; 134 buffers.len = sizeof(szRecvBuf); 135 dwFlags = MSG_PEEK; 136 dwRecv = sizeof(szRecvBuf); 137 ok(overlapped.hEvent != NULL, "WSACreateEvent failed %d\n", WSAGetLastError()); 138 WSASetLastError(0xdeadbeef); 139 iResult = WSARecv(sck, &buffers, 1, &dwRecv, &dwFlags, &overlapped, NULL); 140 err = WSAGetLastError(); 141 ok(iResult == 0 || (iResult == SOCKET_ERROR && err == WSA_IO_PENDING), "iResult = %d, %d\n", iResult, err); 142 if (err == WSA_IO_PENDING) 143 { 144 iResult = WSAWaitForMultipleEvents(1, &overlapped.hEvent, TRUE, WSARecv_TIMEOUT, TRUE); 145 ok(iResult == WSA_WAIT_EVENT_0, "WSAWaitForMultipleEvents failed %d\n", iResult); 146 ret = WSAGetOverlappedResult(sck, &overlapped, &dwRecv, TRUE, &dwFlags); 147 ok(ret, "WSAGetOverlappedResult failed %d\n", WSAGetLastError()); 148 } 149 ok(dwRecv == sizeof(szRecvBuf), "dwRecv %ld != %d\n", dwRecv, sizeof(szRecvBuf)); 150 /* normal overlapped, no completion */ 151 buffers.buf = szBuf; 152 buffers.len = sizeof(szBuf); 153 dwFlags = 0; 154 dwRecv = sizeof(szBuf); 155 WSAResetEvent(overlapped.hEvent); 156 WSASetLastError(0xdeadbeef); 157 iResult = WSARecv(sck, &buffers, 1, &dwRecv, &dwFlags, &overlapped, NULL); 158 err = WSAGetLastError(); 159 ok(iResult == 0 || (iResult == SOCKET_ERROR && err == WSA_IO_PENDING), "iResult = %d, %d\n", iResult, err); 160 if (err == WSA_IO_PENDING) 161 { 162 iResult = WSAWaitForMultipleEvents(1, &overlapped.hEvent, TRUE, WSARecv_TIMEOUT, TRUE); 163 ok(iResult == WSA_WAIT_EVENT_0, "WSAWaitForMultipleEvents failed %d\n", iResult); 164 ret = WSAGetOverlappedResult(sck, &overlapped, &dwRecv, TRUE, &dwFlags); 165 ok(ret, "WSAGetOverlappedResult failed %d\n", WSAGetLastError()); 166 } 167 ok(dwRecv == sizeof(szBuf), "dwRecv %ld != %d\n", dwRecv, sizeof(szBuf)); 168 ok(memcmp(szRecvBuf, szBuf, sizeof(szBuf)) == 0, "MSG_PEEK shouldn't have moved the pointer\n"); 169 /* overlapped with completion */ 170 dwFlags = 0; 171 dwRecv = sizeof(szBuf); 172 WSAResetEvent(overlapped.hEvent); 173 WSASetLastError(0xdeadbeef); 174 iResult = WSARecv(sck, &buffers, 1, &dwRecv, &dwFlags, &overlapped, &completion); 175 err = WSAGetLastError(); 176 ok(iResult == 0 || (iResult == SOCKET_ERROR && err == WSA_IO_PENDING), "iResult = %d, %d\n", iResult, err); 177 if (err == WSA_IO_PENDING) 178 { 179 iResult = WSAWaitForMultipleEvents(1, &overlapped.hEvent, TRUE, WSARecv_TIMEOUT, TRUE); 180 ok(iResult == WSA_WAIT_EVENT_0, "WSAWaitForMultipleEvents failed %d\n", iResult); 181 ret = WSAGetOverlappedResult(sck, &overlapped, &dwRecv, TRUE, &dwFlags); 182 ok(ret, "WSAGetOverlappedResult failed %d\n", WSAGetLastError()); 183 } 184 ret = WSACloseEvent(overlapped.hEvent); 185 ok(ret, "WSACloseEvent failed %d\n", WSAGetLastError()); 186 ok(dwRecv == sizeof(szBuf), "dwRecv %ld != %d\n", dwRecv, sizeof(szBuf)); 187 /* no overlapped with completion */ 188 dwFlags = 0; 189 dwRecv = sizeof(szBuf); 190 WSASetLastError(0xdeadbeef); 191 /* call doesn't fail, but completion is not called */ 192 iResult = WSARecv(sck, &buffers, 1, &dwRecv, &dwFlags, NULL, &completion); 193 err = WSAGetLastError(); 194 ok(iResult == 0 || (iResult == SOCKET_ERROR && err == WSA_IO_PENDING), "iResult = %d, %d\n", iResult, err); 195 ok(err == 0, "WSARecv failed %d\n", err); 196 ok(dwRecv == sizeof(szBuf), "dwRecv %ld != %d and 0\n", dwRecv, sizeof(szBuf)); 197 198 closesocket(sck); 199 WSACleanup(); 200 return; 201 } 202 203 START_TEST(WSARecv) 204 { 205 Test_WSARecv(); 206 } 207 208