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(((GetVersion() & 0xFF) >= 6) ? STATUS_SUCCESS : STATUS_ACCESS_VIOLATION); 42 43 ok_long(ApiReturn, ((GetVersion() & 0xFF) >= 6) ? 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, ((GetVersion() & 0xFF) >= 6) ? ERROR_INVALID_PARAMETER : ERROR_SUCCESS); 59 ok_long(Error, ((GetVersion() & 0xFF) >= 6) ? 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, ((GetVersion() & 0xFF) >= 6) ? 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, ((GetVersion() & 0xFF) >= 6) ? ERROR_INVALID_PARAMETER : ERROR_NOT_FOUND); 115 ok_long(Error, 0); 116 ok(ulOutBufLen == sizeof(Name), 117 "ulOutBufLen is %ld, expected = sizeof(Name)\n", 118 ulOutBufLen); 119 ok_wstr(L"", Name); 120 121 // Test correct values, but with small length 122 SetLastError(0xbeeffeed); 123 ZeroMemory(&Name, sizeof(Name)); 124 ulOutBufLen = 0; 125 ApiReturn = pNhGetInterfaceNameFromGuid(&AdapterGUID, &Name, &ulOutBufLen, par1, par2); 126 Error = GetLastError(); 127 128 ok_long(ApiReturn, ((GetVersion() & 0xFF) >= 6) ? ERROR_NOT_ENOUGH_MEMORY : ERROR_INSUFFICIENT_BUFFER); 129 ok_long(Error, ((GetVersion() & 0xFF) >= 6) ? 0 : 0xbeeffeed); 130 ok_long(ulOutBufLen, MAX_INTERFACE_NAME_LEN * 2 + ((GetVersion() & 0xFF) >= 6 ? 2 : 0)); 131 ok_wstr(L"", Name); 132 } 133 134 /* 135 * Tests for NhGetInterfaceNameFromDeviceGuid 136 */ 137 static 138 VOID 139 test_NhGetInterfaceNameFromDeviceGuid(GUID AdapterGUID, DWORD par1, DWORD par2) 140 { 141 DWORD ApiReturn, Error; 142 ULONG ulOutBufLen; 143 WCHAR Name[MAX_INTERFACE_NAME_LEN]; 144 GUID UniqueGUID = MY_TEST_GUID; 145 SIZE_T Length; 146 147 // Test NULL GUID 148 // Windows XP: NhGetInterfaceNameFromDeviceGuid throws exception here 149 SetLastError(0xbeeffeed); 150 Error = 0xbeeffeed; 151 ZeroMemory(&Name, sizeof(Name)); 152 ApiReturn = ERROR_SUCCESS; 153 ulOutBufLen = sizeof(Name); 154 StartSeh() 155 ApiReturn = pNhGetInterfaceNameFromDeviceGuid(NULL, &Name, &ulOutBufLen, par1, par2); 156 Error = GetLastError(); 157 EndSeh(((GetVersion() & 0xFF) >= 6) ? STATUS_SUCCESS : STATUS_ACCESS_VIOLATION); 158 159 ok_long(ApiReturn, ((GetVersion() & 0xFF) >= 6) ? ERROR_INVALID_PARAMETER : 0); 160 ok(Error == 0xbeeffeed, 161 "GetLastError() returned %ld, expected ERROR_SUCCESS\n", 162 Error); 163 ok(ulOutBufLen == sizeof(Name), 164 "ulOutBufLen is %ld, expected = sizeof(Name)\n", 165 ulOutBufLen); 166 ok_wstr(L"", Name); 167 168 // Test correct GUID, but NULL name 169 SetLastError(0xbeeffeed); 170 Error = 0xbeeffeed; 171 ZeroMemory(&Name, sizeof(Name)); 172 ApiReturn = ERROR_SUCCESS; 173 StartSeh() 174 ApiReturn = pNhGetInterfaceNameFromDeviceGuid(&AdapterGUID, NULL, &ulOutBufLen, par1, par2); 175 Error = GetLastError(); 176 EndSeh(((GetVersion() & 0xFF) >= 6) ? STATUS_SUCCESS : STATUS_ACCESS_VIOLATION); 177 178 ok_long(ApiReturn, ((GetVersion() & 0xFF) >= 6) ? ERROR_INVALID_PARAMETER : 0); 179 ok_long(Error, ((GetVersion() & 0xFF) >= 6) ? ERROR_SUCCESS : 0xbeeffeed); 180 ok(ulOutBufLen > 0, 181 "ulOutBufLen is %ld, expected > 0\n", 182 ulOutBufLen); 183 ok_wstr(L"", Name); 184 185 // NhGetInterfaceNameFromDeviceGuid will throw exception if pOutBufLen is NULL 186 SetLastError(0xbeeffeed); 187 Error = 0xbeeffeed; 188 ZeroMemory(&Name, sizeof(Name)); 189 ApiReturn = ERROR_SUCCESS; 190 StartSeh() 191 ApiReturn = pNhGetInterfaceNameFromDeviceGuid(&AdapterGUID, &Name, NULL, par1, par2); 192 Error = GetLastError(); 193 EndSeh(STATUS_ACCESS_VIOLATION); 194 195 ok_long(ApiReturn, 0); 196 ok_long(Error, 0xbeeffeed); 197 ok(ulOutBufLen > 0, 198 "ulOutBufLen is %ld, expected > 0\n", 199 ulOutBufLen); 200 ok_wstr(L"", Name); 201 202 // Test correct values 203 SetLastError(0xbeeffeed); 204 ZeroMemory(&Name, sizeof(Name)); 205 ulOutBufLen = sizeof(Name); 206 ApiReturn = pNhGetInterfaceNameFromDeviceGuid(&AdapterGUID, &Name, &ulOutBufLen, par1, par2); 207 Error = GetLastError(); 208 209 ok(ApiReturn == ERROR_SUCCESS, 210 "ApiReturn returned %ld, expected ERROR_SUCCESS\n", 211 ApiReturn); 212 ok(Error == ERROR_SUCCESS, 213 "GetLastError() returned %ld, expected ERROR_SUCCESS\n", 214 Error); 215 ok(ulOutBufLen > 0, 216 "ulOutBufLen is %ld, expected > 0\n", 217 ulOutBufLen); 218 Length = wcslen(Name); 219 ok(Length > 0, 220 "wcslen(Name) is %ld, expected > 0\n", 221 Length); 222 if (Length > 0) 223 trace("Adapter name: \"%S\"\n", Name); 224 225 // Test correct values, but with new unique GUID 226 SetLastError(0xbeeffeed); 227 ZeroMemory(&Name, sizeof(Name)); 228 ulOutBufLen = sizeof(Name); 229 ApiReturn = pNhGetInterfaceNameFromDeviceGuid((PVOID)&UniqueGUID, &Name, &ulOutBufLen, par1, par2); 230 Error = GetLastError(); 231 232 ok_long(ApiReturn, ((GetVersion() & 0xFF) >= 6) ? ERROR_INVALID_PARAMETER : ERROR_NOT_FOUND); 233 ok(Error == ERROR_SUCCESS, 234 "GetLastError() returned %ld, expected ERROR_SUCCESS\n", 235 Error); 236 ok(ulOutBufLen == sizeof(Name), 237 "ulOutBufLen is %ld, expected = sizeof(Name)\n", 238 ulOutBufLen); 239 ok_wstr(L"", Name); 240 241 // Test correct values, but with small length 242 SetLastError(0xbeeffeed); 243 ZeroMemory(&Name, sizeof(Name)); 244 ulOutBufLen = 0; 245 ApiReturn = pNhGetInterfaceNameFromDeviceGuid(&AdapterGUID, &Name, &ulOutBufLen, par1, par2); 246 Error = GetLastError(); 247 248 ok_long(ApiReturn, ((GetVersion() & 0xFF) >= 6) ? ERROR_NOT_ENOUGH_MEMORY : ERROR_INSUFFICIENT_BUFFER); 249 ok(Error == ERROR_SUCCESS, 250 "GetLastError() returned %ld, expected ERROR_SUCCESS\n", 251 Error); 252 ok_long(ulOutBufLen, MAX_INTERFACE_NAME_LEN * 2 + (((GetVersion() & 0xFF) >= 6) ? 2 : 0)); 253 ok_wstr(L"", Name); 254 } 255 256 static 257 VOID 258 test_GetInterfaceName(VOID) 259 { 260 PIP_INTERFACE_INFO pInfo = NULL; 261 ULONG ulOutBufLen = 0; 262 DWORD ApiReturn; 263 WCHAR Name[MAX_ADAPTER_NAME]; 264 UNICODE_STRING GuidString; 265 GUID AdapterGUID; 266 HINSTANCE hIpHlpApi; 267 268 ApiReturn = GetInterfaceInfo(pInfo, &ulOutBufLen); 269 ok(ApiReturn == ERROR_INSUFFICIENT_BUFFER, 270 "GetInterfaceInfo(pInfo, &ulOutBufLen) returned %ld, expected ERROR_INSUFFICIENT_BUFFER\n", 271 ApiReturn); 272 if (ApiReturn != ERROR_INSUFFICIENT_BUFFER) 273 { 274 skip("Can't determine size of IP_INTERFACE_INFO. Can't proceed\n"); 275 return; 276 } 277 278 pInfo = (IP_INTERFACE_INFO *)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, ulOutBufLen); 279 if (pInfo == NULL) 280 { 281 skip("pInfo is NULL. Can't proceed\n"); 282 return; 283 } 284 285 ApiReturn = GetInterfaceInfo(pInfo, &ulOutBufLen); 286 ok(ApiReturn == NO_ERROR, 287 "GetInterfaceInfo(pInfo, &ulOutBufLen) returned %ld, expected NO_ERROR\n", 288 ApiReturn); 289 if (ApiReturn != NO_ERROR || ulOutBufLen == 0) 290 { 291 skip("GetInterfaceInfo failed with error %ld. Can't proceed\n", ApiReturn); 292 return; 293 } 294 295 if (pInfo->NumAdapters > 0) 296 CopyMemory(&Name, &pInfo->Adapter[0].Name, sizeof(Name)); 297 298 if (pInfo->NumAdapters == 0) 299 { 300 HeapFree(GetProcessHeap(), 0, pInfo); 301 skip("pInfo->NumAdapters = 0. Can't proceed\n"); 302 return; 303 } 304 trace("pInfo->NumAdapters: %lu\n", pInfo->NumAdapters); 305 306 HeapFree(GetProcessHeap(), 0, pInfo); 307 308 ApiReturn = wcsncmp(Name, L"\\DEVICE\\TCPIP_", 14); 309 ok(ApiReturn == 0, 310 "wcsncmp(Name, L\"\\DEVICE\\TCPIP_\", 14) returned %ld, expected 0\n", 311 ApiReturn); 312 if (ApiReturn != 0) 313 { 314 if (wcslen(Name) == 0) 315 { 316 skip("pInfo->Adapter[0].Name is empty. Can't proceed\n"); 317 return; 318 } 319 else 320 { 321 // workaround for ReactOS 322 trace("pInfo->Adapter[0].Name = \"%ls\" is incorrect.\n", Name); 323 RtlInitUnicodeString(&GuidString, &Name[0]); 324 } 325 } 326 else 327 { 328 RtlInitUnicodeString(&GuidString, &Name[14]); 329 } 330 331 ApiReturn = RtlGUIDFromString(&GuidString, &AdapterGUID); 332 if (ApiReturn != 0) 333 { 334 skip("RtlGUIDFromString failed. Can't proceed\n"); 335 return; 336 } 337 338 hIpHlpApi = GetModuleHandleW(L"iphlpapi.dll"); 339 if (!hIpHlpApi) 340 { 341 skip("Failed to load iphlpapi.dll. Can't proceed\n"); 342 return; 343 } 344 345 pNhGetInterfaceNameFromGuid = (void *)GetProcAddress(hIpHlpApi, "NhGetInterfaceNameFromGuid"); 346 347 if (!pNhGetInterfaceNameFromGuid) 348 skip("NhGetInterfaceNameFromGuid not found. Can't proceed\n"); 349 else 350 test_NhGetInterfaceNameFromGuid(AdapterGUID, 0, 0); 351 352 pNhGetInterfaceNameFromDeviceGuid = (void *)GetProcAddress(hIpHlpApi, "NhGetInterfaceNameFromDeviceGuid"); 353 354 if (!pNhGetInterfaceNameFromDeviceGuid) 355 skip("NhGetInterfaceNameFromDeviceGuid not found. Can't proceed\n"); 356 else 357 test_NhGetInterfaceNameFromDeviceGuid(AdapterGUID, 1, 0); 358 } 359 360 START_TEST(GetInterfaceName) 361 { 362 test_GetInterfaceName(); 363 } 364