VC准确地获取真实网络连接的名字(本地连接)

来源:互联网 发布:黑科技网络验证破解版 编辑:程序博客网 时间:2024/05/01 01:50

因为虚拟机和vpn软件会创建网络连接,电脑就有可能有多个网络连接,用程序获取真实的操作系统的网络连接就比较困难。

原理:注册表项HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\NetworkCards下面会有子键,里面记录的是系统创建的对应真实网卡的网络连接的名字,但是这个名字不太友好,要做转换。

获取到了本地连接的名字之后,再配合netsh命令就可以干很多事情了,比如程序修改网卡的dns服务器地址。

上VC代码:控制台程序,可直接编译测试

目前在xp、win7、win8和win10上面测试了一遍,结果都准确。

// QueryKey - Enumerates the subkeys of key and its associated values.//     hKey - Key whose subkeys and values are to be enumerated.#include <windows.h>#include <stdio.h>#include <tchar.h>#include <Iphlpapi.h>#include <Mprapi.h>#include <string>#include <vector>#include <map>#include <iostream>#include <locale.h>#pragma comment(lib,"Iphlpapi.lib")#pragma comment(lib, "Mprapi.lib")using namespace std;#define MAX_KEY_LENGTH 255#define MAX_VALUE_NAME 16383//网卡名字与连接名字的对应关系,key为网卡名字,value为连接名字map<wstring, wstring> mapAdapterNames;const TCHAR NETWORKCARDS[MAX_KEY_LENGTH] = TEXT("SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\NetworkCards");void QueryKey(HKEY hKey) { TCHAR    achKey[MAX_KEY_LENGTH];   // buffer for subkey nameDWORD    cbName;                   // size of name string TCHAR    achClass[MAX_PATH] = TEXT("");  // buffer for class name DWORD    cchClassName = MAX_PATH;  // size of class string DWORD    cSubKeys=0;               // number of subkeys DWORD    cbMaxSubKey;              // longest subkey size DWORD    cchMaxClass;              // longest class string DWORD    cValues;              // number of values for key DWORD    cchMaxValue;          // longest value name DWORD    cbMaxValueData;       // longest value data DWORD    cbSecurityDescriptor; // size of security descriptor FILETIME ftLastWriteTime;      // last write time DWORD i, retCode; TCHAR  achValue[MAX_VALUE_NAME]; DWORD cchValue = MAX_VALUE_NAME; // Get the class name and the value count. retCode = RegQueryInfoKey(hKey,                    // key handle achClass,                // buffer for class name &cchClassName,           // size of class string NULL,                    // reserved &cSubKeys,               // number of subkeys &cbMaxSubKey,            // longest subkey size &cchMaxClass,            // longest class string &cValues,                // number of values for this key &cchMaxValue,            // longest value name &cbMaxValueData,         // longest value data &cbSecurityDescriptor,   // security descriptor &ftLastWriteTime);       // last write time // Enumerate the subkeys, until RegEnumKeyEx fails.if (cSubKeys){printf( "\nNumber of subkeys: %d\n", cSubKeys);for (i=0; i<cSubKeys; i++) { cbName = MAX_KEY_LENGTH;retCode = RegEnumKeyEx(hKey, i,achKey, &cbName, NULL, NULL, NULL, &ftLastWriteTime); if (retCode == ERROR_SUCCESS) {_tprintf(TEXT("(%d) %s\n"), i+1, achKey);}}} // Enumerate the key values. if (cValues) {printf( "\nNumber of values: %d\n", cValues);for (i=0, retCode=ERROR_SUCCESS; i<cValues; i++) { cchValue = MAX_VALUE_NAME; achValue[0] = '\0'; retCode = RegEnumValue(hKey, i, achValue, &cchValue, NULL, NULL,NULL,NULL);if (retCode == ERROR_SUCCESS ) { _tprintf(TEXT("(%d) %s\n"), i+1, achValue); } }}}void QuerySubKeyValue(HKEY hKey) { TCHAR    achKey[MAX_KEY_LENGTH];   // buffer for subkey nameDWORD    cbName;                   // size of name string TCHAR    achClass[MAX_PATH] = TEXT("");  // buffer for class name DWORD    cchClassName = MAX_PATH;  // size of class string DWORD    cSubKeys=0;               // number of subkeys DWORD    cbMaxSubKey;              // longest subkey size DWORD    cchMaxClass;              // longest class string DWORD    cValues;              // number of values for key DWORD    cchMaxValue;          // longest value name DWORD    cbMaxValueData;       // longest value data DWORD    cbSecurityDescriptor; // size of security descriptor FILETIME ftLastWriteTime;      // last write time DWORD i, retCode; TCHAR  achValue[MAX_VALUE_NAME]; DWORD cchValue = MAX_VALUE_NAME; // Get the class name and the value count. retCode = RegQueryInfoKey(hKey,                    // key handle achClass,                // buffer for class name &cchClassName,           // size of class string NULL,                    // reserved &cSubKeys,               // number of subkeys &cbMaxSubKey,            // longest subkey size &cchMaxClass,            // longest class string &cValues,                // number of values for this key &cchMaxValue,            // longest value name &cbMaxValueData,         // longest value data &cbSecurityDescriptor,   // security descriptor &ftLastWriteTime);       // last write time // Enumerate the subkeys, until RegEnumKeyEx fails.if (cSubKeys){printf( "\nNumber of subkeys: %d\n", cSubKeys);for (i=0; i<cSubKeys; i++) { cbName = MAX_KEY_LENGTH;retCode = RegEnumKeyEx(hKey, i,achKey, &cbName, NULL, NULL, NULL, &ftLastWriteTime); if (retCode == ERROR_SUCCESS) {_tprintf(TEXT("(%d) %s\n"), i+1, achKey);//生成键名TCHAR szFullSubKeyName[MAX_KEY_LENGTH] = {0};_sntprintf(szFullSubKeyName,MAX_KEY_LENGTH,TEXT("%s\\%s"),NETWORKCARDS,achKey);//打开子键HKEY hSubKey;if( RegOpenKeyEx( HKEY_LOCAL_MACHINE,szFullSubKeyName,0,KEY_READ,&hSubKey) == ERROR_SUCCESS){//查询键值TCHAR szSubKeyValue[MAX_VALUE_NAME] = {0};DWORD dwType = REG_NONE, dwResultSize=MAX_VALUE_NAME * sizeof(TCHAR);long lResult = RegQueryValueEx(hSubKey, _T("ServiceName"), 0, &dwType, (BYTE *)(szSubKeyValue), &dwResultSize);if ((lResult==ERROR_SUCCESS) && (dwType==REG_SZ))_tprintf(mapAdapterNames[szSubKeyValue].c_str());//_tprintf(szSubKeyValue);RegCloseKey(hSubKey);}}}}}wstring Ascii2Unicode(string astrsrc){int wideSize = ::MultiByteToWideChar(CP_ACP, 0, astrsrc.c_str(), -1, NULL, 0);if (wideSize == ERROR_NO_UNICODE_TRANSLATION)return L"";if(wideSize <= 0) return wstring(L"");//wchar_t *szbuffer = new wchar_t[nLength + 2];vector<wchar_t> resultString(wideSize);int conResult = ::MultiByteToWideChar(CP_ACP, 0, astrsrc.c_str(), -1, &resultString[0], wideSize);if(conResult != wideSize)return L"";return wstring(&resultString[0]);}//获取网卡名字与连接名字的对应关系void GetAdapterNamesMap(){/********************************************通过Iphlpapi库获取网卡信息********************************************/PIP_ADAPTER_INFO pIpAdapterInfo = (PIP_ADAPTER_INFO) malloc(sizeof(IP_ADAPTER_INFO));ULONG stSize = sizeof(IP_ADAPTER_INFO);int nRel = GetAdaptersInfo(pIpAdapterInfo, &stSize);    //获得其大小if (ERROR_BUFFER_OVERFLOW == nRel)                      //重新申请所需要的空间{free(pIpAdapterInfo);pIpAdapterInfo = (PIP_ADAPTER_INFO) malloc(stSize);nRel = GetAdaptersInfo(pIpAdapterInfo, &stSize); }/********************************************通过mprapi库获取连接名称*并通过index将网卡信息和连接名称相关联********************************************/HANDLE   hMprConfig;                    //连接信息的句柄DWORD   dwRet=0;                        //返回值PIP_INTERFACE_INFO   plfTable = NULL;   //接口信息表DWORD   dwBufferSize=0;                 //接口信息表空间大小dwRet = MprConfigServerConnect(NULL, &hMprConfig);  //获得句柄dwRet = GetInterfaceInfo(NULL, &dwBufferSize);      //获得接口信息表大小if(dwRet == ERROR_INSUFFICIENT_BUFFER)              //获得接口信息{ plfTable = (PIP_INTERFACE_INFO)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwBufferSize); GetInterfaceInfo(plfTable, &dwBufferSize); } TCHAR   szFriendName[256];                   //接口名称DWORD   tchSize = sizeof(TCHAR) * 256; ZeroMemory(&szFriendName, tchSize);  for (UINT i = 0; i < plfTable-> NumAdapters; i++) { IP_ADAPTER_INDEX_MAP   AdaptMap;         //接口信息AdaptMap = plfTable->Adapter[i]; dwRet = MprConfigGetFriendlyName(hMprConfig, AdaptMap.Name, (PWCHAR)szFriendName, tchSize);      //获得连接名称unicode //遍历网卡信息链表,通过index匹配,找到对应关系for(PIP_ADAPTER_INFO pIpAdapterInfoCopy = pIpAdapterInfo; pIpAdapterInfoCopy != NULL; pIpAdapterInfoCopy = pIpAdapterInfoCopy->Next){if(pIpAdapterInfoCopy->Index == AdaptMap.Index){mapAdapterNames[Ascii2Unicode(pIpAdapterInfoCopy->AdapterName)] = szFriendName;break;}}                                      } HeapFree(GetProcessHeap(), HEAP_ZERO_MEMORY, plfTable);//删除网卡信息if(pIpAdapterInfo)free(pIpAdapterInfo);}void __cdecl _tmain(void){setlocale(LC_ALL, "chs");//首先获取网卡适配器的名字与本地连接名字的对应关系GetAdapterNamesMap();//再获取真实的网络连接的名字HKEY hKey;if( RegOpenKeyEx( HKEY_LOCAL_MACHINE,TEXT("SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\NetworkCards"),0,KEY_READ,&hKey) == ERROR_SUCCESS){QuerySubKeyValue(hKey);}RegCloseKey(hKey);system("pause");}


0 0
原创粉丝点击