Fix subclassing to support nested messages.
[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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  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 "config.h"
38
39 #include <stdarg.h>
40 #include "windef.h"
41 #include "winbase.h"
42 #include "iphlpapi.h"
43 #include "iprtrmib.h"
44 #include "wine/test.h"
45 #include <sys/types.h>
46 #if HAVE_SYS_SOCKET_H
47 #include <sys/socket.h>
48 #endif
49 #include <stdio.h>
50 #include <stdlib.h>
51
52 static HMODULE hLibrary = NULL;
53
54 typedef DWORD (WINAPI *GetNumberOfInterfacesFunc)(PDWORD);
55 typedef DWORD (WINAPI *GetIpAddrTableFunc)(PMIB_IPADDRTABLE,PULONG,BOOL);
56 typedef DWORD (WINAPI *GetIfEntryFunc)(PMIB_IFROW);
57 typedef DWORD (WINAPI *GetFriendlyIfIndexFunc)(DWORD);
58 typedef DWORD (WINAPI *GetIfTableFunc)(PMIB_IFTABLE,PULONG,BOOL);
59 typedef DWORD (WINAPI *GetIpForwardTableFunc)(PMIB_IPFORWARDTABLE,PULONG,BOOL);
60 typedef DWORD (WINAPI *GetIpNetTableFunc)(PMIB_IPNETTABLE,PULONG,BOOL);
61 typedef DWORD (WINAPI *GetInterfaceInfoFunc)(PIP_INTERFACE_INFO,PULONG);
62 typedef DWORD (WINAPI *GetAdaptersInfoFunc)(PIP_ADAPTER_INFO,PULONG);
63 typedef DWORD (WINAPI *GetNetworkParamsFunc)(PFIXED_INFO,PULONG);
64 typedef DWORD (WINAPI *GetIcmpStatisticsFunc)(PMIB_ICMP);
65 typedef DWORD (WINAPI *GetIpStatisticsFunc)(PMIB_IPSTATS);
66 typedef DWORD (WINAPI *GetTcpStatisticsFunc)(PMIB_TCPSTATS);
67 typedef DWORD (WINAPI *GetUdpStatisticsFunc)(PMIB_UDPSTATS);
68 typedef DWORD (WINAPI *GetTcpTableFunc)(PMIB_TCPTABLE,PDWORD,BOOL);
69 typedef DWORD (WINAPI *GetUdpTableFunc)(PMIB_UDPTABLE,PDWORD,BOOL);
70
71 static GetNumberOfInterfacesFunc gGetNumberOfInterfaces = NULL;
72 static GetIpAddrTableFunc gGetIpAddrTable = NULL;
73 static GetIfEntryFunc gGetIfEntry = NULL;
74 static GetFriendlyIfIndexFunc gGetFriendlyIfIndex = NULL;
75 static GetIfTableFunc gGetIfTable = NULL;
76 static GetIpForwardTableFunc gGetIpForwardTable = NULL;
77 static GetIpNetTableFunc gGetIpNetTable = NULL;
78 static GetInterfaceInfoFunc gGetInterfaceInfo = NULL;
79 static GetAdaptersInfoFunc gGetAdaptersInfo = NULL;
80 static GetNetworkParamsFunc gGetNetworkParams = NULL;
81 static GetIcmpStatisticsFunc gGetIcmpStatistics = NULL;
82 static GetIpStatisticsFunc gGetIpStatistics = NULL;
83 static GetTcpStatisticsFunc gGetTcpStatistics = NULL;
84 static GetUdpStatisticsFunc gGetUdpStatistics = NULL;
85 static GetTcpTableFunc gGetTcpTable = NULL;
86 static GetUdpTableFunc gGetUdpTable = NULL;
87
88 static void loadIPHlpApi(void)
89 {
90   hLibrary = LoadLibraryA("iphlpapi.dll");
91   if (hLibrary) {
92     gGetNumberOfInterfaces = (GetNumberOfInterfacesFunc)GetProcAddress(
93      hLibrary, "GetNumberOfInterfaces");
94     gGetIpAddrTable = (GetIpAddrTableFunc)GetProcAddress(
95      hLibrary, "GetIpAddrTable");
96     gGetIfEntry = (GetIfEntryFunc)GetProcAddress(
97      hLibrary, "GetIfEntry");
98     gGetFriendlyIfIndex = (GetFriendlyIfIndexFunc)GetProcAddress(
99      hLibrary, "GetFriendlyIfIndex");
100     gGetIfTable = (GetIfTableFunc)GetProcAddress(
101      hLibrary, "GetIfTable");
102     gGetIpForwardTable = (GetIpForwardTableFunc)GetProcAddress(
103      hLibrary, "GetIpForwardTable");
104     gGetIpNetTable = (GetIpNetTableFunc)GetProcAddress(
105      hLibrary, "GetIpNetTable");
106     gGetInterfaceInfo = (GetInterfaceInfoFunc)GetProcAddress(
107      hLibrary, "GetInterfaceInfo");
108     gGetAdaptersInfo = (GetAdaptersInfoFunc)GetProcAddress(
109      hLibrary, "GetAdaptersInfo");
110     gGetNetworkParams = (GetNetworkParamsFunc)GetProcAddress(
111      hLibrary, "GetNetworkParams");
112     gGetIcmpStatistics = (GetIcmpStatisticsFunc)GetProcAddress(
113      hLibrary, "GetIcmpStatistics");
114     gGetIpStatistics = (GetIpStatisticsFunc)GetProcAddress(
115      hLibrary, "GetIpStatistics");
116     gGetTcpStatistics = (GetTcpStatisticsFunc)GetProcAddress(
117      hLibrary, "GetTcpStatistics");
118     gGetUdpStatistics = (GetUdpStatisticsFunc)GetProcAddress(
119      hLibrary, "GetUdpStatistics");
120     gGetTcpTable = (GetTcpTableFunc)GetProcAddress(
121      hLibrary, "GetTcpTable");
122     gGetUdpTable = (GetUdpTableFunc)GetProcAddress(
123      hLibrary, "GetUdpTable");
124   }
125 }
126
127 static void freeIPHlpApi(void)
128 {
129   if (hLibrary) {
130     gGetNumberOfInterfaces = NULL;
131     gGetIpAddrTable = NULL;
132     gGetIfEntry = NULL;
133     gGetFriendlyIfIndex = NULL;
134     gGetIfTable = NULL;
135     gGetIpForwardTable = NULL;
136     gGetIpNetTable = NULL;
137     gGetInterfaceInfo = NULL;
138     gGetAdaptersInfo = NULL;
139     gGetNetworkParams = NULL;
140     gGetIcmpStatistics = NULL;
141     gGetIpStatistics = NULL;
142     gGetTcpStatistics = NULL;
143     gGetUdpStatistics = NULL;
144     gGetTcpTable = NULL;
145     gGetUdpTable = NULL;
146     FreeLibrary(hLibrary);
147     hLibrary = NULL;
148   }
149 }
150
151 /*
152 still-to-be-tested 98-only functions:
153 GetUniDirectionalAdapterInfo
154 */
155 void testWin98OnlyFunctions(void)
156 {
157 }
158
159 static void testGetNumberOfInterfaces(void)
160 {
161   if (gGetNumberOfInterfaces) {
162     DWORD apiReturn = gGetNumberOfInterfaces(NULL), numInterfaces;
163
164     if (apiReturn == ERROR_NOT_SUPPORTED)
165       return;
166     ok(apiReturn == ERROR_INVALID_PARAMETER, 
167      "GetNumberOfInterfaces(NULL) returned %ld, expected ERROR_INVALID_PARAMETER\n",
168      apiReturn);
169     apiReturn = gGetNumberOfInterfaces(&numInterfaces);
170     ok(apiReturn == NO_ERROR,
171      "GetNumberOfInterfaces returned %ld, expected 0\n", apiReturn);
172   }
173 }
174
175 static void testGetIfEntry(DWORD index)
176 {
177   if (gGetIfEntry) {
178     DWORD apiReturn;
179     MIB_IFROW row;
180
181     memset(&row, 0, sizeof(row));
182     apiReturn = gGetIfEntry(NULL);
183     if (apiReturn == ERROR_NOT_SUPPORTED)
184       return;
185     ok(apiReturn == ERROR_INVALID_PARAMETER,
186      "GetIfEntry(NULL) returned %ld, expected ERROR_INVALID_PARAMETER\n",
187      apiReturn);
188     row.dwIndex = -1; /* hope that's always bogus! */
189     apiReturn = gGetIfEntry(&row);
190     ok(apiReturn == ERROR_INVALID_DATA,
191      "GetIfEntry(bogus row) returned %ld, expected ERROR_INVALID_DATA\n",
192      apiReturn);
193     row.dwIndex = index;
194     apiReturn = gGetIfEntry(&row);
195     ok(apiReturn == NO_ERROR, 
196      "GetIfEntry returned %ld, expected NO_ERROR\n", apiReturn);
197   }
198 }
199
200 static void testGetIpAddrTable(void)
201 {
202   if (gGetIpAddrTable) {
203     DWORD apiReturn;
204     ULONG dwSize = 0;
205
206     apiReturn = gGetIpAddrTable(NULL, NULL, FALSE);
207     if (apiReturn == ERROR_NOT_SUPPORTED)
208       return;
209     ok(apiReturn == ERROR_INVALID_PARAMETER,
210      "GetIpAddrTable(NULL, NULL, FALSE) returned %ld, expected ERROR_INVALID_PARAMETER\n",
211      apiReturn);
212     apiReturn = gGetIpAddrTable(NULL, &dwSize, FALSE);
213     ok(apiReturn == ERROR_INSUFFICIENT_BUFFER,
214      "GetIpAddrTable(NULL, &dwSize, FALSE) returned %ld, expected ERROR_INSUFFICIENT_BUFFER\n",
215      apiReturn);
216     if (apiReturn == ERROR_INSUFFICIENT_BUFFER) {
217       PMIB_IPADDRTABLE buf = (PMIB_IPADDRTABLE)malloc(dwSize);
218
219       apiReturn = gGetIpAddrTable(buf, &dwSize, FALSE);
220       ok(apiReturn == NO_ERROR,
221        "GetIpAddrTable(buf, &dwSize, FALSE) returned %ld, expected NO_ERROR\n",
222        apiReturn);
223       if (apiReturn == NO_ERROR)
224         testGetIfEntry(buf->table[0].dwIndex);
225       free(buf);
226     }
227   }
228 }
229
230 static void testGetIfTable(void)
231 {
232   if (gGetIfTable) {
233     DWORD apiReturn;
234     ULONG dwSize = 0;
235
236     apiReturn = gGetIfTable(NULL, NULL, FALSE);
237     if (apiReturn == ERROR_NOT_SUPPORTED)
238       return;
239     ok(apiReturn == ERROR_INVALID_PARAMETER,
240      "GetIfTable(NULL, NULL, FALSE) returned %ld, expected ERROR_INVALID_PARAMETER\n",
241      apiReturn);
242     apiReturn = gGetIfTable(NULL, &dwSize, FALSE);
243     ok(apiReturn == ERROR_INSUFFICIENT_BUFFER,
244      "GetIfTable(NULL, &dwSize, FALSE) returned %ld, expected ERROR_INSUFFICIENT_BUFFER\n",
245      apiReturn);
246     if (apiReturn == ERROR_INSUFFICIENT_BUFFER) {
247       PMIB_IFTABLE buf = (PMIB_IFTABLE)malloc(dwSize);
248
249       apiReturn = gGetIfTable(buf, &dwSize, FALSE);
250       ok(apiReturn == NO_ERROR,
251        "GetIfTable(buf, &dwSize, FALSE) returned %ld, expected NO_ERROR\n\n",
252        apiReturn);
253       free(buf);
254     }
255   }
256 }
257
258 static void testGetIpForwardTable(void)
259 {
260   if (gGetIpForwardTable) {
261     DWORD apiReturn;
262     ULONG dwSize = 0;
263
264     apiReturn = gGetIpForwardTable(NULL, NULL, FALSE);
265     if (apiReturn == ERROR_NOT_SUPPORTED)
266       return;
267     ok(apiReturn == ERROR_INVALID_PARAMETER,
268      "GetIpForwardTable(NULL, NULL, FALSE) returned %ld, expected ERROR_INVALID_PARAMETER\n",
269      apiReturn);
270     apiReturn = gGetIpForwardTable(NULL, &dwSize, FALSE);
271     ok(apiReturn == ERROR_INSUFFICIENT_BUFFER,
272      "GetIpForwardTable(NULL, &dwSize, FALSE) returned %ld, expected ERROR_INSUFFICIENT_BUFFER\n",
273      apiReturn);
274     if (apiReturn == ERROR_INSUFFICIENT_BUFFER) {
275       PMIB_IPFORWARDTABLE buf = (PMIB_IPFORWARDTABLE)malloc(dwSize);
276
277       apiReturn = gGetIpForwardTable(buf, &dwSize, FALSE);
278       ok(apiReturn == NO_ERROR,
279        "GetIpForwardTable(buf, &dwSize, FALSE) returned %ld, expected NO_ERROR\n",
280        apiReturn);
281       if (apiReturn == NO_ERROR)
282         ok(buf->dwNumEntries > 0,
283           "Got 0 IP forward table entries, expect at least 1\n");
284       free(buf);
285     }
286   }
287 }
288
289 void testGetIpNetTable(void)
290 {
291   if (gGetIpNetTable) {
292     DWORD apiReturn;
293     ULONG dwSize = 0;
294
295     apiReturn = gGetIpNetTable(NULL, NULL, FALSE);
296     if (apiReturn == ERROR_NOT_SUPPORTED)
297       return;
298     ok(apiReturn == ERROR_INVALID_PARAMETER,
299      "GetIpNetTable(NULL, NULL, FALSE) returned %ld, expected ERROR_INVALID_PARAMETER\n",
300      apiReturn);
301     apiReturn = gGetIpNetTable(NULL, &dwSize, FALSE);
302     ok(apiReturn == ERROR_NO_DATA || apiReturn == ERROR_INSUFFICIENT_BUFFER,
303      "GetIpNetTable(NULL, &dwSize, FALSE) returned %ld, expected ERROR_NO_DATA or ERROR_INSUFFICIENT_BUFFER\n",
304      apiReturn);
305     if (apiReturn == ERROR_NO_DATA)
306       ; /* empty ARP table's okay */
307     else if (apiReturn == ERROR_INSUFFICIENT_BUFFER) {
308       PMIB_IPNETTABLE buf = (PMIB_IPNETTABLE)malloc(dwSize);
309
310       apiReturn = gGetIpNetTable(buf, &dwSize, FALSE);
311       ok(apiReturn == NO_ERROR,
312        "GetIpNetTable(buf, &dwSize, FALSE) returned %ld, expected NO_ERROR\n",
313        apiReturn);
314       free(buf);
315     }
316   }
317 }
318
319 void testGetIcmpStatistics(void)
320 {
321   if (gGetIcmpStatistics) {
322     DWORD apiReturn;
323     MIB_ICMP stats;
324
325     apiReturn = gGetIcmpStatistics(NULL);
326     if (apiReturn == ERROR_NOT_SUPPORTED)
327       return;
328     ok(apiReturn == ERROR_INVALID_PARAMETER,
329      "GetIcmpStatistics(NULL) returned %ld, expected ERROR_INVALID_PARAMETER\n",
330      apiReturn);
331     apiReturn = gGetIcmpStatistics(&stats);
332     ok(apiReturn == NO_ERROR,
333      "GetIcmpStatistics returned %ld, expected NO_ERROR\n", apiReturn);
334   }
335 }
336
337 void testGetIpStatistics(void)
338 {
339   if (gGetIpStatistics) {
340     DWORD apiReturn;
341     MIB_IPSTATS stats;
342
343     apiReturn = gGetIpStatistics(NULL);
344     if (apiReturn == ERROR_NOT_SUPPORTED)
345       return;
346     ok(apiReturn == ERROR_INVALID_PARAMETER,
347      "GetIpStatistics(NULL) returned %ld, expected ERROR_INVALID_PARAMETER\n",
348      apiReturn);
349     apiReturn = gGetIpStatistics(&stats);
350     ok(apiReturn == NO_ERROR,
351       "GetIpStatistics returned %ld, expected NO_ERROR\n", apiReturn);
352   }
353 }
354
355 void testGetTcpStatistics(void)
356 {
357   if (gGetTcpStatistics) {
358     DWORD apiReturn;
359     MIB_TCPSTATS stats;
360
361     apiReturn = gGetTcpStatistics(NULL);
362     if (apiReturn == ERROR_NOT_SUPPORTED)
363       return;
364     ok(apiReturn == ERROR_INVALID_PARAMETER,
365      "GetTcpStatistics(NULL) returned %ld, expected ERROR_INVALID_PARAMETER\n",
366      apiReturn);
367     apiReturn = gGetTcpStatistics(&stats);
368     ok(apiReturn == NO_ERROR,
369       "GetTcpStatistics returned %ld, expected NO_ERROR\n", apiReturn);
370   }
371 }
372
373 void testGetUdpStatistics(void)
374 {
375   if (gGetUdpStatistics) {
376     DWORD apiReturn;
377     MIB_UDPSTATS stats;
378
379     apiReturn = gGetUdpStatistics(NULL);
380     if (apiReturn == ERROR_NOT_SUPPORTED)
381       return;
382     ok(apiReturn == ERROR_INVALID_PARAMETER,
383      "GetUdpStatistics(NULL) returned %ld, expected ERROR_INVALID_PARAMETER\n",
384      apiReturn);
385     apiReturn = gGetUdpStatistics(&stats);
386     ok(apiReturn == NO_ERROR,
387      "GetUdpStatistics returned %ld, expected NO_ERROR\n", apiReturn);
388   }
389 }
390
391 void testGetTcpTable(void)
392 {
393   if (gGetTcpTable) {
394     DWORD apiReturn;
395     ULONG dwSize = 0;
396
397     apiReturn = gGetTcpTable(NULL, NULL, FALSE);
398     if (apiReturn == ERROR_NOT_SUPPORTED)
399       return;
400     ok(apiReturn == ERROR_INVALID_PARAMETER,
401      "GetTcpTable(NULL, NULL, FALSE) returned %ld, expected ERROR_INVALID_PARAMETER\n",
402      apiReturn);
403     apiReturn = gGetTcpTable(NULL, &dwSize, FALSE);
404     ok(apiReturn == ERROR_INSUFFICIENT_BUFFER,
405      "GetTcpTable(NULL, &dwSize, FALSE) returned %ld, expected ERROR_INSUFFICIENT_BUFFER\n",
406      apiReturn);
407     if (apiReturn == ERROR_INSUFFICIENT_BUFFER) {
408       PMIB_TCPTABLE buf = (PMIB_TCPTABLE)malloc(dwSize);
409
410       apiReturn = gGetTcpTable(buf, &dwSize, FALSE);
411       ok(apiReturn == NO_ERROR,
412        "GetTcpTable(buf, &dwSize, FALSE) returned %ld, expected NO_ERROR\n",
413        apiReturn);
414       free(buf);
415     }
416   }
417 }
418
419 void testGetUdpTable(void)
420 {
421   if (gGetUdpTable) {
422     DWORD apiReturn;
423     ULONG dwSize = 0;
424
425     apiReturn = gGetUdpTable(NULL, NULL, FALSE);
426     if (apiReturn == ERROR_NOT_SUPPORTED)
427       return;
428     ok(apiReturn == ERROR_INVALID_PARAMETER,
429      "GetUdpTable(NULL, NULL, FALSE) returned %ld, expected ERROR_INVALID_PARAMETER\n",
430      apiReturn);
431     apiReturn = gGetUdpTable(NULL, &dwSize, FALSE);
432     ok(apiReturn == ERROR_INSUFFICIENT_BUFFER,
433      "GetUdpTable(NULL, &dwSize, FALSE) returned %ld, expected ERROR_INSUFFICIENT_BUFFER\n",
434      apiReturn);
435     if (apiReturn != ERROR_INSUFFICIENT_BUFFER) {
436       PMIB_UDPTABLE buf = (PMIB_UDPTABLE)malloc(dwSize);
437
438       apiReturn = gGetUdpTable(buf, &dwSize, FALSE);
439       ok(apiReturn == NO_ERROR,
440        "GetUdpTable(buf, &dwSize, FALSE) returned %ld, expected NO_ERROR\n",
441        apiReturn);
442       free(buf);
443     }
444   }
445 }
446
447 /*
448 still-to-be-tested NT4-onward functions:
449 CreateIpForwardEntry
450 DeleteIpForwardEntry
451 CreateIpNetEntry
452 DeleteIpNetEntry
453 GetFriendlyIfIndex
454 GetRTTAndHopCount
455 SetIfEntry
456 SetIpForwardEntry
457 SetIpNetEntry
458 SetIpStatistics
459 SetIpTTL
460 SetTcpEntry
461 */
462 static void testWinNT4Functions(void)
463 {
464   testGetNumberOfInterfaces();
465   testGetIpAddrTable();
466   testGetIfTable();
467   testGetIpForwardTable();
468   testGetIpNetTable();
469   testGetIcmpStatistics();
470   testGetIpStatistics();
471   testGetTcpStatistics();
472   testGetUdpStatistics();
473   testGetTcpTable();
474   testGetUdpTable();
475 }
476
477 static void testGetInterfaceInfo(void)
478 {
479   if (gGetInterfaceInfo) {
480     DWORD apiReturn;
481     ULONG len = 0;
482
483     apiReturn = gGetInterfaceInfo(NULL, NULL);
484     if (apiReturn == ERROR_NOT_SUPPORTED)
485       return;
486     ok(apiReturn == ERROR_INVALID_PARAMETER,
487      "GetInterfaceInfo returned %ld, expected ERROR_INVALID_PARAMETER\n",
488      apiReturn);
489     apiReturn = gGetInterfaceInfo(NULL, &len);
490     ok(apiReturn == ERROR_INSUFFICIENT_BUFFER,
491      "GetInterfaceInfo returned %ld, expected ERROR_INSUFFICIENT_BUFFER\n",
492      apiReturn);
493     if (apiReturn == ERROR_INSUFFICIENT_BUFFER) {
494       PIP_INTERFACE_INFO buf = (PIP_INTERFACE_INFO)malloc(len);
495
496       apiReturn = gGetInterfaceInfo(buf, &len);
497       ok(apiReturn == NO_ERROR,
498        "GetInterfaceInfo(buf, &dwSize) returned %ld, expected NO_ERROR\n",
499        apiReturn);
500       free(buf);
501     }
502   }
503 }
504
505 static void testGetAdaptersInfo(void)
506 {
507   if (gGetAdaptersInfo) {
508     DWORD apiReturn;
509     ULONG len = 0;
510
511     apiReturn = gGetAdaptersInfo(NULL, NULL);
512     if (apiReturn == ERROR_NOT_SUPPORTED)
513       return;
514     ok(apiReturn == ERROR_INVALID_PARAMETER,
515      "GetAdaptersInfo returned %ld, expected ERROR_INVALID_PARAMETER\n",
516      apiReturn);
517     apiReturn = gGetAdaptersInfo(NULL, &len);
518     ok(apiReturn == ERROR_NO_DATA || apiReturn == ERROR_BUFFER_OVERFLOW,
519      "GetAdaptersInfo returned %ld, expected ERROR_NO_DATA or ERROR_BUFFER_OVERFLOW\n",
520      apiReturn);
521     if (apiReturn == ERROR_NO_DATA)
522       ; /* no adapter's, that's okay */
523     else if (apiReturn == ERROR_BUFFER_OVERFLOW) {
524       PIP_ADAPTER_INFO buf = (PIP_ADAPTER_INFO)malloc(len);
525
526       apiReturn = gGetAdaptersInfo(buf, &len);
527       ok(apiReturn == NO_ERROR,
528        "GetAdaptersInfo(buf, &dwSize) returned %ld, expected NO_ERROR\n",
529        apiReturn);
530       free(buf);
531     }
532   }
533 }
534
535 static void testGetNetworkParams(void)
536 {
537   if (gGetNetworkParams) {
538     DWORD apiReturn;
539     ULONG len = 0;
540
541     apiReturn = gGetNetworkParams(NULL, NULL);
542     if (apiReturn == ERROR_NOT_SUPPORTED)
543       return;
544     ok(apiReturn == ERROR_INVALID_PARAMETER,
545      "GetNetworkParams returned %ld, expected ERROR_INVALID_PARAMETER\n",
546      apiReturn);
547     apiReturn = gGetNetworkParams(NULL, &len);
548     ok(apiReturn == ERROR_BUFFER_OVERFLOW,
549      "GetNetworkParams returned %ld, expected ERROR_BUFFER_OVERFLOW\n",
550      apiReturn);
551     if (apiReturn == ERROR_BUFFER_OVERFLOW) {
552       PFIXED_INFO buf = (PFIXED_INFO)malloc(len);
553
554       apiReturn = gGetNetworkParams(buf, &len);
555       ok(apiReturn == NO_ERROR,
556        "GetNetworkParams(buf, &dwSize) returned %ld, expected NO_ERROR\n",
557        apiReturn);
558       free(buf);
559     }
560   }
561 }
562
563 /*
564 still-to-be-tested 98-onward functions:
565 GetBestInterface
566 GetBestRoute
567 IpReleaseAddress
568 IpRenewAddress
569 */
570 static void testWin98Functions(void)
571 {
572   testGetInterfaceInfo();
573   testGetAdaptersInfo();
574   testGetNetworkParams();
575 }
576
577 /*
578 still-to-be-tested 2K-onward functions:
579 AddIPAddress
580 CreateProxyArpEntry
581 DeleteIPAddress
582 DeleteProxyArpEntry
583 EnableRouter
584 FlushIpNetTable
585 GetAdapterIndex
586 GetPerAdapterInfo
587 NotifyAddrChange
588 NotifyRouteChange
589 SendARP
590 UnenableRouter
591 */
592 static void testWin2KFunctions(void)
593 {
594 }
595
596 START_TEST(iphlpapi)
597 {
598
599   loadIPHlpApi();
600   if (hLibrary) {
601     testWin98OnlyFunctions();
602     testWinNT4Functions();
603     testWin98Functions();
604     testWin2KFunctions();
605     freeIPHlpApi();
606   }
607 }