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