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