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