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