#include "pch.h" #include "usrerr.h" #include #include #include #include #include #include #include #include "globalcfg.h" #include "misc.h" #include "network.h" #include #include #pragma comment(lib, "Iphlpapi.lib") #pragma comment(lib, "Ws2_32.lib") static NIC_CONTENT g_NetAdapterInfo[NET_CARD_MAX]; int GetInterfaceIfIndexByIpAddr(const TCHAR *pIpAddr, ULONG *pIfIndex) { PIP_ADAPTER_INFO pAdapterInfo; DWORD dwRetVal; ULONG ulOutBufLen; if (pIpAddr == nullptr || lstrlen(pIpAddr) == 0) { SPDLOG_ERROR(TEXT("Input pIpAddr error: {0}"), pIpAddr); return -ERR_INPUT_PARAMS; } if (pIfIndex == nullptr) { SPDLOG_ERROR(TEXT("Input pIfIndex params error")); return -ERR_INPUT_PARAMS; } ulOutBufLen = sizeof(IP_ADAPTER_INFO); pAdapterInfo = static_cast(HeapAlloc(GetProcessHeap(), 0, sizeof(IP_ADAPTER_INFO))); if (pAdapterInfo == nullptr) { SPDLOG_ERROR(TEXT("Error allocating memory needed to call GetAdaptersinfo")); return -ERR_MALLOC_MEMORY; } if (GetAdaptersInfo(pAdapterInfo, &ulOutBufLen) == ERROR_BUFFER_OVERFLOW) { HeapFree(GetProcessHeap(), 0, pAdapterInfo); pAdapterInfo = static_cast(HeapAlloc(GetProcessHeap(), 0, ulOutBufLen)); if (pAdapterInfo == nullptr) { SPDLOG_ERROR(TEXT("Error allocating memory needed to call GetAdaptersinfo\n")); return -ERR_MALLOC_MEMORY; } } *pIfIndex = -1; if ((dwRetVal = GetAdaptersInfo(pAdapterInfo, &ulOutBufLen)) == NO_ERROR) { PIP_ADAPTER_INFO pAdapter = pAdapterInfo; while (pAdapter) { PIP_ADDR_STRING ipAddressListPointer = &(pAdapter->IpAddressList); while (ipAddressListPointer != nullptr) { if (StrCmp((ipAddressListPointer->IpAddress).String, pIpAddr) == 0) { *pIfIndex = pAdapter->Index; HeapFree(GetProcessHeap(), 0, pAdapterInfo); return ERR_SUCCESS; } else { ipAddressListPointer = ipAddressListPointer->Next; } } pAdapter = pAdapter->Next; } } else { SPDLOG_ERROR(TEXT("GetAdaptersInfo failed with error: {0}\n"), dwRetVal); HeapFree(GetProcessHeap(), 0, pAdapterInfo); return -ERR_SYS_CALL; } if (pAdapterInfo) { HeapFree(GetProcessHeap(), 0, pAdapterInfo); } return -ERR_ITEM_UNEXISTS; } int GetInterfaceIfIndexByGUID(const TCHAR *pGUID, int *pIfIndex) { PIP_ADAPTER_INFO pAdapterInfo; DWORD dwRetVal; if (pGUID == nullptr || lstrlen(pGUID) == 0) { SPDLOG_ERROR(TEXT("Input pGUID error: {0}"), pGUID); return -ERR_INPUT_PARAMS; } if (pIfIndex == nullptr) { SPDLOG_ERROR(TEXT("Input pIfIndex params error")); return -ERR_INPUT_PARAMS; } ULONG ulOutBufLen = sizeof(IP_ADAPTER_INFO); pAdapterInfo = static_cast(HeapAlloc(GetProcessHeap(), 0, sizeof(IP_ADAPTER_INFO))); if (pAdapterInfo == nullptr) { SPDLOG_ERROR(TEXT("Error allocating memory needed to call GetAdaptersinfo")); return -ERR_MALLOC_MEMORY; } if (GetAdaptersInfo(pAdapterInfo, &ulOutBufLen) == ERROR_BUFFER_OVERFLOW) { HeapFree(GetProcessHeap(), 0, pAdapterInfo); pAdapterInfo = static_cast(HeapAlloc(GetProcessHeap(), 0, ulOutBufLen)); if (pAdapterInfo == nullptr) { SPDLOG_ERROR(TEXT("Error allocating memory needed to call GetAdaptersinfo\n")); return -ERR_MALLOC_MEMORY; } } *pIfIndex = -1; if ((dwRetVal = GetAdaptersInfo(pAdapterInfo, &ulOutBufLen)) == NO_ERROR) { PIP_ADAPTER_INFO pAdapter = pAdapterInfo; while (pAdapter) { if (StrCmp(pAdapter->AdapterName, pGUID) == 0) { *pIfIndex = static_cast(pAdapter->Index); HeapFree(GetProcessHeap(), 0, pAdapterInfo); return ERR_SUCCESS; } pAdapter = pAdapter->Next; } } else { SPDLOG_ERROR(TEXT("GetAdaptersInfo failed with error: {0}\n"), dwRetVal); HeapFree(GetProcessHeap(), 0, pAdapterInfo); return -ERR_SYS_CALL; } if (pAdapterInfo) { HeapFree(GetProcessHeap(), 0, pAdapterInfo); } return -ERR_ITEM_UNEXISTS; } int GetInterfaceNameByGUID(const TCHAR *pGUID, TCHAR ifName[MAX_NETCARD_NAME], int *pConnStatus) { VARIANT v; INetConnection *pNC = nullptr; IEnumVARIANT *pEV = nullptr; IUnknown *pUnk = nullptr; INetSharingEveryConnectionCollection *pNSECC = nullptr; INetSharingManager *pNSM; HRESULT hr; if (pGUID == nullptr || lstrlen(pGUID) == 0) { SPDLOG_ERROR(TEXT("Input pGUID params error: {0}"), pGUID); return -ERR_INPUT_PARAMS; } hr = ::CoCreateInstance(CLSID_NetSharingManager, nullptr, CLSCTX_ALL, IID_INetSharingManager, reinterpret_cast(&pNSM)); if (hr != S_OK || pNSM == nullptr) { CoInitialize(nullptr); CoInitializeSecurity(nullptr, -1, nullptr, nullptr, RPC_C_AUTHN_LEVEL_PKT, RPC_C_IMP_LEVEL_IMPERSONATE, nullptr, EOAC_NONE, nullptr); hr = ::CoCreateInstance(CLSID_NetSharingManager, nullptr, CLSCTX_ALL, IID_INetSharingManager, reinterpret_cast(&pNSM)); } if (hr != S_OK || pNSM == nullptr) { SPDLOG_ERROR(TEXT("CoCreateInstance NetSharingManager failed: {0}"), hr); return -ERR_CREATE_COMMOBJECT; } VariantInit(&v); hr = pNSM->get_EnumEveryConnection(&pNSECC); if (hr != S_OK || !pNSECC) { SPDLOG_ERROR(TEXT("INetSharingManager get_EnumEveryConnection failed: {0}."), hr); return -ERR_SYS_CALL; } hr = pNSECC->get__NewEnum(&pUnk); pNSECC->Release(); if (hr != S_OK || !pUnk) { SPDLOG_ERROR(TEXT("INetSharingManager get_EnumEveryConnection failed: {0}."), hr); return -ERR_SYS_CALL; } hr = pUnk->QueryInterface(IID_IEnumVARIANT, reinterpret_cast(&pEV)); pUnk->Release(); if (hr != S_OK || !pUnk) { SPDLOG_ERROR(TEXT("INetSharingManager get_EnumEveryConnection failed: {0}."), hr); return -ERR_SYS_CALL; } while (S_OK == pEV->Next(1, &v, nullptr)) { if (V_VT(&v) == VT_UNKNOWN) { V_UNKNOWN(&v)->QueryInterface(IID_INetConnection, reinterpret_cast(&pNC)); if (pNC) { int ret; TCHAR strGuid[MAX_PATH] = {}; NETCON_PROPERTIES *pNP; pNC->GetProperties(&pNP); StringCbPrintf(strGuid, MAX_PATH, TEXT("{%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}"), pNP->guidId.Data1, pNP->guidId.Data2, pNP->guidId.Data3, pNP->guidId.Data4[0], pNP->guidId.Data4[1], pNP->guidId.Data4[2], pNP->guidId.Data4[3], pNP->guidId.Data4[4], pNP->guidId.Data4[5], pNP->guidId.Data4[6], pNP->guidId.Data4[7]); // 找到对应的网卡进行处理 if (StrCmp(pGUID, strGuid) != 0) { continue; } memset(ifName, 0, MAX_NETCARD_NAME); ret = WideCharToTChar(pNP->pszwName, ifName, MAX_NETCARD_NAME); // 执行字符串转换 if (ret != ERR_SUCCESS) { SPDLOG_ERROR(TEXT("Convert Unicode wide char to TCHAR failed: {0}."), ret); return ret; } if (pConnStatus) { *pConnStatus = pNP->Status; } return ERR_SUCCESS; } } } return ERR_ITEM_UNEXISTS; } int GetInternetIfIndex(int *pIfIndex) { PIP_ADAPTER_INFO pAdapterInfo; DWORD dwRetVal; ULONG ulOutBufLen; if (pIfIndex == nullptr) { SPDLOG_ERROR(TEXT("Input pIfIndex params error")); return -ERR_INPUT_PARAMS; } ulOutBufLen = sizeof(IP_ADAPTER_INFO); pAdapterInfo = static_cast(HeapAlloc(GetProcessHeap(), 0, sizeof(IP_ADAPTER_INFO))); if (pAdapterInfo == nullptr) { SPDLOG_ERROR(TEXT("Error allocating memory needed to call GetAdaptersinfo")); return -ERR_MALLOC_MEMORY; } if (GetAdaptersInfo(pAdapterInfo, &ulOutBufLen) == ERROR_BUFFER_OVERFLOW) { HeapFree(GetProcessHeap(), 0, pAdapterInfo); pAdapterInfo = static_cast(HeapAlloc(GetProcessHeap(), 0, ulOutBufLen)); if (pAdapterInfo == nullptr) { SPDLOG_ERROR(TEXT("Error allocating memory needed to call GetAdaptersinfo\n")); return -ERR_MALLOC_MEMORY; } } *pIfIndex = -1; if ((dwRetVal = GetAdaptersInfo(pAdapterInfo, &ulOutBufLen)) == NO_ERROR) { PIP_ADAPTER_INFO pAdapter = pAdapterInfo; while (pAdapter) { bool bIsInternel; int index = static_cast(pAdapter->Index); int ret = IsInternetConnectAdapter(index, &bIsInternel); if (ret != ERR_SUCCESS) { SPDLOG_ERROR(TEXT("IsInternetConnectAdapter {0} : {1}\n"), index, ret); } if (ret == ERR_SUCCESS && bIsInternel) { *pIfIndex = index; HeapFree(GetProcessHeap(), 0, pAdapterInfo); return ERR_SUCCESS; } pAdapter = pAdapter->Next; } } else { SPDLOG_ERROR(TEXT("GetAdaptersInfo failed with error: {0}\n"), dwRetVal); HeapFree(GetProcessHeap(), 0, pAdapterInfo); return -ERR_SYS_CALL; } if (pAdapterInfo) { HeapFree(GetProcessHeap(), 0, pAdapterInfo); } return -ERR_ITEM_UNEXISTS; } int GetInterfaceGUIDByIfIndex(const int ifIndex, GUID *pGuid) { PIP_ADAPTER_INFO pAdapterInfo; DWORD dwRetVal; ULONG ulOutBufLen; if (pGuid == nullptr) { SPDLOG_ERROR(TEXT("Input pGuid error.")); return -ERR_INPUT_PARAMS; } ulOutBufLen = sizeof(IP_ADAPTER_INFO); pAdapterInfo = static_cast(HeapAlloc(GetProcessHeap(), 0, sizeof(IP_ADAPTER_INFO))); if (pAdapterInfo == nullptr) { SPDLOG_ERROR(TEXT("Error allocating memory needed to call GetAdaptersinfo")); return -ERR_MALLOC_MEMORY; } if (GetAdaptersInfo(pAdapterInfo, &ulOutBufLen) == ERROR_BUFFER_OVERFLOW) { HeapFree(GetProcessHeap(), 0, pAdapterInfo); pAdapterInfo = static_cast(HeapAlloc(GetProcessHeap(), 0, ulOutBufLen)); if (pAdapterInfo == nullptr) { SPDLOG_ERROR(TEXT("Error allocating memory needed to call GetAdaptersinfo")); return -ERR_MALLOC_MEMORY; } } if ((dwRetVal = GetAdaptersInfo(pAdapterInfo, &ulOutBufLen)) == NO_ERROR) { PIP_ADAPTER_INFO pAdapter = pAdapterInfo; while (pAdapter) { if (ifIndex == static_cast(pAdapter->Index)) { int ret; WCHAR strGuid[MAX_PATH]; if ((ret = TCharToWideChar(pAdapter->AdapterName, strGuid, MAX_PATH)) != ERR_SUCCESS) { HeapFree(GetProcessHeap(), 0, pAdapterInfo); return ret; } if (CLSIDFromString(strGuid, pGuid) != NOERROR) { HeapFree(GetProcessHeap(), 0, pAdapterInfo); return -ERR_MEMORY_STR; } HeapFree(GetProcessHeap(), 0, pAdapterInfo); return ERR_SUCCESS; } pAdapter = pAdapter->Next; } } else { SPDLOG_ERROR(TEXT("GetAdaptersInfo failed with error: {0}"), dwRetVal); HeapFree(GetProcessHeap(), 0, pAdapterInfo); return -ERR_SYS_CALL; } if (pAdapterInfo) { HeapFree(GetProcessHeap(), 0, pAdapterInfo); } return -ERR_ITEM_UNEXISTS; } /** * @brief 根据网卡名获取网卡索引 * @param[in] pInterfaceName 网卡名称 * @param[out] pIfIndex 网卡 Index * @return 函数执行结果 0: 成功, 小于0 失败 @see USER_ERRNO * - -ERR_INPUT_PARAMS 输入参数错误 * - -ERR_ITEM_UNEXISTS 网卡不存在 * - -ERR_SYS_CALL 获取操作系统网卡适配器失败 * - -ERR_MALLOC_MEMORY 分配内存失败 * - ERR_SUCCESS 成功 */ int GetInterfaceIfIndexByName(const TCHAR *pInterfaceName, int *pIfIndex) { PIP_ADAPTER_INFO pAdapterInfo; DWORD dwRetVal; ULONG ulOutBufLen; if (pInterfaceName == nullptr || lstrlen(pInterfaceName) == 0) { SPDLOG_ERROR(TEXT("Input pInterfaceName error: {0}"), pInterfaceName); return -ERR_INPUT_PARAMS; } if (pIfIndex == nullptr) { SPDLOG_ERROR(TEXT("Input pIfIndex params error.")); return -ERR_INPUT_PARAMS; } ulOutBufLen = sizeof(IP_ADAPTER_INFO); pAdapterInfo = static_cast(HeapAlloc(GetProcessHeap(), 0, sizeof(IP_ADAPTER_INFO))); if (pAdapterInfo == nullptr) { SPDLOG_ERROR(TEXT("Error allocating memory needed to call GetAdaptersinfo")); return -ERR_MALLOC_MEMORY; } if (GetAdaptersInfo(pAdapterInfo, &ulOutBufLen) == ERROR_BUFFER_OVERFLOW) { HeapFree(GetProcessHeap(), 0, pAdapterInfo); pAdapterInfo = static_cast(HeapAlloc(GetProcessHeap(), 0, ulOutBufLen)); if (pAdapterInfo == nullptr) { SPDLOG_ERROR(TEXT("Error allocating memory needed to call GetAdaptersinfo\n")); return -ERR_MALLOC_MEMORY; } } *pIfIndex = -1; if ((dwRetVal = GetAdaptersInfo(pAdapterInfo, &ulOutBufLen)) == NO_ERROR) { PIP_ADAPTER_INFO pAdapter = pAdapterInfo; while (pAdapter) { TCHAR NetCardName[MAX_NETCARD_NAME] = {}; GetInterfaceNameByGUID(pAdapter->AdapterName, NetCardName, nullptr); if (StrCmp(pInterfaceName, NetCardName) == 0) { *pIfIndex = static_cast(pAdapter->Index); HeapFree(GetProcessHeap(), 0, pAdapterInfo); return ERR_SUCCESS; } pAdapter = pAdapter->Next; } } else { SPDLOG_ERROR(TEXT("GetAdaptersInfo failed with error: {0}\n"), dwRetVal); HeapFree(GetProcessHeap(), 0, pAdapterInfo); return -ERR_SYS_CALL; } if (pAdapterInfo) { HeapFree(GetProcessHeap(), 0, pAdapterInfo); } return -ERR_ITEM_UNEXISTS; } int GetInterfaceGUIDByName(const TCHAR *pInterfaceName, GUID *pGuid) { PIP_ADAPTER_INFO pAdapterInfo; DWORD dwRetVal; ULONG ulOutBufLen; if (pInterfaceName == nullptr || lstrlen(pInterfaceName) == 0) { SPDLOG_ERROR(TEXT("Input pInterfaceName error: {0}"), pInterfaceName); return -ERR_INPUT_PARAMS; } if (pGuid == nullptr) { SPDLOG_ERROR(TEXT("Input pGuid params error")); return -ERR_INPUT_PARAMS; } ulOutBufLen = sizeof(IP_ADAPTER_INFO); pAdapterInfo = static_cast(HeapAlloc(GetProcessHeap(), 0, sizeof(IP_ADAPTER_INFO))); if (pAdapterInfo == nullptr) { SPDLOG_ERROR(TEXT("Error allocating memory needed to call GetAdaptersinfo")); return -ERR_MALLOC_MEMORY; } if (GetAdaptersInfo(pAdapterInfo, &ulOutBufLen) == ERROR_BUFFER_OVERFLOW) { HeapFree(GetProcessHeap(), 0, pAdapterInfo); pAdapterInfo = static_cast(HeapAlloc(GetProcessHeap(), 0, ulOutBufLen)); if (pAdapterInfo == nullptr) { SPDLOG_ERROR(TEXT("Error allocating memory needed to call GetAdaptersinfo\n")); return -ERR_MALLOC_MEMORY; } } if ((dwRetVal = GetAdaptersInfo(pAdapterInfo, &ulOutBufLen)) == NO_ERROR) { PIP_ADAPTER_INFO pAdapter = pAdapterInfo; while (pAdapter) { int ret; TCHAR NetCardName[MAX_NETCARD_NAME] = {}; GetInterfaceNameByGUID(pAdapter->AdapterName, NetCardName, nullptr); if (StrCmp(pInterfaceName, NetCardName) == 0) { WCHAR strGuid[MAX_PATH]; if ((ret = TCharToWideChar(pAdapter->AdapterName, strGuid, MAX_PATH)) != ERR_SUCCESS) { HeapFree(GetProcessHeap(), 0, pAdapterInfo); return ret; } if (CLSIDFromString(strGuid, pGuid) != NOERROR) { HeapFree(GetProcessHeap(), 0, pAdapterInfo); return -ERR_MEMORY_STR; } HeapFree(GetProcessHeap(), 0, pAdapterInfo); return ERR_SUCCESS; } pAdapter = pAdapter->Next; } } else { SPDLOG_ERROR(TEXT("GetAdaptersInfo failed with error: {0}\n"), dwRetVal); HeapFree(GetProcessHeap(), 0, pAdapterInfo); return -ERR_SYS_CALL; } if (pAdapterInfo) { HeapFree(GetProcessHeap(), 0, pAdapterInfo); } return -ERR_ITEM_UNEXISTS; } int WaitNetAdapterConnected(const TCHAR *pInterfaceName, int timeOutOfMs) { INetworkListManager *pNLM; IEnumNetworkConnections *pEnumConns; INetwork *pINet; INetworkConnection *pIConn; HRESULT hr; GUID guid; const DWORD startTime = timeGetTime(); if (pInterfaceName == nullptr || lstrlen(pInterfaceName) == 0) { SPDLOG_ERROR(TEXT("Input pInterfaceName params error: {0}"), pInterfaceName); return -ERR_INPUT_PARAMS; } hr = ::CoCreateInstance(CLSID_NetworkListManager, nullptr, CLSCTX_ALL, IID_INetworkListManager, reinterpret_cast(&pNLM)); if (hr != S_OK || pNLM == nullptr) { SPDLOG_ERROR(TEXT("CoCreateInstance NetworkListManager failed: {0}."), hr); return -ERR_CREATE_COMMOBJECT; } do { hr = pNLM->GetNetworkConnections(&pEnumConns); if (hr != S_OK || pEnumConns == nullptr) { SPDLOG_ERROR(TEXT("NetworkListManager GetNetworks failed: {0}."), hr); continue; } while (S_OK == pEnumConns->Next(1, &pIConn, nullptr)) { GUID adpterGuid; pIConn->GetAdapterId(&adpterGuid); pIConn->GetNetwork(&pINet); if (pINet) { BSTR sName = {}; TCHAR ifName[MAX_PATH]; pINet->GetName(&sName); if (WideCharToTChar(sName, ifName, MAX_PATH) != ERR_SUCCESS) { SysFreeString(sName); return -ERR_MEMORY_STR; } SysFreeString(sName); if (StrNCmp(pInterfaceName, ifName, lstrlen(pInterfaceName)) == 0) { int ret = GetInterfaceGUIDByName(pInterfaceName, &guid); if (ret != ERR_SUCCESS) { SPDLOG_ERROR(TEXT("Get Interface {0} GUID error: {1}"), pInterfaceName, ret); continue; } /*SPDLOG_DEBUG(TEXT("Match Interface {0} --> {1}, Guid {2:x} --> {3:x}"), ifName, pInterfaceName, adpterGuid.Data1, guid.Data1);*/ if (memcmp(&adpterGuid, &guid, sizeof(GUID)) == 0) { SPDLOG_DEBUG(TEXT("Interface {0}({1}) network connected now..."), ifName, pInterfaceName); return ERR_SUCCESS; } } } } Sleep(1000); } while (timeGetTime() - startTime <= static_cast(timeOutOfMs)); return -ERR_SYS_TIMEOUT; } int GetAllNICInfo(PNIC_CONTENT *pInfo, int *pItemCounts) { PNIC_CONTENT pNic; PIP_ADAPTER_INFO pAdapterInfo; DWORD dwRetVal; if (pItemCounts == nullptr) { SPDLOG_ERROR(TEXT("Input pItemCounts params error")); return -ERR_INPUT_PARAMS; } if (pInfo == nullptr) { SPDLOG_ERROR(TEXT("Input pInfo params error")); return -ERR_INPUT_PARAMS; } ULONG ulOutBufLen = sizeof(IP_ADAPTER_INFO); pAdapterInfo = static_cast(HeapAlloc(GetProcessHeap(), 0, sizeof(IP_ADAPTER_INFO))); if (pAdapterInfo == nullptr) { SPDLOG_ERROR(TEXT("Error allocating memory needed to call GetAdaptersinfo")); return -ERR_MALLOC_MEMORY; } if (GetAdaptersInfo(pAdapterInfo, &ulOutBufLen) == ERROR_BUFFER_OVERFLOW) { HeapFree(GetProcessHeap(), 0, pAdapterInfo); pAdapterInfo = static_cast(HeapAlloc(GetProcessHeap(), 0, ulOutBufLen)); if (pAdapterInfo == nullptr) { SPDLOG_ERROR(TEXT("Error allocating memory needed to call GetAdaptersinfo\n")); return -ERR_MALLOC_MEMORY; } } if ((dwRetVal = GetAdaptersInfo(pAdapterInfo, &ulOutBufLen)) == NO_ERROR) { int id = 0; int ncStatus; PIP_ADAPTER_INFO pAdapter = pAdapterInfo; while (pAdapter && id < NET_CARD_MAX) { // 网卡索引 g_NetAdapterInfo[id].InterfaceIndex = static_cast(pAdapter->Index); // 网卡名称 StringCbCopy(g_NetAdapterInfo[id].NetCardUUID, MAX_ADAPTER_NAME_LENGTH, pAdapter->AdapterName); // 网卡详细描述 StringCbCopy(g_NetAdapterInfo[id].NetCardDescription, MAX_ADAPTER_DESCRIPTION_LENGTH, pAdapter->Description); // 网卡 IP 地址 StringCbCopy(g_NetAdapterInfo[id].NetCardIpaddr, MAX_IP_LEN - 1, pAdapter->IpAddressList.IpAddress.String); // 网卡子网掩码 StringCbCopy(g_NetAdapterInfo[id].NetCardNetmask, MAX_IP_LEN - 1, pAdapter->IpAddressList.IpMask.String); // 网卡网关地址 StringCbCopy(g_NetAdapterInfo[id].NetCardGateway, MAX_IP_LEN - 1, pAdapter->GatewayList.IpAddress.String); // 网卡 MAC 地址 StringCbPrintf(g_NetAdapterInfo[id].NetCardMacAddr, 20 - 1, TEXT("%02X:%02X:%02X:%02X:%02X:%02X"), pAdapter->Address[0], pAdapter->Address[1], pAdapter->Address[2], pAdapter->Address[3], pAdapter->Address[4], pAdapter->Address[5]); if (GetInterfaceNameByGUID(pAdapter->AdapterName, g_NetAdapterInfo[id].NetCardName, &ncStatus) == ERR_SUCCESS) { g_NetAdapterInfo[id].netConnStatus = static_cast(ncStatus); } id++; pAdapter = pAdapter->Next; } *pItemCounts = id; } else { SPDLOG_ERROR(TEXT("GetAdaptersInfo failed with error: {0}\n"), dwRetVal); HeapFree(GetProcessHeap(), 0, pAdapterInfo); return -ERR_SYS_CALL; } if (pAdapterInfo) { HeapFree(GetProcessHeap(), 0, pAdapterInfo); } pNic = static_cast(CoTaskMemAlloc(sizeof(NIC_CONTENT) * (*pItemCounts))); if (pNic == nullptr) { *pItemCounts = 0; SPDLOG_ERROR(TEXT("Error allocating memory {0} bytes"), sizeof(NIC_CONTENT) * (*pItemCounts)); return -ERR_MALLOC_MEMORY; } memset(pNic, 0, sizeof(NIC_CONTENT) * (*pItemCounts)); memcpy(pNic, g_NetAdapterInfo, sizeof(NIC_CONTENT) * *pItemCounts); *pInfo = pNic; return ERR_SUCCESS; } int IsInternetConnectAdapter(int ifIndex, bool *pRet) { DWORD dwSize = 0; DWORD dwRetVal; PMIB_IPFORWARDTABLE pIpForwardTable; if (ifIndex < 0 || ifIndex > 255) { SPDLOG_ERROR(TEXT("Input ifIndex params error: {0}"), ifIndex); return -ERR_INPUT_PARAMS; } if (pRet == nullptr) { SPDLOG_ERROR(TEXT("Input pRet params error")); return -ERR_INPUT_PARAMS; } pIpForwardTable = static_cast(HeapAlloc(GetProcessHeap(), 0, sizeof(MIB_IPFORWARDTABLE))); if (pIpForwardTable == nullptr) { SPDLOG_ERROR(TEXT("Malloc {0} bytes memory error"), sizeof(MIB_IPFORWARDTABLE)); return -ERR_MALLOC_MEMORY; } if (GetIpForwardTable(pIpForwardTable, &dwSize, 0) == ERROR_INSUFFICIENT_BUFFER) { HeapFree(GetProcessHeap(), 0, pIpForwardTable); pIpForwardTable = static_cast(HeapAlloc(GetProcessHeap(), 0, dwSize)); if (pIpForwardTable == nullptr) { SPDLOG_ERROR(TEXT("Malloc {0} bytes memory error"), dwSize); return -ERR_MALLOC_MEMORY; } } *pRet = false; if ((dwRetVal = GetIpForwardTable(pIpForwardTable, &dwSize, 0)) == NO_ERROR) { for (DWORD i = 0; i < pIpForwardTable->dwNumEntries; i++) { TCHAR ipStr[24] = {}; TCHAR maskStr[24] = {}; if (static_cast(pIpForwardTable->table[i].dwForwardIfIndex) != ifIndex) { continue; } if (InetNtop(AF_INET, &pIpForwardTable->table[i].dwForwardDest, ipStr, 24) == nullptr) { continue; } if (InetNtop(AF_INET, &pIpForwardTable->table[i].dwForwardMask, maskStr, 24) == nullptr) { continue; } if (StrCmp(ipStr, TEXT("0.0.0.0")) == 0 && StrCmp(maskStr, TEXT("0.0.0.0")) == 0) { *pRet = true; break; } } HeapFree(GetProcessHeap(), 0, pIpForwardTable); return ERR_SUCCESS; } else { SPDLOG_ERROR(TEXT("GetIpForwardTable failed: {0}."), dwRetVal); HeapFree(GetProcessHeap(), 0, pIpForwardTable); return ERR_GET_IPFOWARDTBL; } } int SetNetConnectionNetworkCategory(const TCHAR *pInterfaceName, const bool isPrivate) { INetworkListManager *pNLM; IEnumNetworkConnections *pEnumConns; INetwork *pINet; INetworkConnection *pIConn; HRESULT hr; GUID guid; int ret; if (pInterfaceName == nullptr || lstrlen(pInterfaceName) == 0) { SPDLOG_ERROR(TEXT("Input pInterfaceName params error: {0}"), pInterfaceName); return -ERR_INPUT_PARAMS; } if ((ret = GetInterfaceGUIDByName(pInterfaceName, &guid)) != ERR_SUCCESS) { SPDLOG_ERROR(TEXT("Get NetCard [{0}] GUID error: {1}"), pInterfaceName, ret); return ret; } hr = ::CoCreateInstance(CLSID_NetworkListManager, nullptr, CLSCTX_ALL, IID_INetworkListManager, reinterpret_cast(&pNLM)); if (hr != S_OK || pNLM == nullptr) { SPDLOG_ERROR(TEXT("CoCreateInstance NetworkListManager failed: {0}."), hr); return -ERR_CREATE_COMMOBJECT; } hr = pNLM->GetNetworkConnections(&pEnumConns); if (hr != S_OK || pEnumConns == nullptr) { SPDLOG_ERROR(TEXT("NetworkListManager GetNetworks failed: {0}."), hr); return -ERR_CREATE_COMMOBJECT; } while (S_OK == pEnumConns->Next(1, &pIConn, nullptr)) { GUID adpterGuid; pIConn->GetNetwork(&pINet); pIConn->GetAdapterId(&adpterGuid); if (pINet) { if (memcmp(&adpterGuid, &guid, sizeof(GUID)) == 0) { pINet->SetCategory(isPrivate ? NLM_NETWORK_CATEGORY_PRIVATE : NLM_NETWORK_CATEGORY_PUBLIC); return ERR_SUCCESS; } } } return -ERR_ITEM_UNEXISTS; } int GetNetConnectionNetworkCategory(const TCHAR *pInterfaceName, bool *pIsPrivate) { INetworkListManager *pNLM; IEnumNetworkConnections *pEnumConns; INetwork *pINet; INetworkConnection *pIConn; HRESULT hr; GUID guid; int ret; if (pInterfaceName == nullptr || lstrlen(pInterfaceName) == 0) { SPDLOG_ERROR(TEXT("Input pInterfaceName params error: {0}"), pInterfaceName); return -ERR_INPUT_PARAMS; } if (pIsPrivate == nullptr) { SPDLOG_ERROR(TEXT("Input pIsPrivate params error")); return -ERR_INPUT_PARAMS; } if ((ret = GetInterfaceGUIDByName(pInterfaceName, &guid)) != ERR_SUCCESS) { SPDLOG_ERROR(TEXT("Get NetCard [{0}] GUID error: {1}"), pInterfaceName, ret); return ret; } hr = ::CoCreateInstance(CLSID_NetworkListManager, nullptr, CLSCTX_ALL, IID_INetworkListManager, reinterpret_cast(&pNLM)); if (hr != S_OK || pNLM == nullptr) { SPDLOG_ERROR(TEXT("CoCreateInstance NetworkListManager failed: {0}."), hr); return -ERR_CREATE_COMMOBJECT; } hr = pNLM->GetNetworkConnections(&pEnumConns); if (hr != S_OK || pEnumConns == nullptr) { SPDLOG_ERROR(TEXT("NetworkListManager GetNetworks failed: {0}."), hr); return -ERR_CREATE_COMMOBJECT; } while (S_OK == pEnumConns->Next(1, &pIConn, nullptr)) { GUID adpterGuid; pIConn->GetNetwork(&pINet); pIConn->GetAdapterId(&adpterGuid); if (pINet) { if (memcmp(&adpterGuid, &guid, sizeof(GUID)) == 0) { NLM_NETWORK_CATEGORY cat; pINet->GetCategory(&cat); *pIsPrivate = (cat == NLM_NETWORK_CATEGORY_PRIVATE) ? true : false; return ERR_SUCCESS; } } } return -ERR_ITEM_UNEXISTS; } int SetNetIntelnetConnectionSharing(int ifIndex, bool isEnable, bool isSetPrivate) { VARIANT v; INetConnection *pNC = nullptr; INetSharingConfiguration *pNSC = nullptr; IEnumVARIANT *pEV = nullptr; IUnknown *pUnk = nullptr; INetSharingEveryConnectionCollection *pNSECC = nullptr; INetSharingManager *pNSM; HRESULT hr; GUID ifGuid; int ret; if ((ret = GetInterfaceGUIDByIfIndex(ifIndex, &ifGuid)) != ERR_SUCCESS) { return ret; } hr = ::CoCreateInstance(CLSID_NetSharingManager, nullptr, CLSCTX_ALL, IID_INetSharingManager, reinterpret_cast(&pNSM)); if (hr != S_OK || pNSM == nullptr) { SPDLOG_ERROR(TEXT("CoCreateInstance NetSharingManager failed: {0}."), hr); return -ERR_CREATE_COMMOBJECT; } VariantInit(&v); hr = pNSM->get_EnumEveryConnection(&pNSECC); if (hr != S_OK || !pNSECC) { SPDLOG_ERROR(TEXT("INetSharingManager get_EnumEveryConnection failed: {0}."), hr); return -ERR_SYS_CALL; } hr = pNSECC->get__NewEnum(&pUnk); pNSECC->Release(); if (hr != S_OK || !pUnk) { SPDLOG_ERROR(TEXT("INetSharingManager get_EnumEveryConnection failed: {0}."), hr); return -ERR_SYS_CALL; } hr = pUnk->QueryInterface(IID_IEnumVARIANT, reinterpret_cast(&pEV)); pUnk->Release(); if (hr != S_OK || !pUnk) { SPDLOG_ERROR(TEXT("INetSharingManager get_EnumEveryConnection failed: {0}."), hr); return -ERR_SYS_CALL; } while (S_OK == pEV->Next(1, &v, nullptr)) { if (V_VT(&v) == VT_UNKNOWN) { V_UNKNOWN(&v)->QueryInterface(IID_INetConnection, reinterpret_cast(&pNC)); if (pNC) { NETCON_PROPERTIES *pNP; pNC->GetProperties(&pNP); // 找到对应的网卡进行处理 if (memcmp(&ifGuid, &pNP->guidId, sizeof(GUID)) != 0) { continue; } // 未连接的网卡不处理 if (pNP->Status != NCS_CONNECTED) { return -ERR_NET_UNCONNECT; } hr = pNSM->get_INetSharingConfigurationForINetConnection(pNC, &pNSC); if (hr != S_OK || !pNSC) { continue; } if (pNSC) { if (isEnable) { hr = pNSC->DisableSharing(); if (hr != S_OK) { SPDLOG_ERROR(TEXT("INetSharingManager DisableSharing failed: {0}."), hr); pNSC->Release(); return -ERR_CALL_COMMOBJECT; } Sleep(500); hr = pNSC->EnableSharing(isSetPrivate ? ICSSHARINGTYPE_PRIVATE : ICSSHARINGTYPE_PUBLIC); if (hr != S_OK) { SPDLOG_ERROR(TEXT("INetSharingManager EnableSharing failed: {0}."), hr); pNSC->Release(); return -ERR_CALL_COMMOBJECT; } } else { hr = pNSC->DisableSharing(); if (hr != S_OK) { SPDLOG_ERROR(TEXT("INetSharingManager DisableSharing failed: {0}."), hr); pNSC->Release(); return -ERR_CALL_COMMOBJECT; } } pNSC->Release(); return ERR_SUCCESS; } } } } return ERR_ITEM_UNEXISTS; } int GetNetIntelnetConnectionSharing(int ifIndex, bool *pIsEnable) { VARIANT v; INetConnection *pNC = nullptr; INetSharingConfiguration *pNSC = nullptr; IEnumVARIANT *pEV = nullptr; IUnknown *pUnk = nullptr; INetSharingEveryConnectionCollection *pNSECC = nullptr; INetSharingManager *pNSM; HRESULT hr; GUID ifGuid; int ret; if (pIsEnable == nullptr) { SPDLOG_ERROR(TEXT("Input pIsEnable params error")); return -ERR_INPUT_PARAMS; } // 根据网卡索引获取网卡GUID if ((ret = GetInterfaceGUIDByIfIndex(ifIndex, &ifGuid)) != ERR_SUCCESS) { return ret; } hr = ::CoCreateInstance(CLSID_NetSharingManager, nullptr, CLSCTX_ALL, IID_INetSharingManager, reinterpret_cast(&pNSM)); if (hr != S_OK || pNSM == nullptr) { SPDLOG_ERROR(TEXT("CoCreateInstance NetSharingManager failed: {0}."), hr); return -ERR_CREATE_COMMOBJECT; } VariantInit(&v); hr = pNSM->get_EnumEveryConnection(&pNSECC); if (hr != S_OK || !pNSECC) { SPDLOG_ERROR(TEXT("INetSharingManager get_EnumEveryConnection failed: {0}."), hr); return -ERR_SYS_CALL; } hr = pNSECC->get__NewEnum(&pUnk); pNSECC->Release(); if (hr != S_OK || !pUnk) { SPDLOG_ERROR(TEXT("INetSharingManager get_EnumEveryConnection failed: {0}."), hr); return -ERR_SYS_CALL; } hr = pUnk->QueryInterface(IID_IEnumVARIANT, reinterpret_cast(&pEV)); pUnk->Release(); if (hr != S_OK || !pUnk) { SPDLOG_ERROR(TEXT("INetSharingManager get_EnumEveryConnection failed: {0}."), hr); return -ERR_SYS_CALL; } while (S_OK == pEV->Next(1, &v, nullptr)) { if (V_VT(&v) == VT_UNKNOWN) { V_UNKNOWN(&v)->QueryInterface(IID_INetConnection, reinterpret_cast(&pNC)); if (pNC) { NETCON_PROPERTIES *pNP; pNC->GetProperties(&pNP); // 找到对应的网卡进行处理 if (memcmp(&ifGuid, &pNP->guidId, sizeof(GUID)) != 0) { continue; } //if (StrCmp(pInterfaceName, ifName) != 0) { // continue; //} hr = pNSM->get_INetSharingConfigurationForINetConnection(pNC, &pNSC); if (hr != S_OK || !pNSC) { continue; } if (pNSC) { VARIANT_BOOL bRet = false; hr = pNSC->get_SharingEnabled(&bRet); pNSC->Release(); if (hr != S_OK) { SPDLOG_ERROR(TEXT("INetSharingManager DisableSharing failed: {0}."), hr); return -ERR_CALL_COMMOBJECT; } *pIsEnable = bRet; return ERR_SUCCESS; } } } } return ERR_ITEM_UNEXISTS; } int AddRouteTable(const char *pIP, const char *pMask, const char *pGateway) { PMIB_IPFORWARDTABLE pIpForwardTable = nullptr; PMIB_IPFORWARDROW pRow = nullptr; DWORD dwSize = 0; DWORD dwStatus; DWORD dwDestIp; int ret; IP_INFO ipInfo; if (pIP == nullptr || lstrlen(pIP) < MIN_IP_LEN) { SPDLOG_ERROR(TEXT("Input pIP params error: {0}"), pIP); return -ERR_INPUT_PARAMS; } if (pMask == nullptr || lstrlen(pMask) < MIN_IP_LEN) { SPDLOG_ERROR(TEXT("Input pMask params error: {0}"), pMask); return -ERR_INPUT_PARAMS; } if (pGateway == nullptr || lstrlen(pGateway) < MIN_IP_LEN) { SPDLOG_ERROR(TEXT("Input pGateway params error: {0}"), pGateway); return -ERR_INPUT_PARAMS; } if ((ret = GetIpV4InfoFromNetmask(pIP, pMask, &ipInfo)) != ERR_SUCCESS) { return ret; } if (inet_pton(AF_INET, ipInfo.network, &dwDestIp) <= 0) { SPDLOG_ERROR(TEXT("Convert {0} to network ipaddress error."), pIP); return -ERR_UN_SUPPORT; } // Find out how big our buffer needs to be. dwStatus = GetIpForwardTable(pIpForwardTable, &dwSize, FALSE); if (dwStatus == ERROR_INSUFFICIENT_BUFFER) { // Allocate the memory for the table pIpForwardTable = static_cast(malloc(dwSize)); if (!pIpForwardTable) { SPDLOG_ERROR(TEXT("Malloc failed. Out of memory.")); return -ERR_MALLOC_MEMORY; } // Now get the table. dwStatus = GetIpForwardTable(pIpForwardTable, &dwSize, FALSE); } if (dwStatus != ERROR_SUCCESS) { SPDLOG_ERROR(TEXT("getIpForwardTable failed.")); if (pIpForwardTable) { free(pIpForwardTable); } return -ERR_SYS_CALL; } for (DWORD i = 0; i < pIpForwardTable->dwNumEntries; i++) { if (pIpForwardTable->table[i].dwForwardDest == 0) { if (!pRow) { pRow = static_cast(malloc(sizeof(MIB_IPFORWARDROW))); if (!pRow) { SPDLOG_ERROR(TEXT("Malloc failed. Out of memory.")); free(pIpForwardTable); free(pRow); return -ERR_MALLOC_MEMORY; } // Copy the row memcpy(pRow, &(pIpForwardTable->table[i]), sizeof(MIB_IPFORWARDROW)); } } else if (pIpForwardTable->table[i].dwForwardDest == dwDestIp) { // 删除可能存在的旧的路由信息 dwStatus = DeleteIpForwardEntry(&(pIpForwardTable->table[i])); if (dwStatus != ERROR_SUCCESS) { SPDLOG_ERROR(TEXT("Could not delete old gateway")); return -ERR_NET_REMOVE_ROUTE; } } } free(pIpForwardTable); pRow->dwForwardDest = dwDestIp; if (inet_pton(AF_INET, ipInfo.netmask, &pRow->dwForwardMask) <= 0) { SPDLOG_ERROR(TEXT("Convert {0} to network ipaddress error."), pMask); return -ERR_UN_SUPPORT; } if (inet_pton(AF_INET, pGateway, &pRow->dwForwardNextHop) <= 0) { SPDLOG_ERROR(TEXT("Convert {0} to network ipaddress error."), pGateway); free(pRow); return -ERR_UN_SUPPORT; } if ((ret = GetInterfaceIfIndexByIpAddr(pGateway, &pRow->dwForwardIfIndex)) != ERR_SUCCESS) { free(pRow); return ret; } if ((dwStatus = CreateIpForwardEntry(pRow)) != NO_ERROR) { SPDLOG_ERROR(TEXT("Add Route {1} netmask {2} gateway {3} error: {0}."), dwStatus, pIP, pMask, pGateway); free(pRow); return -ERR_NET_ADD_ROUTE; } free(pRow); return ERR_SUCCESS; } int SetNATRule(const TCHAR *pInterfaceName, const TCHAR *pCidrIpaddr) { int ret; TCHAR cmdBuf[1024]; DWORD retCode; if (pInterfaceName == nullptr || lstrlen(pInterfaceName) == 0) { SPDLOG_ERROR("Input pInterfaceName params error: {0}", pInterfaceName); return -ERR_INPUT_PARAMS; } if (pCidrIpaddr == nullptr || lstrlen(pCidrIpaddr) == 0) { SPDLOG_ERROR("Input pCidrIpaddr params error: {0}", pCidrIpaddr); return -ERR_INPUT_PARAMS; } if (FAILED(StringCbPrintf( cmdBuf, 1024, TEXT("PowerShell -NoProfile -NonInteractive -WindowStyle Hidden -ExecutionPolicy Bypass Invoke-Command " "-ScriptBlock { Get-NetNat -Name %s_nat -ErrorAction Ignore | Remove-NetNat -Confirm:$false; " "New-NetNat -Name %s_nat -InternalIPInterfaceAddressPrefix %s }"), pInterfaceName, pInterfaceName, pCidrIpaddr))) { SPDLOG_ERROR("Format String Error"); return -ERR_MEMORY_STR; } if ((ret = RunCommand(cmdBuf, nullptr, 0, &retCode)) != ERR_SUCCESS) { SPDLOG_ERROR("Run command [{0}] error: {1}", cmdBuf, ret); return -ERR_CALL_SHELL; } SPDLOG_DEBUG("Run Command({1}): {0}", cmdBuf, retCode); if (retCode != 0) { SPDLOG_ERROR("PowerShell return error({1}): {0}", cmdBuf, retCode); return -ERR_PROCESS_RETURN; } return ERR_SUCCESS; } int RemoveNATRule(const TCHAR *pInterfaceName) { int ret; TCHAR cmdBuf[1024]; DWORD retCode; if (pInterfaceName == nullptr || lstrlen(pInterfaceName) == 0) { SPDLOG_ERROR("Input pInterfaceName params error: {0}", pInterfaceName); return -ERR_INPUT_PARAMS; } if (FAILED(StringCbPrintf( cmdBuf, 1024, TEXT("PowerShell -NoProfile -NonInteractive -WindowStyle Hidden -ExecutionPolicy Bypass Invoke-Command " "-ScriptBlock { Get-NetNat -Name %s_nat -ErrorAction Ignore | Remove-NetNat -Confirm:$false}"), pInterfaceName))) { SPDLOG_ERROR("Format String Error"); return -ERR_MEMORY_STR; } if ((ret = RunCommand(cmdBuf, nullptr, 0, &retCode)) != ERR_SUCCESS) { SPDLOG_ERROR("Run command [{0}] error: {1}", cmdBuf, ret); return -ERR_CALL_SHELL; } SPDLOG_DEBUG("Run Command({1}): {0}", cmdBuf, retCode); return ERR_SUCCESS; } #if 0 int SetInterfaceIpAddress(const TCHAR *pInterfaceName, const TCHAR *pIpaddr, const TCHAR *pNetmask) { int ret; TCHAR cmdBuf[MAX_PATH]; //int cidr; DWORD retCode; IP_INFO ipInfo {}; if (pInterfaceName == nullptr || lstrlen(pInterfaceName) == 0) { SPDLOG_ERROR("Input pInterfaceName params error: {0}", pInterfaceName); return -ERR_INPUT_PARAMS; } if (pIpaddr == nullptr || lstrlen(pIpaddr) == 0) { SPDLOG_ERROR("Input pIpaddr params error: {0}", pIpaddr); return -ERR_INPUT_PARAMS; } if (pNetmask == nullptr || lstrlen(pNetmask) == 0) { SPDLOG_WARN("Input pNetmask params error: {0}", pNetmask); return -ERR_INPUT_PARAMS; } GetIpV4InfoFromNetmask(pIpaddr, pNetmask, &ipInfo); //cidr = NetmaskToCIDR(pNetmask); if (FAILED(StringCbPrintf( cmdBuf, MAX_PATH, "PowerShell -Command \"& {New-NetIPAddress -InterfaceAlias %s -AddressFamily IPv4 -IPAddress %s -PrefixLength %d}\"", pInterfaceName, pIpaddr, ipInfo.prefix))) { SPDLOG_ERROR("Format String Error"); return -ERR_MEMORY_STR; } if ((ret = RunCommand(cmdBuf, nullptr, 0, &retCode)) != ERR_SUCCESS) { SPDLOG_ERROR("Run command [{0}] error: {1}", cmdBuf, ret); return -ERR_CALL_SHELL; } SPDLOG_DEBUG("Run Set IP Command({1}): {0}", cmdBuf, retCode); return ERR_SUCCESS; } int GetWindowsHyperVStatus(int *pEnabled) { int ret; TCHAR cmdBuf[MAX_PATH]; TCHAR cmdResult[2048]; DWORD retCode; if (pEnabled == nullptr) { SPDLOG_ERROR(TEXT("Input pEnabled params error")); return -ERR_INPUT_PARAMS; } if (FAILED(StringCbPrintf(cmdBuf, MAX_PATH, TEXT("PowerShell -Command \"& {Get-WindowsOptionalFeature -FeatureName Microsoft-Hyper-V-All " "-Online | Format-List -Property State}\"")))) { SPDLOG_ERROR("Format String Error"); return -ERR_MEMORY_STR; } if ((ret = RunCommand(cmdBuf, cmdResult, 2048, &retCode)) != ERR_SUCCESS) { SPDLOG_ERROR("Run command [{0}] error: {1}", cmdBuf, ret); return -ERR_CALL_SHELL; } if (StrStr(cmdResult, TEXT("Enabled")) != nullptr) { *pEnabled = TRUE; } else { *pEnabled = FALSE; } SPDLOG_DEBUG(TEXT("Run Get Windows Hyper-V status Command({1}): {0} result: {2}\n"), cmdBuf, retCode, cmdResult); return ERR_SUCCESS; } int EnableWindowsHyperV(bool enabled) { int ret; TCHAR cmdBuf[MAX_PATH]; DWORD retCode; if (enabled) { if (FAILED(StringCbPrintf(cmdBuf, MAX_PATH, TEXT("PowerShell -Command \"& {Enable-WindowsOptionalFeature -Online -FeatureName " "Microsoft-Hyper-V -All}\"")))) { SPDLOG_ERROR("Format String Error"); return -ERR_MEMORY_STR; } } else { if (FAILED(StringCbPrintf(cmdBuf, MAX_PATH, TEXT("PowerShell -Command \"& {Disable-WindowsOptionalFeature -Online -FeatureName " "Microsoft-Hyper-V-Hypervisor}\"")))) { SPDLOG_ERROR("Format String Error"); return -ERR_MEMORY_STR; } } if ((ret = RunCommand(cmdBuf, nullptr, 0, &retCode)) != ERR_SUCCESS) { SPDLOG_ERROR(TEXT("Run command [{0}] error: {1}"), cmdBuf, ret); return -ERR_CALL_SHELL; } if (retCode != 0) { SPDLOG_ERROR(TEXT("PowerShell return error({1}): {0}"), cmdBuf, retCode); return -ERR_PROCESS_RETURN; } return ERR_SUCCESS; } int GetInterfaceIndexByName(const TCHAR *pInterfaceName, int *pIndex) { int ret; DWORD retCode; TCHAR cmdBuf[MAX_PATH]; TCHAR cmdResult[MAX_PATH] = {}; if (pInterfaceName == nullptr || lstrlen(pInterfaceName) == 0) { SPDLOG_ERROR(TEXT("Input pInterfaceName params error: {0}"), pInterfaceName); return -ERR_INPUT_PARAMS; } if (pIndex == nullptr) { SPDLOG_ERROR(TEXT("Input pIndex params error")); return -ERR_INPUT_PARAMS; } if (FAILED( StringCbPrintf(cmdBuf, MAX_PATH, TEXT("PowerShell -Command \"& {Get-NetAdapter -Name %s | Format-List -Property InterfaceIndex}\""), pInterfaceName))) { SPDLOG_ERROR("Format String Error"); return -ERR_MEMORY_STR; } if ((ret = RunCommand(cmdBuf, cmdResult, MAX_PATH, &retCode)) != ERR_SUCCESS) { SPDLOG_ERROR(TEXT("Run command [{0}] error: {1}"), cmdBuf, ret); return -ERR_CALL_SHELL; } SPDLOG_DEBUG(TEXT("Run command [{0}] resutl \'{1}\' return {2}"), cmdBuf, cmdResult, retCode); // 移除 StringRemoveAll(cmdResult, TEXT("\r\n")); StringRemoveAll(cmdResult, TEXT(" ")); StringRemoveAll(cmdResult, TEXT("InterfaceIndex:")); *pIndex = strtol(cmdResult, nullptr, 10); return ERR_SUCCESS; } int RemoveInterfaceIpAddress(const TCHAR *pInterfaceName) { int ret; TCHAR cmdBuf[MAX_PATH]; DWORD retCode; if (pInterfaceName == nullptr || lstrlen(pInterfaceName) == 0) { SPDLOG_ERROR("Input pInterfaceName params error: {0}", pInterfaceName); return -ERR_INPUT_PARAMS; } if (FAILED(StringCbPrintf(cmdBuf, MAX_PATH, "PowerShell -Command \"& {Remove-NetIPAddress -InterfaceAlias %s -Confirm:$false}\"", pInterfaceName))) { SPDLOG_ERROR("Format String Error"); return -ERR_MEMORY_STR; } if ((ret = RunCommand(cmdBuf, nullptr, 0, &retCode)) != ERR_SUCCESS) { SPDLOG_ERROR("Run command [{0}] error: {1}", cmdBuf, ret); return -ERR_CALL_SHELL; } SPDLOG_DEBUG("Run Set IP Command({1}): {0}", cmdBuf, retCode); return ERR_SUCCESS; } int SetInterfaceIpAddress(const TCHAR *pInterfaceName, const TCHAR *pIpaddr, const TCHAR *pNetmask) { int ret; TCHAR cmdBuf[MAX_PATH]; int cidr; DWORD retCode; if (pInterfaceName == nullptr || lstrlen(pInterfaceName) == 0) { SPDLOG_ERROR("Input pInterfaceName params error: {0}", pInterfaceName); return -ERR_INPUT_PARAMS; } if (pIpaddr == nullptr || lstrlen(pIpaddr) == 0) { SPDLOG_ERROR("Input pIpaddr params error: {0}", pIpaddr); return -ERR_INPUT_PARAMS; } if (pNetmask == nullptr || lstrlen(pNetmask) == 0) { SPDLOG_WARN("Input pNetmask params error: {0}", pNetmask); return -ERR_INPUT_PARAMS; } cidr = NetmaskToCIDR(pNetmask); if (FAILED(StringCbPrintf( cmdBuf, MAX_PATH, "PowerShell -Command \"& {New-NetIPAddress -InterfaceAlias %s -IPAddress %s -PrefixLength %d}\"", pInterfaceName, pIpaddr, cidr))) { SPDLOG_ERROR("Format String Error"); return -ERR_MEMORY_STR; } if ((ret = RunCommand(cmdBuf, nullptr, 0, &retCode)) != ERR_SUCCESS) { SPDLOG_ERROR("Run command [{0}] error: {1}", cmdBuf, ret); return -ERR_CALL_SHELL; } SPDLOG_DEBUG("Run Set IP Command({1}): {0}", cmdBuf, retCode); return ERR_SUCCESS; } int SetInterfaceIpAddressFromCIDR(const TCHAR *pInterfaceName, const TCHAR *pCidrIpaddr) { TCHAR ipAddr[MAX_IP_LEN]; TCHAR ip[MAX_IP_LEN]; int ret; TCHAR cmdBuf[MAX_PATH]; DWORD retCode; TCHAR *token, *p = nullptr; if (pInterfaceName == nullptr || lstrlen(pInterfaceName) == 0) { SPDLOG_ERROR("Input pInterfaceName params error: {0}", pInterfaceName); return -ERR_INPUT_PARAMS; } if (pCidrIpaddr == nullptr || lstrlen(pCidrIpaddr) == 0) { SPDLOG_ERROR("Input pCidrIpaddr params error: {0}", pCidrIpaddr); return -ERR_INPUT_PARAMS; } StringCbCopy(ipAddr, MAX_IP_LEN, pCidrIpaddr); // 获取前面IP地址 token = strtok_s(ipAddr, TEXT("/"), &p); if (token == nullptr) { SPDLOG_ERROR("CIDR IpAddress string format error: {0}", pCidrIpaddr); return -ERR_INPUT_PARAMS; } StringCbCopy(ip, MAX_IP_LEN, token); // 获取后面子网掩码 token = strtok_s(nullptr, TEXT("/"), &p); if (token == nullptr) { SPDLOG_ERROR("CIDR IpAddress string format error: {0}", pCidrIpaddr); return -ERR_INPUT_PARAMS; } if (FAILED(StringCbPrintf( cmdBuf, MAX_PATH, "PowerShell -Command \"& {New-NetIPAddress -InterfaceAlias %s -IPAddress %s -PrefixLength %s}\"", pInterfaceName, ip, token))) { SPDLOG_ERROR("Format String Error"); return -ERR_MEMORY_STR; } if ((ret = RunCommand(cmdBuf, nullptr, 0, &retCode)) != ERR_SUCCESS) { SPDLOG_ERROR("Run command [{0}] error: {1}", cmdBuf, ret); return -ERR_CALL_SHELL; } SPDLOG_DEBUG("Run Set IP Command({1}): {0}", cmdBuf, retCode); return ERR_SUCCESS; } int IsInterfacePrivate(const TCHAR *pInterfaceName, bool *pIsPrivateMode) { int ret; DWORD retCode; TCHAR cmdBuf[MAX_PATH]; TCHAR cmdResult[MAX_PATH] = {}; if (pInterfaceName == nullptr || lstrlen(pInterfaceName) == 0) { SPDLOG_ERROR("Input pInterfaceName params error: {0}", pInterfaceName); return -ERR_INPUT_PARAMS; } if (pIsPrivateMode == nullptr) { SPDLOG_ERROR("Input pIsPrivateMode params error"); return -ERR_INPUT_PARAMS; } if (FAILED(StringCbPrintf( cmdBuf, MAX_PATH, "PowerShell -Command \"& {Get-NetConnectionProfile -Name %s | Format-List -Property NetworkCategory}\"", pInterfaceName))) { SPDLOG_ERROR("Format String Error"); return -ERR_MEMORY_STR; } if ((ret = RunCommand(cmdBuf, cmdResult, MAX_PATH, &retCode)) != ERR_SUCCESS) { SPDLOG_ERROR("Run command [{0}] error: {1}", cmdBuf, ret); return -ERR_CALL_SHELL; } SPDLOG_DEBUG("Run command [{0}] resutl \'{1}\' return {2}", cmdBuf, cmdResult, retCode); if (StrStr(cmdResult, TEXT("Private")) != nullptr) { *pIsPrivateMode = true; return ERR_SUCCESS; } else { if (StrStr(cmdResult, TEXT("Public")) != nullptr) { *pIsPrivateMode = false; return ERR_SUCCESS; } } return -ERR_ITEM_UNEXISTS; } int SetInterfacePrivate(const TCHAR *pInterfaceName, bool isPrivate) { int ret; TCHAR cmdBuf[MAX_PATH]; DWORD retCode; if (isPrivate) { if (FAILED(StringCbPrintf(cmdBuf, MAX_PATH, "PowerShell -Command \"& {Get-NetConnectionProfile -InterfaceAlias %s | " "Set-NetConnectionProfile -NetworkCategory Private}\"", pInterfaceName))) { SPDLOG_ERROR("Format String Error"); return -ERR_MEMORY_STR; } } else { if (FAILED(StringCbPrintf(cmdBuf, MAX_PATH, "PowerShell -Command \"& {Get-NetConnectionProfile -InterfaceAlias %s | " "Set-NetConnectionProfile -NetworkCategory Public}\"", pInterfaceName))) { SPDLOG_ERROR("Format String Error"); return -ERR_MEMORY_STR; } } if ((ret = RunCommand(cmdBuf, nullptr, 0, &retCode)) != ERR_SUCCESS) { SPDLOG_ERROR("Run command [{0}] error: {1}", cmdBuf, ret); return -ERR_CALL_SHELL; } if (retCode != 0) { SPDLOG_ERROR("PowerShell return error({1}): {0}", cmdBuf, retCode); return -ERR_PROCESS_RETURN; } return ERR_SUCCESS; } bool IsCustomNatPSCmdInstalled() { TCHAR psCmdPath[MAX_PATH]; StringCbPrintf(psCmdPath, MAX_PATH, TEXT("%s\\system32\\WindowsPowerShell\\v1.0\\Modules\\wireguard"), GetGlobalCfgInfo()->systemDirectory); // 判断 WireGuard NAT 命令是否安装 if (!PathFileExists(psCmdPath)) { if (!CreateDirectory(psCmdPath, nullptr)) { return false; } } StringCbCat(psCmdPath, MAX_PATH, "\\wireguard.psm1"); if (PathFileExists(psCmdPath)) { // 文件存在说明已经安装 return true; } return false; } int IsNetConnectionSharingEnabled(const TCHAR *pInterfaceName, bool *pIsEnabled) { int ret; DWORD retCode; TCHAR cmdResult[MAX_PATH] = {}; TCHAR cmdBuf[512]; if (pInterfaceName == nullptr || lstrlen(pInterfaceName) == 0) { SPDLOG_ERROR("Input pInterfaceName params error: {0}", pInterfaceName); return -ERR_INPUT_PARAMS; } if (pIsEnabled == nullptr) { SPDLOG_ERROR("Input pIsEnabled params error"); return -ERR_INPUT_PARAMS; } if (FAILED(StringCbPrintf( cmdBuf, 512, TEXT("PowerShell -NoProfile -NonInteractive -WindowStyle Hidden -ExecutionPolicy Bypass Invoke-Command " "-ArgumentList '%s' -ScriptBlock {param($IFNAME);$netShare = New-Object -ComObject HNetCfg.HNetShare;" "$privateConnection = $netShare.EnumEveryConnection |? { $netShare.NetConnectionProps.Invoke($_).Name " "-eq " "'wg_cli' };$privateConfig = " "$netShare.INetSharingConfigurationForINetConnection.Invoke($privateConnection);" "Write-Output $privateConfig}"), pInterfaceName))) { SPDLOG_ERROR("Format String Error"); return -ERR_MEMORY_STR; } if ((ret = RunCommand(cmdBuf, nullptr, 0, &retCode)) != ERR_SUCCESS) { SPDLOG_ERROR("Run command [{0}] error: {1}", cmdBuf, ret); return -ERR_CALL_SHELL; } if (retCode != 0) { SPDLOG_ERROR("PowerShell return error({1}): {0}", cmdBuf, retCode); return -ERR_PROCESS_RETURN; } SPDLOG_DEBUG("Run command [{0}] resutl \'{1}\' return {2}", cmdBuf, cmdResult, retCode); if (StrStr(cmdResult, TEXT("False")) != nullptr) { *pIsEnabled = false; return ERR_SUCCESS; } else { if (StrStr(cmdResult, TEXT("True")) != nullptr) { *pIsEnabled = true; return ERR_SUCCESS; } } return -ERR_ITEM_UNEXISTS; } #endif