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 if (ApiReturn != 0) 365 { 366 skip("RtlGUIDFromString failed. Can't proceed\n"); 367 return; 368 } 369 370 hIpHlpApi = GetModuleHandleW(L"iphlpapi.dll"); 371 if (!hIpHlpApi) 372 { 373 skip("Failed to load iphlpapi.dll. Can't proceed\n"); 374 return; 375 } 376 377 pNhGetInterfaceNameFromGuid = (void *)GetProcAddress(hIpHlpApi, "NhGetInterfaceNameFromGuid"); 378 379 if (!pNhGetInterfaceNameFromGuid) 380 skip("NhGetInterfaceNameFromGuid not found. Can't proceed\n"); 381 else 382 test_NhGetInterfaceNameFromGuid(AdapterGUID, 0, 0); 383 384 pNhGetInterfaceNameFromDeviceGuid = (void *)GetProcAddress(hIpHlpApi, "NhGetInterfaceNameFromDeviceGuid"); 385 386 if (!pNhGetInterfaceNameFromDeviceGuid) 387 skip("NhGetInterfaceNameFromDeviceGuid not found. Can't proceed\n"); 388 else 389 test_NhGetInterfaceNameFromDeviceGuid(AdapterGUID, 1, 0); 390 } 391 392 START_TEST(GetInterfaceName) 393 { 394 test_GetInterfaceName(); 395 } 396