Revert "winex11.drv: Optimise getting the bits of a DIB after calling SetDIBits."
[wine] / dlls / iphlpapi / tests / iphlpapi.c
1 /*
2  * iphlpapi dll test
3  *
4  * Copyright (C) 2003 Juan Lang
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19  */
20
21 /*
22  * Some observations that an automated test can't produce:
23  * An adapter index is a key for an adapter.  That is, if an index is returned
24  * from one API, that same index may be used successfully in another API, as
25  * long as the adapter remains present.
26  * If the adapter is removed and reinserted, however, the index may change (and
27  * indeed it does change on Win2K).
28  *
29  * The Name field of the IP_ADAPTER_INDEX_MAP entries returned by
30  * GetInterfaceInfo is declared as a wide string, but the bytes are actually
31  * an ASCII string on some versions of the IP helper API under Win9x.  This was
32  * apparently an MS bug, it's corrected in later versions.
33  *
34  * The DomainName field of FIXED_INFO isn't NULL-terminated on Win98.
35  */
36
37 #include <stdarg.h>
38 #include "windef.h"
39 #include "winbase.h"
40 #include "iphlpapi.h"
41 #include "iprtrmib.h"
42 #include "wine/test.h"
43 #include <stdio.h>
44 #include <stdlib.h>
45
46 static HMODULE hLibrary = NULL;
47
48 typedef DWORD (WINAPI *GetNumberOfInterfacesFunc)(PDWORD);
49 typedef DWORD (WINAPI *GetIpAddrTableFunc)(PMIB_IPADDRTABLE,PULONG,BOOL);
50 typedef DWORD (WINAPI *GetIfEntryFunc)(PMIB_IFROW);
51 typedef DWORD (WINAPI *GetFriendlyIfIndexFunc)(DWORD);
52 typedef DWORD (WINAPI *GetIfTableFunc)(PMIB_IFTABLE,PULONG,BOOL);
53 typedef DWORD (WINAPI *GetIpForwardTableFunc)(PMIB_IPFORWARDTABLE,PULONG,BOOL);
54 typedef DWORD (WINAPI *GetIpNetTableFunc)(PMIB_IPNETTABLE,PULONG,BOOL);
55 typedef DWORD (WINAPI *GetInterfaceInfoFunc)(PIP_INTERFACE_INFO,PULONG);
56 typedef DWORD (WINAPI *GetAdaptersInfoFunc)(PIP_ADAPTER_INFO,PULONG);
57 typedef DWORD (WINAPI *GetNetworkParamsFunc)(PFIXED_INFO,PULONG);
58 typedef DWORD (WINAPI *GetIcmpStatisticsFunc)(PMIB_ICMP);
59 typedef DWORD (WINAPI *GetIpStatisticsFunc)(PMIB_IPSTATS);
60 typedef DWORD (WINAPI *GetTcpStatisticsFunc)(PMIB_TCPSTATS);
61 typedef DWORD (WINAPI *GetUdpStatisticsFunc)(PMIB_UDPSTATS);
62 typedef DWORD (WINAPI *GetTcpTableFunc)(PMIB_TCPTABLE,PDWORD,BOOL);
63 typedef DWORD (WINAPI *GetUdpTableFunc)(PMIB_UDPTABLE,PDWORD,BOOL);
64 typedef DWORD (WINAPI *GetPerAdapterInfoFunc)(ULONG,PIP_PER_ADAPTER_INFO,PULONG);
65
66 static GetNumberOfInterfacesFunc gGetNumberOfInterfaces = NULL;
67 static GetIpAddrTableFunc gGetIpAddrTable = NULL;
68 static GetIfEntryFunc gGetIfEntry = NULL;
69 static GetFriendlyIfIndexFunc gGetFriendlyIfIndex = NULL;
70 static GetIfTableFunc gGetIfTable = NULL;
71 static GetIpForwardTableFunc gGetIpForwardTable = NULL;
72 static GetIpNetTableFunc gGetIpNetTable = NULL;
73 static GetInterfaceInfoFunc gGetInterfaceInfo = NULL;
74 static GetAdaptersInfoFunc gGetAdaptersInfo = NULL;
75 static GetNetworkParamsFunc gGetNetworkParams = NULL;
76 static GetIcmpStatisticsFunc gGetIcmpStatistics = NULL;
77 static GetIpStatisticsFunc gGetIpStatistics = NULL;
78 static GetTcpStatisticsFunc gGetTcpStatistics = NULL;
79 static GetUdpStatisticsFunc gGetUdpStatistics = NULL;
80 static GetTcpTableFunc gGetTcpTable = NULL;
81 static GetUdpTableFunc gGetUdpTable = NULL;
82 static GetPerAdapterInfoFunc gGetPerAdapterInfo = NULL;
83
84 static void loadIPHlpApi(void)
85 {
86   hLibrary = LoadLibraryA("iphlpapi.dll");
87   if (hLibrary) {
88     gGetNumberOfInterfaces = (GetNumberOfInterfacesFunc)GetProcAddress(
89      hLibrary, "GetNumberOfInterfaces");
90     gGetIpAddrTable = (GetIpAddrTableFunc)GetProcAddress(
91      hLibrary, "GetIpAddrTable");
92     gGetIfEntry = (GetIfEntryFunc)GetProcAddress(
93      hLibrary, "GetIfEntry");
94     gGetFriendlyIfIndex = (GetFriendlyIfIndexFunc)GetProcAddress(
95      hLibrary, "GetFriendlyIfIndex");
96     gGetIfTable = (GetIfTableFunc)GetProcAddress(
97      hLibrary, "GetIfTable");
98     gGetIpForwardTable = (GetIpForwardTableFunc)GetProcAddress(
99      hLibrary, "GetIpForwardTable");
100     gGetIpNetTable = (GetIpNetTableFunc)GetProcAddress(
101      hLibrary, "GetIpNetTable");
102     gGetInterfaceInfo = (GetInterfaceInfoFunc)GetProcAddress(
103      hLibrary, "GetInterfaceInfo");
104     gGetAdaptersInfo = (GetAdaptersInfoFunc)GetProcAddress(
105      hLibrary, "GetAdaptersInfo");
106     gGetNetworkParams = (GetNetworkParamsFunc)GetProcAddress(
107      hLibrary, "GetNetworkParams");
108     gGetIcmpStatistics = (GetIcmpStatisticsFunc)GetProcAddress(
109      hLibrary, "GetIcmpStatistics");
110     gGetIpStatistics = (GetIpStatisticsFunc)GetProcAddress(
111      hLibrary, "GetIpStatistics");
112     gGetTcpStatistics = (GetTcpStatisticsFunc)GetProcAddress(
113      hLibrary, "GetTcpStatistics");
114     gGetUdpStatistics = (GetUdpStatisticsFunc)GetProcAddress(
115      hLibrary, "GetUdpStatistics");
116     gGetTcpTable = (GetTcpTableFunc)GetProcAddress(
117      hLibrary, "GetTcpTable");
118     gGetUdpTable = (GetUdpTableFunc)GetProcAddress(
119      hLibrary, "GetUdpTable");
120     gGetPerAdapterInfo = (GetPerAdapterInfoFunc)GetProcAddress(hLibrary, "GetPerAdapterInfo");
121   }
122 }
123
124 static void freeIPHlpApi(void)
125 {
126   if (hLibrary) {
127     gGetNumberOfInterfaces = NULL;
128     gGetIpAddrTable = NULL;
129     gGetIfEntry = NULL;
130     gGetFriendlyIfIndex = NULL;
131     gGetIfTable = NULL;
132     gGetIpForwardTable = NULL;
133     gGetIpNetTable = NULL;
134     gGetInterfaceInfo = NULL;
135     gGetAdaptersInfo = NULL;
136     gGetNetworkParams = NULL;
137     gGetIcmpStatistics = NULL;
138     gGetIpStatistics = NULL;
139     gGetTcpStatistics = NULL;
140     gGetUdpStatistics = NULL;
141     gGetTcpTable = NULL;
142     gGetUdpTable = NULL;
143     FreeLibrary(hLibrary);
144     hLibrary = NULL;
145   }
146 }
147
148 /*
149 still-to-be-tested 98-only functions:
150 GetUniDirectionalAdapterInfo
151 */
152 static void testWin98OnlyFunctions(void)
153 {
154 }
155
156 static void testGetNumberOfInterfaces(void)
157 {
158   if (gGetNumberOfInterfaces) {
159     DWORD apiReturn, numInterfaces;
160
161     /* Crashes on Vista */
162     if (0) {
163       apiReturn = gGetNumberOfInterfaces(NULL), numInterfaces;
164       if (apiReturn == ERROR_NOT_SUPPORTED)
165         return;
166       ok(apiReturn == ERROR_INVALID_PARAMETER,
167        "GetNumberOfInterfaces(NULL) returned %d, expected ERROR_INVALID_PARAMETER\n",
168        apiReturn);
169     }
170
171     apiReturn = gGetNumberOfInterfaces(&numInterfaces);
172     if (apiReturn == ERROR_NOT_SUPPORTED) {
173       skip("GetNumberOfInterfaces is not supported\n");
174       return;
175     }
176     ok(apiReturn == NO_ERROR,
177      "GetNumberOfInterfaces returned %d, expected 0\n", apiReturn);
178   }
179 }
180
181 static void testGetIfEntry(DWORD index)
182 {
183   if (gGetIfEntry) {
184     DWORD apiReturn;
185     MIB_IFROW row;
186
187     memset(&row, 0, sizeof(row));
188     apiReturn = gGetIfEntry(NULL);
189     if (apiReturn == ERROR_NOT_SUPPORTED)
190       return;
191     ok(apiReturn == ERROR_INVALID_PARAMETER,
192      "GetIfEntry(NULL) returned %d, expected ERROR_INVALID_PARAMETER\n",
193      apiReturn);
194     row.dwIndex = -1; /* hope that's always bogus! */
195     apiReturn = gGetIfEntry(&row);
196     ok(apiReturn == ERROR_INVALID_DATA ||
197      apiReturn == ERROR_FILE_NOT_FOUND /* Vista */,
198      "GetIfEntry(bogus row) returned %d, expected ERROR_INVALID_DATA or ERROR_FILE_NOT_FOUND\n",
199      apiReturn);
200     row.dwIndex = index;
201     apiReturn = gGetIfEntry(&row);
202     ok(apiReturn == NO_ERROR, 
203      "GetIfEntry returned %d, expected NO_ERROR\n", apiReturn);
204   }
205 }
206
207 static void testGetIpAddrTable(void)
208 {
209   if (gGetIpAddrTable) {
210     DWORD apiReturn;
211     ULONG dwSize = 0;
212
213     apiReturn = gGetIpAddrTable(NULL, NULL, FALSE);
214     if (apiReturn == ERROR_NOT_SUPPORTED)
215       return;
216     ok(apiReturn == ERROR_INVALID_PARAMETER,
217      "GetIpAddrTable(NULL, NULL, FALSE) returned %d, expected ERROR_INVALID_PARAMETER\n",
218      apiReturn);
219     apiReturn = gGetIpAddrTable(NULL, &dwSize, FALSE);
220     ok(apiReturn == ERROR_INSUFFICIENT_BUFFER,
221      "GetIpAddrTable(NULL, &dwSize, FALSE) returned %d, expected ERROR_INSUFFICIENT_BUFFER\n",
222      apiReturn);
223     if (apiReturn == ERROR_INSUFFICIENT_BUFFER) {
224       PMIB_IPADDRTABLE buf = (PMIB_IPADDRTABLE)malloc(dwSize);
225
226       apiReturn = gGetIpAddrTable(buf, &dwSize, FALSE);
227       ok(apiReturn == NO_ERROR,
228        "GetIpAddrTable(buf, &dwSize, FALSE) returned %d, expected NO_ERROR\n",
229        apiReturn);
230       if (apiReturn == NO_ERROR && buf->dwNumEntries)
231         testGetIfEntry(buf->table[0].dwIndex);
232       free(buf);
233     }
234   }
235 }
236
237 static void testGetIfTable(void)
238 {
239   if (gGetIfTable) {
240     DWORD apiReturn;
241     ULONG dwSize = 0;
242
243     apiReturn = gGetIfTable(NULL, NULL, FALSE);
244     if (apiReturn == ERROR_NOT_SUPPORTED)
245       return;
246     ok(apiReturn == ERROR_INVALID_PARAMETER,
247      "GetIfTable(NULL, NULL, FALSE) returned %d, expected ERROR_INVALID_PARAMETER\n",
248      apiReturn);
249     apiReturn = gGetIfTable(NULL, &dwSize, FALSE);
250     ok(apiReturn == ERROR_INSUFFICIENT_BUFFER,
251      "GetIfTable(NULL, &dwSize, FALSE) returned %d, expected ERROR_INSUFFICIENT_BUFFER\n",
252      apiReturn);
253     if (apiReturn == ERROR_INSUFFICIENT_BUFFER) {
254       PMIB_IFTABLE buf = (PMIB_IFTABLE)malloc(dwSize);
255
256       apiReturn = gGetIfTable(buf, &dwSize, FALSE);
257       ok(apiReturn == NO_ERROR,
258        "GetIfTable(buf, &dwSize, FALSE) returned %d, expected NO_ERROR\n\n",
259        apiReturn);
260       free(buf);
261     }
262   }
263 }
264
265 static void testGetIpForwardTable(void)
266 {
267   if (gGetIpForwardTable) {
268     DWORD apiReturn;
269     ULONG dwSize = 0;
270
271     apiReturn = gGetIpForwardTable(NULL, NULL, FALSE);
272     if (apiReturn == ERROR_NOT_SUPPORTED)
273       return;
274     ok(apiReturn == ERROR_INVALID_PARAMETER,
275      "GetIpForwardTable(NULL, NULL, FALSE) returned %d, expected ERROR_INVALID_PARAMETER\n",
276      apiReturn);
277     apiReturn = gGetIpForwardTable(NULL, &dwSize, FALSE);
278     ok(apiReturn == ERROR_INSUFFICIENT_BUFFER,
279      "GetIpForwardTable(NULL, &dwSize, FALSE) returned %d, expected ERROR_INSUFFICIENT_BUFFER\n",
280      apiReturn);
281     if (apiReturn == ERROR_INSUFFICIENT_BUFFER) {
282       PMIB_IPFORWARDTABLE buf = (PMIB_IPFORWARDTABLE)malloc(dwSize);
283
284       apiReturn = gGetIpForwardTable(buf, &dwSize, FALSE);
285       ok(apiReturn == NO_ERROR,
286        "GetIpForwardTable(buf, &dwSize, FALSE) returned %d, expected NO_ERROR\n",
287        apiReturn);
288       free(buf);
289     }
290   }
291 }
292
293 static void testGetIpNetTable(void)
294 {
295   if (gGetIpNetTable) {
296     DWORD apiReturn;
297     ULONG dwSize = 0;
298
299     apiReturn = gGetIpNetTable(NULL, NULL, FALSE);
300     if (apiReturn == ERROR_NOT_SUPPORTED)
301       return;
302     ok(apiReturn == ERROR_INVALID_PARAMETER,
303      "GetIpNetTable(NULL, NULL, FALSE) returned %d, expected ERROR_INVALID_PARAMETER\n",
304      apiReturn);
305     apiReturn = gGetIpNetTable(NULL, &dwSize, FALSE);
306     ok(apiReturn == ERROR_NO_DATA || apiReturn == ERROR_INSUFFICIENT_BUFFER,
307      "GetIpNetTable(NULL, &dwSize, FALSE) returned %d, expected ERROR_NO_DATA or ERROR_INSUFFICIENT_BUFFER\n",
308      apiReturn);
309     if (apiReturn == ERROR_NO_DATA)
310       ; /* empty ARP table's okay */
311     else if (apiReturn == ERROR_INSUFFICIENT_BUFFER) {
312       PMIB_IPNETTABLE buf = (PMIB_IPNETTABLE)malloc(dwSize);
313
314       apiReturn = gGetIpNetTable(buf, &dwSize, FALSE);
315       ok(apiReturn == NO_ERROR,
316        "GetIpNetTable(buf, &dwSize, FALSE) returned %d, expected NO_ERROR\n",
317        apiReturn);
318       free(buf);
319     }
320   }
321 }
322
323 static void testGetIcmpStatistics(void)
324 {
325   if (gGetIcmpStatistics) {
326     DWORD apiReturn;
327     MIB_ICMP stats;
328
329     /* Crashes on Vista */
330     if (0) {
331       apiReturn = gGetIcmpStatistics(NULL);
332       if (apiReturn == ERROR_NOT_SUPPORTED)
333         return;
334       ok(apiReturn == ERROR_INVALID_PARAMETER,
335        "GetIcmpStatistics(NULL) returned %d, expected ERROR_INVALID_PARAMETER\n",
336        apiReturn);
337     }
338
339     apiReturn = gGetIcmpStatistics(&stats);
340     if (apiReturn == ERROR_NOT_SUPPORTED)
341     {
342       skip("GetIcmpStatistics is not supported\n");
343       return;
344     }
345     ok(apiReturn == NO_ERROR,
346      "GetIcmpStatistics returned %d, expected NO_ERROR\n", apiReturn);
347   }
348 }
349
350 static void testGetIpStatistics(void)
351 {
352   if (gGetIpStatistics) {
353     DWORD apiReturn;
354     MIB_IPSTATS stats;
355
356     apiReturn = gGetIpStatistics(NULL);
357     if (apiReturn == ERROR_NOT_SUPPORTED)
358       return;
359     ok(apiReturn == ERROR_INVALID_PARAMETER,
360      "GetIpStatistics(NULL) returned %d, expected ERROR_INVALID_PARAMETER\n",
361      apiReturn);
362     apiReturn = gGetIpStatistics(&stats);
363     ok(apiReturn == NO_ERROR,
364       "GetIpStatistics returned %d, expected NO_ERROR\n", apiReturn);
365   }
366 }
367
368 static void testGetTcpStatistics(void)
369 {
370   if (gGetTcpStatistics) {
371     DWORD apiReturn;
372     MIB_TCPSTATS stats;
373
374     apiReturn = gGetTcpStatistics(NULL);
375     if (apiReturn == ERROR_NOT_SUPPORTED)
376       return;
377     ok(apiReturn == ERROR_INVALID_PARAMETER,
378      "GetTcpStatistics(NULL) returned %d, expected ERROR_INVALID_PARAMETER\n",
379      apiReturn);
380     apiReturn = gGetTcpStatistics(&stats);
381     ok(apiReturn == NO_ERROR,
382       "GetTcpStatistics returned %d, expected NO_ERROR\n", apiReturn);
383   }
384 }
385
386 static void testGetUdpStatistics(void)
387 {
388   if (gGetUdpStatistics) {
389     DWORD apiReturn;
390     MIB_UDPSTATS stats;
391
392     apiReturn = gGetUdpStatistics(NULL);
393     if (apiReturn == ERROR_NOT_SUPPORTED)
394       return;
395     ok(apiReturn == ERROR_INVALID_PARAMETER,
396      "GetUdpStatistics(NULL) returned %d, expected ERROR_INVALID_PARAMETER\n",
397      apiReturn);
398     apiReturn = gGetUdpStatistics(&stats);
399     ok(apiReturn == NO_ERROR,
400      "GetUdpStatistics returned %d, expected NO_ERROR\n", apiReturn);
401   }
402 }
403
404 static void testGetTcpTable(void)
405 {
406   if (gGetTcpTable) {
407     DWORD apiReturn;
408     ULONG dwSize = 0;
409
410     apiReturn = gGetTcpTable(NULL, NULL, FALSE);
411     if (apiReturn == ERROR_NOT_SUPPORTED)
412       return;
413     ok(apiReturn == ERROR_INVALID_PARAMETER,
414      "GetTcpTable(NULL, NULL, FALSE) returned %d, expected ERROR_INVALID_PARAMETER\n",
415      apiReturn);
416     apiReturn = gGetTcpTable(NULL, &dwSize, FALSE);
417     ok(apiReturn == ERROR_INSUFFICIENT_BUFFER,
418      "GetTcpTable(NULL, &dwSize, FALSE) returned %d, expected ERROR_INSUFFICIENT_BUFFER\n",
419      apiReturn);
420     if (apiReturn == ERROR_INSUFFICIENT_BUFFER) {
421       PMIB_TCPTABLE buf = (PMIB_TCPTABLE)malloc(dwSize);
422
423       apiReturn = gGetTcpTable(buf, &dwSize, FALSE);
424       ok(apiReturn == NO_ERROR,
425        "GetTcpTable(buf, &dwSize, FALSE) returned %d, expected NO_ERROR\n",
426        apiReturn);
427       free(buf);
428     }
429   }
430 }
431
432 static void testGetUdpTable(void)
433 {
434   if (gGetUdpTable) {
435     DWORD apiReturn;
436     ULONG dwSize = 0;
437
438     apiReturn = gGetUdpTable(NULL, NULL, FALSE);
439     if (apiReturn == ERROR_NOT_SUPPORTED)
440       return;
441     ok(apiReturn == ERROR_INVALID_PARAMETER,
442      "GetUdpTable(NULL, NULL, FALSE) returned %d, expected ERROR_INVALID_PARAMETER\n",
443      apiReturn);
444     apiReturn = gGetUdpTable(NULL, &dwSize, FALSE);
445     ok(apiReturn == ERROR_INSUFFICIENT_BUFFER,
446      "GetUdpTable(NULL, &dwSize, FALSE) returned %d, expected ERROR_INSUFFICIENT_BUFFER\n",
447      apiReturn);
448     if (apiReturn != ERROR_INSUFFICIENT_BUFFER) {
449       PMIB_UDPTABLE buf = (PMIB_UDPTABLE)malloc(dwSize);
450
451       apiReturn = gGetUdpTable(buf, &dwSize, FALSE);
452       ok(apiReturn == NO_ERROR,
453        "GetUdpTable(buf, &dwSize, FALSE) returned %d, expected NO_ERROR\n",
454        apiReturn);
455       free(buf);
456     }
457   }
458 }
459
460 /*
461 still-to-be-tested NT4-onward functions:
462 CreateIpForwardEntry
463 DeleteIpForwardEntry
464 CreateIpNetEntry
465 DeleteIpNetEntry
466 GetFriendlyIfIndex
467 GetRTTAndHopCount
468 SetIfEntry
469 SetIpForwardEntry
470 SetIpNetEntry
471 SetIpStatistics
472 SetIpTTL
473 SetTcpEntry
474 */
475 static void testWinNT4Functions(void)
476 {
477   testGetNumberOfInterfaces();
478   testGetIpAddrTable();
479   testGetIfTable();
480   testGetIpForwardTable();
481   testGetIpNetTable();
482   testGetIcmpStatistics();
483   testGetIpStatistics();
484   testGetTcpStatistics();
485   testGetUdpStatistics();
486   testGetTcpTable();
487   testGetUdpTable();
488 }
489
490 static void testGetInterfaceInfo(void)
491 {
492   if (gGetInterfaceInfo) {
493     DWORD apiReturn;
494     ULONG len = 0;
495
496     apiReturn = gGetInterfaceInfo(NULL, NULL);
497     if (apiReturn == ERROR_NOT_SUPPORTED)
498       return;
499     ok(apiReturn == ERROR_INVALID_PARAMETER,
500      "GetInterfaceInfo returned %d, expected ERROR_INVALID_PARAMETER\n",
501      apiReturn);
502     apiReturn = gGetInterfaceInfo(NULL, &len);
503     ok(apiReturn == ERROR_INSUFFICIENT_BUFFER,
504      "GetInterfaceInfo returned %d, expected ERROR_INSUFFICIENT_BUFFER\n",
505      apiReturn);
506     if (apiReturn == ERROR_INSUFFICIENT_BUFFER) {
507       PIP_INTERFACE_INFO buf = (PIP_INTERFACE_INFO)malloc(len);
508
509       apiReturn = gGetInterfaceInfo(buf, &len);
510       ok(apiReturn == NO_ERROR,
511        "GetInterfaceInfo(buf, &dwSize) returned %d, expected NO_ERROR\n",
512        apiReturn);
513       free(buf);
514     }
515   }
516 }
517
518 static void testGetAdaptersInfo(void)
519 {
520   if (gGetAdaptersInfo) {
521     DWORD apiReturn;
522     ULONG len = 0;
523
524     apiReturn = gGetAdaptersInfo(NULL, NULL);
525     if (apiReturn == ERROR_NOT_SUPPORTED)
526       return;
527     ok(apiReturn == ERROR_INVALID_PARAMETER,
528      "GetAdaptersInfo returned %d, expected ERROR_INVALID_PARAMETER\n",
529      apiReturn);
530     apiReturn = gGetAdaptersInfo(NULL, &len);
531     ok(apiReturn == ERROR_NO_DATA || apiReturn == ERROR_BUFFER_OVERFLOW,
532      "GetAdaptersInfo returned %d, expected ERROR_NO_DATA or ERROR_BUFFER_OVERFLOW\n",
533      apiReturn);
534     if (apiReturn == ERROR_NO_DATA)
535       ; /* no adapter's, that's okay */
536     else if (apiReturn == ERROR_BUFFER_OVERFLOW) {
537       PIP_ADAPTER_INFO buf = (PIP_ADAPTER_INFO)malloc(len);
538
539       apiReturn = gGetAdaptersInfo(buf, &len);
540       ok(apiReturn == NO_ERROR,
541        "GetAdaptersInfo(buf, &dwSize) returned %d, expected NO_ERROR\n",
542        apiReturn);
543       free(buf);
544     }
545   }
546 }
547
548 static void testGetNetworkParams(void)
549 {
550   if (gGetNetworkParams) {
551     DWORD apiReturn;
552     ULONG len = 0;
553
554     apiReturn = gGetNetworkParams(NULL, NULL);
555     if (apiReturn == ERROR_NOT_SUPPORTED)
556       return;
557     ok(apiReturn == ERROR_INVALID_PARAMETER,
558      "GetNetworkParams returned %d, expected ERROR_INVALID_PARAMETER\n",
559      apiReturn);
560     apiReturn = gGetNetworkParams(NULL, &len);
561     ok(apiReturn == ERROR_BUFFER_OVERFLOW,
562      "GetNetworkParams returned %d, expected ERROR_BUFFER_OVERFLOW\n",
563      apiReturn);
564     if (apiReturn == ERROR_BUFFER_OVERFLOW) {
565       PFIXED_INFO buf = (PFIXED_INFO)malloc(len);
566
567       apiReturn = gGetNetworkParams(buf, &len);
568       ok(apiReturn == NO_ERROR,
569        "GetNetworkParams(buf, &dwSize) returned %d, expected NO_ERROR\n",
570        apiReturn);
571       free(buf);
572     }
573   }
574 }
575
576 /*
577 still-to-be-tested 98-onward functions:
578 GetBestInterface
579 GetBestRoute
580 IpReleaseAddress
581 IpRenewAddress
582 */
583 static void testWin98Functions(void)
584 {
585   testGetInterfaceInfo();
586   testGetAdaptersInfo();
587   testGetNetworkParams();
588 }
589
590 static void testGetPerAdapterInfo(void)
591 {
592     DWORD ret, needed;
593     void *buffer;
594
595     if (!gGetPerAdapterInfo) return;
596     ret = gGetPerAdapterInfo(1, NULL, NULL);
597     ok( ret == ERROR_INVALID_PARAMETER, "got %u instead of ERROR_INVALID_PARAMETER\n", ret );
598     needed = 0xdeadbeef;
599     ret = gGetPerAdapterInfo(1, NULL, &needed);
600     if (ret == ERROR_NO_DATA) return;  /* no such adapter */
601     ok( ret == ERROR_BUFFER_OVERFLOW, "got %u instead of ERROR_BUFFER_OVERFLOW\n", ret );
602     ok( needed != 0xdeadbeef, "needed not set\n" );
603     buffer = HeapAlloc( GetProcessHeap(), 0, needed );
604     ret = gGetPerAdapterInfo(1, buffer, &needed);
605     ok( ret == NO_ERROR, "got %u instead of NO_ERROR\n", ret );
606     HeapFree( GetProcessHeap(), 0, buffer );
607 }
608
609 /*
610 still-to-be-tested 2K-onward functions:
611 AddIPAddress
612 CreateProxyArpEntry
613 DeleteIPAddress
614 DeleteProxyArpEntry
615 EnableRouter
616 FlushIpNetTable
617 GetAdapterIndex
618 NotifyAddrChange
619 NotifyRouteChange
620 SendARP
621 UnenableRouter
622 */
623 static void testWin2KFunctions(void)
624 {
625     testGetPerAdapterInfo();
626 }
627
628 START_TEST(iphlpapi)
629 {
630
631   loadIPHlpApi();
632   if (hLibrary) {
633     testWin98OnlyFunctions();
634     testWinNT4Functions();
635     testWin98Functions();
636     testWin2KFunctions();
637     freeIPHlpApi();
638   }
639 }