1 /* 2 * PROJECT: ReactOS api tests 3 * LICENSE: GPLv2+ - See COPYING in the top level directory 4 * PURPOSE: Test for WSAStartup 5 * PROGRAMMER: Thomas Faber <thomas.faber@reactos.org> 6 */ 7 8 #include "ws2_32.h" 9 10 static 11 PVOID 12 AllocateGuarded( 13 SIZE_T SizeRequested) 14 { 15 NTSTATUS Status; 16 SIZE_T Size = PAGE_ROUND_UP(SizeRequested + PAGE_SIZE); 17 PVOID VirtualMemory = NULL; 18 PCHAR StartOfBuffer; 19 20 Status = NtAllocateVirtualMemory(NtCurrentProcess(), &VirtualMemory, 0, &Size, MEM_RESERVE, PAGE_NOACCESS); 21 22 if (!NT_SUCCESS(Status)) 23 return NULL; 24 25 Size -= PAGE_SIZE; 26 if (Size) 27 { 28 Status = NtAllocateVirtualMemory(NtCurrentProcess(), &VirtualMemory, 0, &Size, MEM_COMMIT, PAGE_READWRITE); 29 if (!NT_SUCCESS(Status)) 30 { 31 Size = 0; 32 Status = NtFreeVirtualMemory(NtCurrentProcess(), &VirtualMemory, &Size, MEM_RELEASE); 33 ok(Status == STATUS_SUCCESS, "Status = %lx\n", Status); 34 return NULL; 35 } 36 } 37 38 StartOfBuffer = VirtualMemory; 39 StartOfBuffer += Size - SizeRequested; 40 41 return StartOfBuffer; 42 } 43 44 static 45 VOID 46 FreeGuarded( 47 PVOID Pointer) 48 { 49 NTSTATUS Status; 50 PVOID VirtualMemory = (PVOID)PAGE_ROUND_DOWN((SIZE_T)Pointer); 51 SIZE_T Size = 0; 52 53 Status = NtFreeVirtualMemory(NtCurrentProcess(), &VirtualMemory, &Size, MEM_RELEASE); 54 ok(Status == STATUS_SUCCESS, "Status = %lx\n", Status); 55 } 56 57 static 58 BOOLEAN 59 CheckStringBuffer( 60 PCSTR Buffer, 61 SIZE_T MaximumLength, 62 PCSTR Expected, 63 UCHAR Fill) 64 { 65 SIZE_T Length = strlen(Expected); 66 SIZE_T EqualLength; 67 BOOLEAN Result = TRUE; 68 SIZE_T i; 69 70 EqualLength = RtlCompareMemory(Buffer, Expected, Length); 71 if (EqualLength != Length) 72 { 73 ok(0, "String is '%.*s', expected '%s'\n", (int)MaximumLength, Buffer, Expected); 74 Result = FALSE; 75 } 76 77 if (Buffer[Length] != ANSI_NULL) 78 { 79 ok(0, "Not null terminated\n"); 80 Result = FALSE; 81 } 82 83 /* The function nulls the rest of the buffer! */ 84 for (i = Length + 1; i < MaximumLength; i++) 85 { 86 UCHAR Char = ((PUCHAR)Buffer)[i]; 87 if (Char != Fill) 88 { 89 ok(0, "Found 0x%x at offset %lu, expected 0x%x\n", Char, (ULONG)i, Fill); 90 /* Don't count this as a failure unless the string was actually wrong */ 91 //Result = FALSE; 92 /* Don't flood the log */ 93 break; 94 } 95 } 96 97 return Result; 98 } 99 100 static 101 BOOLEAN 102 IsWinsockInitialized(VOID) 103 { 104 struct hostent *Hostent; 105 106 Hostent = gethostbyname("localhost"); 107 if (!Hostent) 108 ok_dec(WSAGetLastError(), WSANOTINITIALISED); 109 return Hostent != NULL; 110 } 111 112 static 113 BOOLEAN 114 AreLegacyFunctionsSupported(VOID) 115 { 116 int Error; 117 118 Error = WSACancelBlockingCall(); 119 ok(Error == SOCKET_ERROR, "Error = %d\n", Error); 120 ok(WSAGetLastError() == WSAEOPNOTSUPP || 121 WSAGetLastError() == WSAEINVAL, "WSAGetLastError = %d\n", WSAGetLastError()); 122 123 return WSAGetLastError() != WSAEOPNOTSUPP; 124 } 125 126 START_TEST(WSAStartup) 127 { 128 BOOLEAN Okay; 129 LPWSADATA WsaData; 130 int Error; 131 struct 132 { 133 WORD Version; 134 BOOLEAN ExpectedSuccess; 135 WORD ExpectedVersion; 136 } Tests[] = 137 { 138 { MAKEWORD(0, 0), FALSE, MAKEWORD(2, 2) }, 139 { MAKEWORD(0, 9), FALSE, MAKEWORD(2, 2) }, 140 { MAKEWORD(1, 0), TRUE }, 141 { MAKEWORD(1, 1), TRUE }, 142 { MAKEWORD(1, 2), TRUE, MAKEWORD(1, 1) }, 143 { MAKEWORD(1, 15), TRUE, MAKEWORD(1, 1) }, 144 { MAKEWORD(1, 255), TRUE, MAKEWORD(1, 1) }, 145 { MAKEWORD(2, 0), TRUE }, 146 { MAKEWORD(2, 1), TRUE }, 147 { MAKEWORD(2, 2), TRUE }, 148 { MAKEWORD(2, 3), TRUE, MAKEWORD(2, 2) }, 149 { MAKEWORD(2, 15), TRUE, MAKEWORD(2, 2) }, 150 { MAKEWORD(2, 255), TRUE, MAKEWORD(2, 2) }, 151 { MAKEWORD(3, 0), TRUE, MAKEWORD(2, 2) }, 152 { MAKEWORD(3, 1), TRUE, MAKEWORD(2, 2) }, 153 { MAKEWORD(3, 2), TRUE, MAKEWORD(2, 2) }, 154 { MAKEWORD(3, 3), TRUE, MAKEWORD(2, 2) }, 155 { MAKEWORD(3, 15), TRUE, MAKEWORD(2, 2) }, 156 { MAKEWORD(3, 255), TRUE, MAKEWORD(2, 2) }, 157 { MAKEWORD(15, 255), TRUE, MAKEWORD(2, 2) }, 158 { MAKEWORD(255, 255), TRUE, MAKEWORD(2, 2) }, 159 }; 160 const INT TestCount = sizeof(Tests) / sizeof(Tests[0]); 161 INT i; 162 163 ok(!IsWinsockInitialized(), "Winsock unexpectedly initialized\n"); 164 165 /* parameter checks */ 166 StartSeh() 167 Error = WSAStartup(0, NULL); 168 ok_dec(Error, WSAVERNOTSUPPORTED); 169 ok_dec(WSAGetLastError(), WSANOTINITIALISED); 170 EndSeh(STATUS_SUCCESS); 171 StartSeh() 172 Error = WSAStartup(MAKEWORD(2, 2), NULL); 173 ok_dec(Error, WSAEFAULT); 174 ok_dec(WSAGetLastError(), WSANOTINITIALISED); 175 EndSeh(STATUS_SUCCESS); 176 ok(!IsWinsockInitialized(), "Winsock unexpectedly initialized\n"); 177 178 WsaData = AllocateGuarded(sizeof(*WsaData)); 179 if (!WsaData) 180 { 181 skip("Out of memory\n"); 182 return; 183 } 184 185 /* test different version */ 186 for (i = 0; i < TestCount; i++) 187 { 188 trace("%d: version %d.%d\n", 189 i, LOBYTE(Tests[i].Version), HIBYTE(Tests[i].Version)); 190 FillMemory(WsaData, sizeof(*WsaData), 0x55); 191 Error = WSANO_RECOVERY; 192 StartSeh() 193 Error = WSAStartup(Tests[i].Version, WsaData); 194 EndSeh(STATUS_SUCCESS); 195 if (Error) 196 { 197 ok(!Tests[i].ExpectedSuccess, "WSAStartup failed unexpectedly\n"); 198 ok_dec(Error, WSAVERNOTSUPPORTED); 199 ok_dec(WSAGetLastError(), WSANOTINITIALISED); 200 ok(!IsWinsockInitialized(), "Winsock unexpectedly initialized\n"); 201 } 202 else 203 { 204 ok(Tests[i].ExpectedSuccess, "WSAStartup succeeded unexpectedly\n"); 205 ok_dec(WSAGetLastError(), 0); 206 ok(IsWinsockInitialized(), "Winsock not initialized despite success\n"); 207 if (LOBYTE(Tests[i].Version) < 2) 208 ok(AreLegacyFunctionsSupported(), "Legacy function failed\n"); 209 else 210 ok(!AreLegacyFunctionsSupported(), "Legacy function succeeded\n"); 211 WSACleanup(); 212 ok(!IsWinsockInitialized(), "Winsock still initialized after cleanup\n"); 213 } 214 if (Tests[i].ExpectedVersion) 215 ok_hex(WsaData->wVersion, Tests[i].ExpectedVersion); 216 else 217 ok_hex(WsaData->wVersion, Tests[i].Version); 218 ok_hex(WsaData->wHighVersion, MAKEWORD(2, 2)); 219 Okay = CheckStringBuffer(WsaData->szDescription, 220 sizeof(WsaData->szDescription), 221 "WinSock 2.0", 222 0x55); 223 ok(Okay, "CheckStringBuffer failed\n"); 224 Okay = CheckStringBuffer(WsaData->szSystemStatus, 225 sizeof(WsaData->szSystemStatus), 226 "Running", 227 0x55); 228 ok(Okay, "CheckStringBuffer failed\n"); 229 if (LOBYTE(WsaData->wVersion) >= 2) 230 { 231 ok_dec(WsaData->iMaxSockets, 0); 232 ok_dec(WsaData->iMaxUdpDg, 0); 233 } 234 else 235 { 236 ok_dec(WsaData->iMaxSockets, 32767); 237 ok_dec(WsaData->iMaxUdpDg, 65467); 238 } 239 ok_ptr(WsaData->lpVendorInfo, (PVOID)0x5555555555555555ULL); 240 } 241 242 /* upgrade the version */ 243 FillMemory(WsaData, sizeof(*WsaData), 0x55); 244 Error = WSAStartup(MAKEWORD(1, 1), WsaData); 245 ok_dec(Error, 0); 246 ok_dec(WSAGetLastError(), 0); 247 ok_hex(WsaData->wVersion, MAKEWORD(1, 1)); 248 ok_hex(WsaData->wHighVersion, MAKEWORD(2, 2)); 249 Okay = CheckStringBuffer(WsaData->szDescription, 250 sizeof(WsaData->szDescription), 251 "WinSock 2.0", 252 0x55); 253 ok(Okay, "CheckStringBuffer failed\n"); 254 Okay = CheckStringBuffer(WsaData->szSystemStatus, 255 sizeof(WsaData->szSystemStatus), 256 "Running", 257 0x55); 258 ok(Okay, "CheckStringBuffer failed\n"); 259 ok_dec(WsaData->iMaxSockets, 32767); 260 ok_dec(WsaData->iMaxUdpDg, 65467); 261 ok_ptr(WsaData->lpVendorInfo, (PVOID)0x5555555555555555ULL); 262 ok(IsWinsockInitialized(), "Winsock not initialized\n"); 263 if (!Error) 264 { 265 ok(AreLegacyFunctionsSupported(), "Legacy function failed\n"); 266 FillMemory(WsaData, sizeof(*WsaData), 0x55); 267 Error = WSAStartup(MAKEWORD(2, 2), WsaData); 268 ok_dec(Error, 0); 269 ok_hex(WsaData->wVersion, MAKEWORD(2, 2)); 270 ok_hex(WsaData->wHighVersion, MAKEWORD(2, 2)); 271 Okay = CheckStringBuffer(WsaData->szDescription, 272 sizeof(WsaData->szDescription), 273 "WinSock 2.0", 274 0x55); 275 ok(Okay, "CheckStringBuffer failed\n"); 276 Okay = CheckStringBuffer(WsaData->szSystemStatus, 277 sizeof(WsaData->szSystemStatus), 278 "Running", 279 0x55); 280 ok(Okay, "CheckStringBuffer failed\n"); 281 ok_dec(WsaData->iMaxSockets, 0); 282 ok_dec(WsaData->iMaxUdpDg, 0); 283 ok_ptr(WsaData->lpVendorInfo, (PVOID)0x5555555555555555ULL); 284 if (!Error) 285 { 286 ok(AreLegacyFunctionsSupported(), "Legacy function failed\n"); 287 WSACleanup(); 288 ok(IsWinsockInitialized(), "Winsock prematurely uninitialized\n"); 289 } 290 WSACleanup(); 291 ok(!IsWinsockInitialized(), "Winsock still initialized after cleanup\n"); 292 } 293 294 /* downgrade the version */ 295 FillMemory(WsaData, sizeof(*WsaData), 0x55); 296 Error = WSAStartup(MAKEWORD(2, 2), WsaData); 297 ok_dec(Error, 0); 298 ok_dec(WSAGetLastError(), 0); 299 ok_hex(WsaData->wVersion, MAKEWORD(2, 2)); 300 ok_hex(WsaData->wHighVersion, MAKEWORD(2, 2)); 301 Okay = CheckStringBuffer(WsaData->szDescription, 302 sizeof(WsaData->szDescription), 303 "WinSock 2.0", 304 0x55); 305 ok(Okay, "CheckStringBuffer failed\n"); 306 Okay = CheckStringBuffer(WsaData->szSystemStatus, 307 sizeof(WsaData->szSystemStatus), 308 "Running", 309 0x55); 310 ok(Okay, "CheckStringBuffer failed\n"); 311 ok_dec(WsaData->iMaxSockets, 0); 312 ok_dec(WsaData->iMaxUdpDg, 0); 313 ok_ptr(WsaData->lpVendorInfo, (PVOID)0x5555555555555555ULL); 314 ok(IsWinsockInitialized(), "Winsock not initialized\n"); 315 if (!Error) 316 { 317 ok(!AreLegacyFunctionsSupported(), "Legacy function succeeded\n"); 318 FillMemory(WsaData, sizeof(*WsaData), 0x55); 319 Error = WSAStartup(MAKEWORD(1, 1), WsaData); 320 ok_dec(Error, 0); 321 ok_hex(WsaData->wVersion, MAKEWORD(1, 1)); 322 ok_hex(WsaData->wHighVersion, MAKEWORD(2, 2)); 323 Okay = CheckStringBuffer(WsaData->szDescription, 324 sizeof(WsaData->szDescription), 325 "WinSock 2.0", 326 0x55); 327 ok(Okay, "CheckStringBuffer failed\n"); 328 Okay = CheckStringBuffer(WsaData->szSystemStatus, 329 sizeof(WsaData->szSystemStatus), 330 "Running", 331 0x55); 332 ok(Okay, "CheckStringBuffer failed\n"); 333 ok_dec(WsaData->iMaxSockets, 32767); 334 ok_dec(WsaData->iMaxUdpDg, 65467); 335 ok_ptr(WsaData->lpVendorInfo, (PVOID)0x5555555555555555ULL); 336 if (!Error) 337 { 338 ok(AreLegacyFunctionsSupported(), "Legacy function failed\n"); 339 WSACleanup(); 340 ok(IsWinsockInitialized(), "Winsock prematurely uninitialized\n"); 341 } 342 WSACleanup(); 343 ok(!IsWinsockInitialized(), "Winsock still initialized after cleanup\n"); 344 } 345 346 FreeGuarded(WsaData); 347 } 348