[IPHLPAPI_APITEST] Add tests for interface resolving functions
[reactos.git] / modules / rostests / apitests / iphlpapi / GetInterfaceName.c
1 /*
2 * PROJECT: ReactOS API Tests
3 * LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
4 * PURPOSE: Tests for network interface name resolving functions
5 * COPYRIGHT: Copyright 2017 Stanislav Motylkov
6 */
7
8 #include <apitest.h>
9
10 #define WIN32_NO_STATUS
11 #include <iphlpapi.h>
12 #include <ndk/rtlfuncs.h>
13 #include <initguid.h>
14
15 DEFINE_GUID(MY_TEST_GUID, 0x8D1AB70F, 0xADF0, 0x49FC, 0x9D, 0x07, 0x4E, 0x89, 0x29, 0x2D, 0xC5, 0x2B);
16 static DWORD (WINAPI * pNhGetInterfaceNameFromGuid)(PVOID, PVOID, PULONG, DWORD, DWORD);
17 static DWORD (WINAPI * pNhGetInterfaceNameFromDeviceGuid)(PVOID, PVOID, PULONG, DWORD, DWORD);
18
19 /*
20 * Tests for NhGetInterfaceNameFromGuid
21 */
22 static
23 VOID
24 test_NhGetInterfaceNameFromGuid(GUID AdapterGUID, DWORD par1, DWORD par2)
25 {
26 DWORD ApiReturn, Error;
27 ULONG ulOutBufLen;
28 WCHAR Name[MAX_INTERFACE_NAME_LEN + 4];
29 GUID UniqueGUID = MY_TEST_GUID;
30
31 // Test NULL GUID
32 SetLastError(0xbeeffeed);
33 Error = 0xbeeffeed;
34 ZeroMemory(&Name, sizeof(Name));
35 ApiReturn = ERROR_SUCCESS;
36 ulOutBufLen = sizeof(Name);
37 StartSeh()
38 ApiReturn = pNhGetInterfaceNameFromGuid(NULL, &Name, &ulOutBufLen, par1, par2);
39 Error = GetLastError();
40 EndSeh(STATUS_SUCCESS);
41
42 ok(ApiReturn == ERROR_INVALID_PARAMETER,
43 "ApiReturn returned %ld, expected ERROR_INVALID_PARAMETER\n",
44 ApiReturn);
45 ok(Error == 0xbeeffeed,
46 "GetLastError() returned %ld, expected 0xbeeffeed\n",
47 Error);
48 ok(ulOutBufLen == sizeof(Name),
49 "ulOutBufLen is %ld, expected = sizeof(Name)\n",
50 ulOutBufLen);
51 ok_wstr(L"", Name);
52
53 // Test correct GUID, but NULL name
54 SetLastError(0xbeeffeed);
55 ZeroMemory(&Name, sizeof(Name));
56 ApiReturn = pNhGetInterfaceNameFromGuid(&AdapterGUID, NULL, &ulOutBufLen, par1, par2);
57 Error = GetLastError();
58
59 ok(ApiReturn == ERROR_SUCCESS,
60 "ApiReturn returned %ld, expected ERROR_SUCCESS\n",
61 ApiReturn);
62 ok(Error == 0xbeeffeed,
63 "GetLastError() returned %ld, expected 0xbeeffeed\n",
64 Error);
65 ok(ulOutBufLen > 0,
66 "ulOutBufLen is %ld, expected > 0\n",
67 ulOutBufLen);
68 ok_wstr(L"", Name);
69
70 // NhGetInterfaceNameFromGuid will throw exception if pOutBufLen is NULL
71 SetLastError(0xbeeffeed);
72 Error = 0xbeeffeed;
73 ZeroMemory(&Name, sizeof(Name));
74 ApiReturn = ERROR_SUCCESS;
75 StartSeh()
76 ApiReturn = pNhGetInterfaceNameFromGuid(&AdapterGUID, &Name, NULL, par1, par2);
77 Error = GetLastError();
78 EndSeh(STATUS_SUCCESS);
79
80 ok(ApiReturn == ERROR_INVALID_PARAMETER,
81 "ApiReturn returned %ld, expected ERROR_INVALID_PARAMETER\n",
82 ApiReturn);
83 ok(Error == 0xbeeffeed,
84 "GetLastError() returned %ld, expected 0xbeeffeed\n",
85 Error);
86 ok(ulOutBufLen > 0,
87 "ulOutBufLen is %ld, expected > 0\n",
88 ulOutBufLen);
89 ok_wstr(L"", Name);
90
91 // Test correct values
92 SetLastError(0xbeeffeed);
93 ZeroMemory(&Name, sizeof(Name));
94 ulOutBufLen = sizeof(Name);
95 ApiReturn = pNhGetInterfaceNameFromGuid(&AdapterGUID, &Name, &ulOutBufLen, par1, par2);
96 Error = GetLastError();
97
98 ok(ApiReturn == ERROR_SUCCESS,
99 "ApiReturn returned %ld, expected ERROR_SUCCESS\n",
100 ApiReturn);
101 ok(Error == 0xbeeffeed,
102 "GetLastError() returned %ld, expected 0xbeeffeed\n",
103 Error);
104 ok(ulOutBufLen > 0,
105 "ulOutBufLen is %ld, expected > 0\n",
106 ulOutBufLen);
107 Error = wcslen(Name);
108 ok(Error > 0,
109 "wcslen(Name) is %ld, expected > 0\n",
110 Error);
111 if (Error > 0)
112 trace("Adapter name: \"%S\"\n", Name);
113
114 // Test correct values, but with new unique GUID
115 SetLastError(0xbeeffeed);
116 ZeroMemory(&Name, sizeof(Name));
117 ulOutBufLen = sizeof(Name);
118 ApiReturn = pNhGetInterfaceNameFromGuid((PVOID)&UniqueGUID, &Name, &ulOutBufLen, par1, par2);
119 Error = GetLastError();
120
121 ok(ApiReturn == ERROR_NOT_FOUND,
122 "ApiReturn returned %ld, expected ERROR_NOT_FOUND\n",
123 ApiReturn);
124 ok(Error == ERROR_PATH_NOT_FOUND,
125 "GetLastError() returned %ld, expected ERROR_PATH_NOT_FOUND\n",
126 Error);
127 ok(ulOutBufLen == sizeof(Name),
128 "ulOutBufLen is %ld, expected = sizeof(Name)\n",
129 ulOutBufLen);
130 ok_wstr(L"", Name);
131
132 // Test correct values, but with small length
133 SetLastError(0xbeeffeed);
134 ZeroMemory(&Name, sizeof(Name));
135 ulOutBufLen = 0;
136 ApiReturn = pNhGetInterfaceNameFromGuid(&AdapterGUID, &Name, &ulOutBufLen, par1, par2);
137 Error = GetLastError();
138
139 ok(ApiReturn == ERROR_INSUFFICIENT_BUFFER,
140 "ApiReturn returned %ld, expected ERROR_INSUFFICIENT_BUFFER\n",
141 ApiReturn);
142 ok(Error == 0xbeeffeed,
143 "GetLastError() returned %ld, expected 0xbeeffeed\n",
144 Error);
145 ok(ulOutBufLen == MAX_INTERFACE_NAME_LEN * 2,
146 "ulOutBufLen is %ld, expected = MAX_INTERFACE_NAME_LEN * 2\n",
147 ulOutBufLen);
148 ok_wstr(L"", Name);
149 }
150
151 /*
152 * Tests for NhGetInterfaceNameFromDeviceGuid
153 */
154 static
155 VOID
156 test_NhGetInterfaceNameFromDeviceGuid(GUID AdapterGUID, DWORD par1, DWORD par2)
157 {
158 DWORD ApiReturn, Error;
159 ULONG ulOutBufLen;
160 WCHAR Name[MAX_INTERFACE_NAME_LEN];
161 GUID UniqueGUID = MY_TEST_GUID;
162
163 // Test NULL GUID
164 // Windows XP: NhGetInterfaceNameFromDeviceGuid throws exception here
165 SetLastError(0xbeeffeed);
166 Error = 0xbeeffeed;
167 ZeroMemory(&Name, sizeof(Name));
168 ApiReturn = ERROR_SUCCESS;
169 ulOutBufLen = sizeof(Name);
170 StartSeh()
171 ApiReturn = pNhGetInterfaceNameFromDeviceGuid(NULL, &Name, &ulOutBufLen, par1, par2);
172 Error = GetLastError();
173 EndSeh(STATUS_SUCCESS);
174
175 ok(ApiReturn == ERROR_INVALID_PARAMETER,
176 "ApiReturn returned %ld, expected ERROR_INVALID_PARAMETER\n",
177 ApiReturn);
178 ok(Error == ERROR_SUCCESS,
179 "GetLastError() returned %ld, expected ERROR_SUCCESS\n",
180 Error);
181 ok(ulOutBufLen == sizeof(Name),
182 "ulOutBufLen is %ld, expected = sizeof(Name)\n",
183 ulOutBufLen);
184 ok_wstr(L"", Name);
185
186 // Test correct GUID, but NULL name
187 SetLastError(0xbeeffeed);
188 Error = 0xbeeffeed;
189 ZeroMemory(&Name, sizeof(Name));
190 ApiReturn = ERROR_SUCCESS;
191 StartSeh()
192 ApiReturn = pNhGetInterfaceNameFromDeviceGuid(&AdapterGUID, NULL, &ulOutBufLen, par1, par2);
193 Error = GetLastError();
194 EndSeh(STATUS_SUCCESS);
195
196 ok(ApiReturn == ERROR_INVALID_PARAMETER,
197 "ApiReturn returned %ld, expected ERROR_INVALID_PARAMETER\n",
198 ApiReturn);
199 ok(Error == ERROR_SUCCESS,
200 "GetLastError() returned %ld, expected ERROR_SUCCESS\n",
201 Error);
202 ok(ulOutBufLen > 0,
203 "ulOutBufLen is %ld, expected > 0\n",
204 ulOutBufLen);
205 ok_wstr(L"", Name);
206
207 // NhGetInterfaceNameFromDeviceGuid will throw exception if pOutBufLen is NULL
208 SetLastError(0xbeeffeed);
209 Error = 0xbeeffeed;
210 ZeroMemory(&Name, sizeof(Name));
211 ApiReturn = ERROR_SUCCESS;
212 StartSeh()
213 ApiReturn = pNhGetInterfaceNameFromDeviceGuid(&AdapterGUID, &Name, NULL, par1, par2);
214 Error = GetLastError();
215 EndSeh(STATUS_SUCCESS);
216
217 ok(ApiReturn == ERROR_INVALID_PARAMETER,
218 "ApiReturn returned %ld, expected ERROR_INVALID_PARAMETER\n",
219 ApiReturn);
220 ok(Error == ERROR_SUCCESS,
221 "GetLastError() returned %ld, expected ERROR_SUCCESS\n",
222 Error);
223 ok(ulOutBufLen > 0,
224 "ulOutBufLen is %ld, expected > 0\n",
225 ulOutBufLen);
226 ok_wstr(L"", Name);
227
228 // Test correct values
229 SetLastError(0xbeeffeed);
230 ZeroMemory(&Name, sizeof(Name));
231 ulOutBufLen = sizeof(Name);
232 ApiReturn = pNhGetInterfaceNameFromDeviceGuid(&AdapterGUID, &Name, &ulOutBufLen, par1, par2);
233 Error = GetLastError();
234
235 ok(ApiReturn == ERROR_SUCCESS,
236 "ApiReturn returned %ld, expected ERROR_SUCCESS\n",
237 ApiReturn);
238 ok(Error == ERROR_SUCCESS,
239 "GetLastError() returned %ld, expected ERROR_SUCCESS\n",
240 Error);
241 ok(ulOutBufLen > 0,
242 "ulOutBufLen is %ld, expected > 0\n",
243 ulOutBufLen);
244 Error = wcslen(Name);
245 ok(Error > 0,
246 "wcslen(Name) is %ld, expected > 0\n",
247 Error);
248 if (Error > 0)
249 trace("Adapter name: \"%S\"\n", Name);
250
251 // Test correct values, but with new unique GUID
252 SetLastError(0xbeeffeed);
253 ZeroMemory(&Name, sizeof(Name));
254 ulOutBufLen = sizeof(Name);
255 ApiReturn = pNhGetInterfaceNameFromDeviceGuid((PVOID)&UniqueGUID, &Name, &ulOutBufLen, par1, par2);
256 Error = GetLastError();
257
258 ok(ApiReturn == ERROR_NOT_FOUND,
259 "ApiReturn returned %ld, expected ERROR_NOT_FOUND\n",
260 ApiReturn);
261 ok(Error == ERROR_SUCCESS,
262 "GetLastError() returned %ld, expected ERROR_SUCCESS\n",
263 Error);
264 ok(ulOutBufLen == sizeof(Name),
265 "ulOutBufLen is %ld, expected = sizeof(Name)\n",
266 ulOutBufLen);
267 ok_wstr(L"", Name);
268
269 // Test correct values, but with small length
270 SetLastError(0xbeeffeed);
271 ZeroMemory(&Name, sizeof(Name));
272 ulOutBufLen = 0;
273 ApiReturn = pNhGetInterfaceNameFromDeviceGuid(&AdapterGUID, &Name, &ulOutBufLen, par1, par2);
274 Error = GetLastError();
275
276 ok(ApiReturn == ERROR_INSUFFICIENT_BUFFER,
277 "ApiReturn returned %ld, expected ERROR_INSUFFICIENT_BUFFER\n",
278 ApiReturn);
279 ok(Error == ERROR_SUCCESS,
280 "GetLastError() returned %ld, expected ERROR_SUCCESS\n",
281 Error);
282 ok(ulOutBufLen == MAX_INTERFACE_NAME_LEN * 2,
283 "ulOutBufLen is %ld, expected = MAX_INTERFACE_NAME_LEN * 2\n",
284 ulOutBufLen);
285 ok_wstr(L"", Name);
286 }
287
288 static
289 VOID
290 test_GetInterfaceName(VOID)
291 {
292 PIP_INTERFACE_INFO pInfo = NULL;
293 ULONG ulOutBufLen = 0;
294 DWORD ApiReturn;
295 WCHAR Name[MAX_ADAPTER_NAME];
296 UNICODE_STRING GuidString;
297 GUID AdapterGUID;
298 HINSTANCE hIpHlpApi;
299
300 ApiReturn = GetInterfaceInfo(pInfo, &ulOutBufLen);
301 ok(ApiReturn == ERROR_INSUFFICIENT_BUFFER,
302 "GetInterfaceInfo(pInfo, &ulOutBufLen) returned %ld, expected ERROR_INSUFFICIENT_BUFFER\n",
303 ApiReturn);
304 if (ApiReturn != ERROR_INSUFFICIENT_BUFFER)
305 {
306 skip("Can't determine size of IP_INTERFACE_INFO. Can't proceed\n");
307 return;
308 }
309
310 pInfo = (IP_INTERFACE_INFO *)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, ulOutBufLen);
311 if (pInfo == NULL)
312 {
313 skip("pInfo is NULL. Can't proceed\n");
314 return;
315 }
316
317 ApiReturn = GetInterfaceInfo(pInfo, &ulOutBufLen);
318 ok(ApiReturn == NO_ERROR,
319 "GetInterfaceInfo(pInfo, &ulOutBufLen) returned %ld, expected NO_ERROR\n",
320 ApiReturn);
321 if (ApiReturn != NO_ERROR || ulOutBufLen == 0)
322 {
323 skip("GetInterfaceInfo failed with error %ld. Can't proceed\n", ApiReturn);
324 return;
325 }
326
327 if (pInfo->NumAdapters > 0)
328 CopyMemory(&Name, &pInfo->Adapter[0].Name, sizeof(Name));
329
330 if (pInfo->NumAdapters == 0)
331 {
332 HeapFree(GetProcessHeap(), 0, pInfo);
333 skip("pInfo->NumAdapters = 0. Can't proceed\n");
334 return;
335 }
336 trace("pInfo->NumAdapters: %lu\n", pInfo->NumAdapters);
337
338 HeapFree(GetProcessHeap(), 0, pInfo);
339
340 ApiReturn = wcsncmp(Name, L"\\DEVICE\\TCPIP_", 14);
341 ok(ApiReturn == 0,
342 "wcsncmp(Name, L\"\\DEVICE\\TCPIP_\", 14) returned %ld, expected 0\n",
343 ApiReturn);
344 if (ApiReturn != 0)
345 {
346 if (wcslen(Name) == 0)
347 {
348 skip("pInfo->Adapter[0].Name is empty. Can't proceed\n");
349 return;
350 }
351 else
352 {
353 // workaround for ReactOS
354 trace("pInfo->Adapter[0].Name = \"%ls\" is incorrect.\n", Name);
355 RtlInitUnicodeString(&GuidString, &Name[0]);
356 }
357 }
358 else
359 {
360 RtlInitUnicodeString(&GuidString, &Name[14]);
361 }
362
363 ApiReturn = RtlGUIDFromString(&GuidString, &AdapterGUID);
364 RtlFreeUnicodeString(&GuidString);
365 if (ApiReturn != 0)
366 {
367 skip("RtlGUIDFromString failed. Can't proceed\n");
368 return;
369 }
370
371 hIpHlpApi = GetModuleHandleW(L"iphlpapi.dll");
372 if (!hIpHlpApi)
373 {
374 skip("Failed to load iphlpapi.dll. Can't proceed\n");
375 return;
376 }
377
378 pNhGetInterfaceNameFromGuid = (void *)GetProcAddress(hIpHlpApi, "NhGetInterfaceNameFromGuid");
379
380 if (!pNhGetInterfaceNameFromGuid)
381 skip("NhGetInterfaceNameFromGuid not found. Can't proceed\n");
382 else
383 test_NhGetInterfaceNameFromGuid(AdapterGUID, 0, 0);
384
385 pNhGetInterfaceNameFromDeviceGuid = (void *)GetProcAddress(hIpHlpApi, "NhGetInterfaceNameFromDeviceGuid");
386
387 if (!pNhGetInterfaceNameFromDeviceGuid)
388 skip("NhGetInterfaceNameFromDeviceGuid not found. Can't proceed\n");
389 else
390 test_NhGetInterfaceNameFromDeviceGuid(AdapterGUID, 1, 0);
391 }
392
393 START_TEST(GetInterfaceName)
394 {
395 test_GetInterfaceName();
396 }