From 3aff833b5c42ad908c4937071cc2600a25cac98d Mon Sep 17 00:00:00 2001 From: TheLastRar Date: Sun, 19 May 2024 18:06:07 +0100 Subject: [PATCH] DEV9: Unify GetAdapter code --- pcsx2/DEV9/AdapterUtils.cpp | 99 +++++++++++++--------------------- pcsx2/DEV9/AdapterUtils.h | 9 ++++ pcsx2/DEV9/Win32/tap-win32.cpp | 87 +++++++++--------------------- pcsx2/DEV9/sockets.cpp | 60 +++++---------------- 4 files changed, 84 insertions(+), 171 deletions(-) diff --git a/pcsx2/DEV9/AdapterUtils.cpp b/pcsx2/DEV9/AdapterUtils.cpp index 01e419d91b..849725ee95 100644 --- a/pcsx2/DEV9/AdapterUtils.cpp +++ b/pcsx2/DEV9/AdapterUtils.cpp @@ -55,17 +55,15 @@ using namespace PacketReader::IP; */ #ifdef _WIN32 -bool AdapterUtils::GetAdapter(const std::string& name, Adapter* adapter, AdapterBuffer* buffer) +AdapterUtils::Adapter* AdapterUtils::GetAllAdapters(AdapterBuffer* buffer, bool includeHidden) { - int neededSize = 128; + int neededSize = includeHidden ? 256 : 128; std::unique_ptr adapterInfo = std::make_unique(neededSize); ULONG dwBufLen = sizeof(IP_ADAPTER_ADDRESSES) * neededSize; - PIP_ADAPTER_ADDRESSES pAdapterInfo; - DWORD dwStatus = GetAdaptersAddresses( AF_UNSPEC, - GAA_FLAG_INCLUDE_PREFIX | GAA_FLAG_INCLUDE_GATEWAYS, + GAA_FLAG_INCLUDE_PREFIX | GAA_FLAG_INCLUDE_GATEWAYS | (includeHidden ? GAA_FLAG_INCLUDE_ALL_INTERFACES : 0), NULL, adapterInfo.get(), &dwBufLen); @@ -80,66 +78,45 @@ bool AdapterUtils::GetAdapter(const std::string& name, Adapter* adapter, Adapter dwStatus = GetAdaptersAddresses( AF_UNSPEC, - GAA_FLAG_INCLUDE_PREFIX | GAA_FLAG_INCLUDE_GATEWAYS, + GAA_FLAG_INCLUDE_PREFIX | GAA_FLAG_INCLUDE_GATEWAYS | (includeHidden ? GAA_FLAG_INCLUDE_ALL_INTERFACES : 0), NULL, adapterInfo.get(), &dwBufLen); } if (dwStatus != ERROR_SUCCESS) - return false; + return nullptr; - pAdapterInfo = adapterInfo.get(); + buffer->swap(adapterInfo); + + return buffer->get(); +} +bool AdapterUtils::GetAdapter(const std::string& name, Adapter* adapter, AdapterBuffer* buffer) +{ + std::unique_ptr adapterInfo; + PIP_ADAPTER_ADDRESSES pAdapter = GetAllAdapters(&adapterInfo); + if (pAdapter == nullptr) + return false; do { - if (strcmp(pAdapterInfo->AdapterName, name.c_str()) == 0) + if (strcmp(pAdapter->AdapterName, name.c_str()) == 0) { - *adapter = *pAdapterInfo; + *adapter = *pAdapter; buffer->swap(adapterInfo); return true; } - pAdapterInfo = pAdapterInfo->Next; - } while (pAdapterInfo); + pAdapter = pAdapter->Next; + } while (pAdapter); return false; } bool AdapterUtils::GetAdapterAuto(Adapter* adapter, AdapterBuffer* buffer) { - int neededSize = 128; - std::unique_ptr adapterInfo = std::make_unique(neededSize); - ULONG dwBufLen = sizeof(IP_ADAPTER_ADDRESSES) * neededSize; - - PIP_ADAPTER_ADDRESSES pAdapter; - - DWORD dwStatus = GetAdaptersAddresses( - AF_UNSPEC, - GAA_FLAG_INCLUDE_PREFIX | GAA_FLAG_INCLUDE_GATEWAYS, - NULL, - adapterInfo.get(), - &dwBufLen); - - if (dwStatus == ERROR_BUFFER_OVERFLOW) - { - DevCon.WriteLn("DEV9: PCAPGetWin32Adapter() buffer too small, resizing"); - // - neededSize = dwBufLen / sizeof(IP_ADAPTER_ADDRESSES) + 1; - adapterInfo = std::make_unique(neededSize); - dwBufLen = sizeof(IP_ADAPTER_ADDRESSES) * neededSize; - DevCon.WriteLn("DEV9: New size %i", neededSize); - - dwStatus = GetAdaptersAddresses( - AF_UNSPEC, - GAA_FLAG_INCLUDE_PREFIX | GAA_FLAG_INCLUDE_GATEWAYS, - NULL, - adapterInfo.get(), - &dwBufLen); - } - - if (dwStatus != ERROR_SUCCESS) - return 0; - - pAdapter = adapterInfo.get(); + std::unique_ptr adapterInfo; + PIP_ADAPTER_ADDRESSES pAdapter = GetAllAdapters(&adapterInfo); + if (pAdapter == nullptr) + return false; do { @@ -181,19 +158,25 @@ bool AdapterUtils::GetAdapterAuto(Adapter* adapter, AdapterBuffer* buffer) return false; } #elif defined(__POSIX__) -bool AdapterUtils::GetAdapter(const std::string& name, Adapter* adapter, AdapterBuffer* buffer) +AdapterUtils::Adapter* AdapterUtils::GetAllAdapters(AdapterBuffer* buffer) { ifaddrs* ifa; - ifaddrs* pAdapter; int error = getifaddrs(&ifa); if (error) + return nullptr; + + buffer->reset(ifa); + + return buffer->get(); +} +bool AdapterUtils::GetAdapter(const std::string& name, Adapter* adapter, AdapterBuffer* buffer) +{ + std::unique_ptr adapterInfo; + ifaddrs* pAdapter = GetAllAdapters(&adapterInfo); + if (pAdapter == nullptr) return false; - std::unique_ptr adapterInfo(ifa, IfAdaptersDeleter()); - - pAdapter = adapterInfo.get(); - do { if (pAdapter->ifa_addr != nullptr && @@ -215,17 +198,11 @@ bool AdapterUtils::GetAdapter(const std::string& name, Adapter* adapter, Adapter } bool AdapterUtils::GetAdapterAuto(Adapter* adapter, AdapterBuffer* buffer) { - ifaddrs* ifa; - ifaddrs* pAdapter; - - int error = getifaddrs(&ifa); - if (error) + std::unique_ptr adapterInfo; + ifaddrs* pAdapter = GetAllAdapters(&adapterInfo); + if (pAdapter == nullptr) return false; - std::unique_ptr adapterInfo(ifa, IfAdaptersDeleter()); - - pAdapter = adapterInfo.get(); - do { if ((pAdapter->ifa_flags & IFF_LOOPBACK) == 0 && diff --git a/pcsx2/DEV9/AdapterUtils.h b/pcsx2/DEV9/AdapterUtils.h index 504ea65ced..f3b859c11c 100644 --- a/pcsx2/DEV9/AdapterUtils.h +++ b/pcsx2/DEV9/AdapterUtils.h @@ -31,6 +31,15 @@ namespace AdapterUtils void operator()(ifaddrs* buffer) const { freeifaddrs(buffer); } }; typedef std::unique_ptr AdapterBuffer; +#endif + // Adapter is a structure that contains ptrs to data stored within AdapterBuffer. + // We need to return this buffer the caller can free it after it's finished with Adapter. + // AdapterBuffer is a unique_ptr, so will be freed when it leaves scope. +#ifdef _WIN32 + // includeHidden sets GAA_FLAG_INCLUDE_ALL_INTERFACES, used by TAPAdapter + Adapter* GetAllAdapters(AdapterBuffer* buffer, bool includeHidden = false); +#elif defined(__POSIX__) + Adapter* GetAllAdapters(AdapterBuffer* buffer); #endif bool GetAdapter(const std::string& name, Adapter* adapter, AdapterBuffer* buffer); bool GetAdapterAuto(Adapter* adapter, AdapterBuffer* buffer); diff --git a/pcsx2/DEV9/Win32/tap-win32.cpp b/pcsx2/DEV9/Win32/tap-win32.cpp index 64d57e9b1e..9662ad6fbe 100644 --- a/pcsx2/DEV9/Win32/tap-win32.cpp +++ b/pcsx2/DEV9/Win32/tap-win32.cpp @@ -24,6 +24,7 @@ #include #include "DEV9/PacketReader/MAC_Address.h" +#include "DEV9/AdapterUtils.h" //============= // TAP IOCTLs @@ -272,80 +273,41 @@ PIP_ADAPTER_ADDRESSES FindAdapterViaIndex(PIP_ADAPTER_ADDRESSES adapterList, int //IP_ADAPTER_ADDRESSES is a structure that contains ptrs to data in other regions //of the buffer, se we need to return both so the caller can free the buffer //after it's finished reading the needed data from IP_ADAPTER_ADDRESSES -bool TAPGetWin32Adapter(const std::string& name, PIP_ADAPTER_ADDRESSES adapter, std::unique_ptr* buffer) +bool TAPGetWin32Adapter(const std::string& name, PIP_ADAPTER_ADDRESSES adapter, AdapterUtils::AdapterBuffer* buffer) { - int neededSize = 256; - std::unique_ptr AdapterInfo = std::make_unique(neededSize); - ULONG dwBufLen = sizeof(IP_ADAPTER_ADDRESSES) * neededSize; - - PIP_ADAPTER_ADDRESSES pAdapterInfo; - //GAA_FLAG_INCLUDE_ALL_INTERFACES needed to get Tap when bridged - DWORD dwStatus = GetAdaptersAddresses( - AF_UNSPEC, - GAA_FLAG_INCLUDE_PREFIX | GAA_FLAG_INCLUDE_GATEWAYS | GAA_FLAG_INCLUDE_ALL_INTERFACES, - NULL, - AdapterInfo.get(), - &dwBufLen); - - if (dwStatus == ERROR_BUFFER_OVERFLOW) - { - DevCon.WriteLn("DEV9: GetWin32Adapter() buffer too small, resizing"); - // - neededSize = dwBufLen / sizeof(IP_ADAPTER_ADDRESSES) + 1; - AdapterInfo = std::make_unique(neededSize); - dwBufLen = sizeof(IP_ADAPTER_ADDRESSES) * neededSize; - DevCon.WriteLn("DEV9: New size %i", neededSize); - - dwStatus = GetAdaptersAddresses( - AF_UNSPEC, - GAA_FLAG_INCLUDE_PREFIX | GAA_FLAG_INCLUDE_GATEWAYS | GAA_FLAG_INCLUDE_ALL_INTERFACES, - NULL, - AdapterInfo.get(), - &dwBufLen); - } - - if (dwStatus != ERROR_SUCCESS) - return 0; - - pAdapterInfo = AdapterInfo.get(); + AdapterUtils::AdapterBuffer adapterInfo; + PIP_ADAPTER_ADDRESSES pAdapterFirst = AdapterUtils::GetAllAdapters(&adapterInfo, true); + if (pAdapterFirst == nullptr) + return false; + PIP_ADAPTER_ADDRESSES pAdapter = pAdapterFirst; do { - if (0 == strcmp(pAdapterInfo->AdapterName, name.c_str())) + if (0 == strcmp(pAdapter->AdapterName, name.c_str())) break; - pAdapterInfo = pAdapterInfo->Next; - } while (pAdapterInfo); + pAdapter = pAdapter->Next; + } while (pAdapter); - if (pAdapterInfo == nullptr) + if (pAdapter == nullptr) return false; //If we are bridged, then we won't show up without GAA_FLAG_INCLUDE_ALL_INTERFACES - std::unique_ptr AdapterInfoReduced = std::make_unique(neededSize); - dwBufLen = sizeof(IP_ADAPTER_ADDRESSES) * neededSize; - - dwStatus = GetAdaptersAddresses( - AF_UNSPEC, - GAA_FLAG_INCLUDE_PREFIX | GAA_FLAG_INCLUDE_GATEWAYS, - NULL, - AdapterInfoReduced.get(), - &dwBufLen); - - if (dwStatus != ERROR_SUCCESS) - return 0; + AdapterUtils::AdapterBuffer adapterInfoReduced; + PIP_ADAPTER_ADDRESSES pAdapterReducedFirst = AdapterUtils::GetAllAdapters(&adapterInfoReduced, false); //If we find our adapter in the reduced list, we are not bridged - if (FindAdapterViaIndex(AdapterInfoReduced.get(), pAdapterInfo->IfIndex) != nullptr) + if (FindAdapterViaIndex(pAdapterReducedFirst, pAdapter->IfIndex) != nullptr) { - *adapter = *pAdapterInfo; - buffer->swap(AdapterInfo); + *adapter = *pAdapter; + buffer->swap(adapterInfo); return true; } //We must be bridged Console.WriteLn("DEV9: Current adapter is probably bridged"); - Console.WriteLn(fmt::format("DEV9: Adapter Display name: {}", StringUtil::WideStringToUTF8String(pAdapterInfo->FriendlyName))); + Console.WriteLn(fmt::format("DEV9: Adapter Display name: {}", StringUtil::WideStringToUTF8String(pAdapter->FriendlyName))); //We will need to find the bridge adapter that out adapter is //as the IP information of the tap adapter is null @@ -379,7 +341,7 @@ bool TAPGetWin32Adapter(const std::string& name, PIP_ADAPTER_ADDRESSES adapter, //If multiple rows have our adapter, we check all of them std::vector potentialBridges; std::vector searchList; - searchList.push_back(pAdapterInfo->IfIndex); + searchList.push_back(pAdapter->IfIndex); PMIB_IFSTACK_TABLE table; GetIfStackTable(&table); @@ -392,7 +354,7 @@ bool TAPGetWin32Adapter(const std::string& name, PIP_ADAPTER_ADDRESSES adapter, MIB_IFSTACK_ROW row = table->Table[i]; if (row.LowerLayerInterfaceIndex == targetIndex) { - const PIP_ADAPTER_ADDRESSES potentialAdapter = FindAdapterViaIndex(AdapterInfoReduced.get(), row.HigherLayerInterfaceIndex); + const PIP_ADAPTER_ADDRESSES potentialAdapter = FindAdapterViaIndex(pAdapterReducedFirst, row.HigherLayerInterfaceIndex); if (potentialAdapter != nullptr) { Console.WriteLn(fmt::format("DEV9: {} is possible bridge (Check 1 passed)", StringUtil::WideStringToUTF8String(potentialAdapter->Description))); @@ -406,7 +368,8 @@ bool TAPGetWin32Adapter(const std::string& name, PIP_ADAPTER_ADDRESSES adapter, } //Cleanup FreeMibTable(table); - AdapterInfoReduced = nullptr; + pAdapterReducedFirst = nullptr; + adapterInfoReduced.reset(); //Step 2 //Init COM @@ -442,7 +405,7 @@ bool TAPGetWin32Adapter(const std::string& name, PIP_ADAPTER_ADDRESSES adapter, //We need to match the adapter index to an INetCfgComponent //We do this by matching IP_ADAPTER_ADDRESSES.AdapterName //with the INetCfgComponent Instance GUID - PIP_ADAPTER_ADDRESSES cAdapterInfo = FindAdapterViaIndex(AdapterInfo.get(), index); + PIP_ADAPTER_ADDRESSES cAdapterInfo = FindAdapterViaIndex(pAdapterFirst, index); if (cAdapterInfo == nullptr || cAdapterInfo->AdapterName == nullptr) continue; @@ -514,7 +477,7 @@ bool TAPGetWin32Adapter(const std::string& name, PIP_ADAPTER_ADDRESSES adapter, if (bridgeAdapter != nullptr) { *adapter = *bridgeAdapter; - buffer->swap(AdapterInfo); + buffer->swap(adapterInfo); return true; } @@ -551,7 +514,7 @@ TAPAdapter::TAPAdapter() SetMACAddress(&newMAC); IP_ADAPTER_ADDRESSES adapter; - std::unique_ptr buffer; + AdapterUtils::AdapterBuffer buffer; if (TAPGetWin32Adapter(EmuConfig.DEV9.EthDevice, &adapter, &buffer)) InitInternalServer(&adapter); else @@ -646,7 +609,7 @@ bool TAPAdapter::send(NetPacket* pkt) void TAPAdapter::reloadSettings() { IP_ADAPTER_ADDRESSES adapter; - std::unique_ptr buffer; + AdapterUtils::AdapterBuffer buffer; if (TAPGetWin32Adapter(EmuConfig.DEV9.EthDevice, &adapter, &buffer)) ReloadInternalServer(&adapter); else diff --git a/pcsx2/DEV9/sockets.cpp b/pcsx2/DEV9/sockets.cpp index 4243118774..43f772b159 100644 --- a/pcsx2/DEV9/sockets.cpp +++ b/pcsx2/DEV9/sockets.cpp @@ -50,67 +50,33 @@ std::vector SocketAdapter::GetAdapters() nic.push_back(autoEntry); #ifdef _WIN32 - int neededSize = 128; - std::unique_ptr AdapterInfo = std::make_unique(neededSize); - ULONG dwBufLen = sizeof(IP_ADAPTER_ADDRESSES) * neededSize; - - PIP_ADAPTER_ADDRESSES pAdapterInfo; - - DWORD dwStatus = GetAdaptersAddresses( - AF_UNSPEC, - GAA_FLAG_INCLUDE_PREFIX | GAA_FLAG_INCLUDE_GATEWAYS, - NULL, - AdapterInfo.get(), - &dwBufLen); - - if (dwStatus == ERROR_BUFFER_OVERFLOW) - { - DevCon.WriteLn("DEV9: PCAPGetWin32Adapter() buffer too small, resizing"); - // - neededSize = dwBufLen / sizeof(IP_ADAPTER_ADDRESSES) + 1; - AdapterInfo = std::make_unique(neededSize); - dwBufLen = sizeof(IP_ADAPTER_ADDRESSES) * neededSize; - DevCon.WriteLn("DEV9: New size %i", neededSize); - - dwStatus = GetAdaptersAddresses( - AF_UNSPEC, - GAA_FLAG_INCLUDE_PREFIX | GAA_FLAG_INCLUDE_GATEWAYS, - NULL, - AdapterInfo.get(), - &dwBufLen); - } - - if (dwStatus != ERROR_SUCCESS) + AdapterUtils::AdapterBuffer adapterInfo; + PIP_ADAPTER_ADDRESSES pAdapter = AdapterUtils::GetAllAdapters(&adapterInfo); + if (pAdapter == nullptr) return nic; - pAdapterInfo = AdapterInfo.get(); - do { - if (pAdapterInfo->IfType != IF_TYPE_SOFTWARE_LOOPBACK && - pAdapterInfo->OperStatus == IfOperStatusUp) + if (pAdapter->IfType != IF_TYPE_SOFTWARE_LOOPBACK && + pAdapter->OperStatus == IfOperStatusUp) { AdapterEntry entry; entry.type = Pcsx2Config::DEV9Options::NetApi::Sockets; - entry.name = StringUtil::WideStringToUTF8String(pAdapterInfo->FriendlyName); - entry.guid = pAdapterInfo->AdapterName; + entry.name = StringUtil::WideStringToUTF8String(pAdapter->FriendlyName); + entry.guid = pAdapter->AdapterName; nic.push_back(entry); } - pAdapterInfo = pAdapterInfo->Next; - } while (pAdapterInfo); + pAdapter = pAdapter->Next; + } while (pAdapter); #elif defined(__POSIX__) - ifaddrs* adapterInfo; - ifaddrs* pAdapter; - - int error = getifaddrs(&adapterInfo); - if (error) + AdapterUtils::AdapterBuffer adapterInfo; + ifaddrs* pAdapter = GetAllAdapters(&adapterInfo); + if (pAdapter == nullptr) return nic; - pAdapter = adapterInfo; - do { if ((pAdapter->ifa_flags & IFF_LOOPBACK) == 0 && @@ -128,8 +94,6 @@ std::vector SocketAdapter::GetAdapters() pAdapter = pAdapter->ifa_next; } while (pAdapter); - - freeifaddrs(adapterInfo); #endif return nic;