VC modify the local IP address

http://www.vcchar.com/thread-1527-1-1.html

Set the IP address only need to change the registry setting on the appropriate adapter, but require a restart to take effect, but AddIPAddress function can only add IP instead of changing the current IP, we do not need to operate on Windows NT / 2000 interface restart can take effect, and that the system in the end what has been done extra work just to make direct IP settings to take effect it? Through tracking explorer.exe found in API calls in a call dhcpcsvc.dll undocumented API in netcfgx.dll in: DhcpNotifyConfigChange, now not restart WINDOWS detailed method of directly changing the IP address are described below

First, access to the adapter name

Herein refers to the name of the adapter is different from the adapter described, such as a card I adapter description: Realtek RTL8139 (A) PCI Fast Ethernet Adapter, the adapter name: {66156DC3-44A4-434C-B8A9-0E5DB4B3EEAD}. There are several ways to get the adapter name:

Second, the IP helper API calls made adapter name


  • ULONG ulAdapterInfoSize = sizeof(IP_ADAPTER_INFO);  
  • IP_ADAPTER_INFO *pAdapterInfoBkp, *pAdapterInfo = (IP_ADAPTER_INFO*)new char[ulAdapterInfoSize];  
  • if( GetAdaptersInfo(pAdapterInfo, &ulAdapterInfoSize) == ERROR_BUFFER_OVERFLOW ) // 缓冲区不够大  
  • {  
  •     delete pAdapterInfo;  
  •     pAdapterInfo = (IP_ADAPTER_INFO*)new char[ulAdapterInfoSize];  
  •     pAdapterInfoBkp = pAdapterInfo;  
  • }  
  • if( GetAdaptersInfo(pAdapterInfo, &ulAdapterInfoSize) == ERROR_SUCCESS )  
  • {  
  •     do {// traverse all adapters  
  •         if (pAdapterInfo-> Type == MIB_IF_TYPE_ETHERNET) // determine whether the Ethernet interface  
  •         {  
  •             // pAdapterInfo-> Description adapter is described  
  •             // pAdapterInfo-> AdapterName is the adapter name  
  •         }  
  •         pAdapterInfo = pAdapterInfo->Next;  
  •     }while(pAdapterInfo);  
  • }  
  • delete pAdapterInfoBkp;  



Third, read the registry to obtain the name of the adapter

In Windows2000 by traversing HKEY_LOCAL_MACHINE \ System \ CurrentControlSet \ Control \ Class \ {4d36e972-e325-11ce-bfc1-08002be10318} \ 000n \ (n is a number from 0 numbered) all interfaces in Windows NT may be read HKEY_LOCAL_MACHINE \ SOFTWARE \ Microsoft \ Windows NT \ CurrentVersion NetworkCards the information \, by GUID find similar HKEY_LOCAL_MACHINE \ SYSTEM \ ControlSet001 \ Services \ Tcpip \ Parameters \ Interfaces \ {8202c21f-87e8-4ed0-baeb-6441a7789ba9} such a primary key, the following with Windows2000 as an example:




  • HKEY hKey, hSubKey, hNdiIntKey;  
  •   
  • if(RegOpenKeyEx(HKEY_LOCAL_MACHINE,  
  •             "System//CurrentControlSet//Control//Class//{4d36e972-e325-11ce-bfc1-08002be10318}",  
  •             0,  
  •             KEY_READ,  
  •             &hKey) != ERROR_SUCCESS)  
  •     return FALSE;  
  •   
  • DWORD dwIndex = 0;  
  • DWORD dwBufSize = 256;  
  • DWORD dwDataType;  
  • char szSubKey[256];  
  • unsigned char szData[256];  
  •   
  • while(RegEnumKeyEx(hKey, dwIndex++, szSubKey, &dwBufSize, NULL, NULL, NULL, NULL) == ERROR_SUCCESS)  
  • {  
  •     if(RegOpenKeyEx(hKey, szSubKey, 0, KEY_READ, &hSubKey) == ERROR_SUCCESS)  
  •     {         
  •         if(RegOpenKeyEx(hSubKey, "Ndi//Interfaces", 0, KEY_READ, &hNdiIntKey) == ERROR_SUCCESS)  
  •         {  
  •             dwBufSize = 256;  
  •             if(RegQueryValueEx(hNdiIntKey, "LowerRange", 0, &dwDataType, szData, &dwBufSize) == ERROR_SUCCESS)  
  •             {  
  •                 if(strcmp((char*)szData, "ethernet") == 0)      //  判断是不是以太网卡  
  •                 {  
  •                     dwBufSize = 256;  
  •                     if(RegQueryValueEx(hSubKey, "DriverDesc", 0, &dwDataType, szData, &dwBufSize) == ERROR_SUCCESS)  
  •                     {  
  •                         // szData 中便是适配器详细描述  
  •                         dwBufSize = 256;  
  •                         if(RegQueryValueEx(hSubKey, "NetCfgInstanceID", 0, &dwDataType, szData, &dwBufSize) == ERROR_SUCCESS)  
  •                         {  
  •                             // szData 中便是适配器名称  
  •                         }  
  •                     }  
  •                 }  
  •             }  
  •             RegCloseKey(hNdiIntKey);  
  •         }  
  •         RegCloseKey(hSubKey);  
  •     }  
  •   
  •     dwBufSize = 256;  
  • }   /* end of while */  
  •          
  • RegCloseKey(hKey);  



四、将IP信息写入注册表

代码如下



  • BOOL RegSetIP(LPCTSTR lpszAdapterName, LPCTSTR pIPAddress, LPCTSTR pNetMask, LPCTSTR pNetGate)  
  • {  
  •     HKEY hKey;  
  •     string strKeyName = "SYSTEM//CurrentControlSet//Services//Tcpip//Parameters//Interfaces//";  
  •     strKeyName += lpszAdapterName;  
  •     if(RegOpenKeyEx(HKEY_LOCAL_MACHINE,  
  •                 strKeyName.c_str(),  
  •                 0,  
  •                 KEY_WRITE,  
  •                 &hKey) != ERROR_SUCCESS)  
  •         return FALSE;  
  •       
  •     char mszIPAddress[100];  
  •     char mszNetMask[100];  
  •     char mszNetGate[100];  
  •   
  •     strncpy(mszIPAddress, pIPAddress, 98);  
  •     strncpy(mszNetMask, pNetMask, 98);  
  •     strncpy(mszNetGate, pNetGate, 98);  
  •   
  •     int nIP, nMask, nGate;  
  •   
  •     nIP = strlen(mszIPAddress);  
  •     nMask = strlen(mszNetMask);  
  •     nGate = strlen(mszNetGate);  
  •   
  •     *(mszIPAddress + nIP + 1) = 0x00;   // REG_MULTI_SZ数据需要在后面再加个0  
  •     nIP += 2;  
  •   
  •     *(mszNetMask + nMask + 1) = 0x00;  
  •     nMask += 2;  
  •   
  •     *(mszNetGate + nGate + 1) = 0x00;  
  •     nGate += 2;  
  •       
  •     RegSetValueEx(hKey, "IPAddress", 0, REG_MULTI_SZ, (unsigned char*)mszIPAddress, nIP);  
  •     RegSetValueEx(hKey, "SubnetMask", 0, REG_MULTI_SZ, (unsigned char*)mszNetMask, nMask);  
  •     RegSetValueEx(hKey, "DefaultGateway", 0, REG_MULTI_SZ, (unsigned char*)mszNetGate, nGate);  
  •   
  •     RegCloseKey(hKey);  
  •   
  •     return TRUE;  
  • }  



五、调用DhcpNotifyConfigChange通知配置的改变

未公开函数DhcpNotifyConfigChange位于 dhcpcsvc.dll中,原型如下:




  • BOOL DhcpNotifyConfigChange(  
  •     LPWSTR lpwszServerName, // 本地机器为NULL  
  •     LPWSTR lpwszAdapterName, // 适配器名称  
  •     BOOL bNewIpAddress, // TRUE表示更改IP  
  •     DWORD dwIpIndex, // 指明第几个IP地址,如果只有该接口只有一个IP地址则为0  
  •     DWORD dwIpAddress, // IP地址  
  •     DWORD dwSubNetMask, // 子网掩码  
  •     int nDhcpAction ); // 对DHCP的操作 0:不修改, 1:启用 DHCP,2:禁用 DHCP  



具体调用代码如下:



    • BOOL NotifyIPChange(LPCTSTR lpszAdapterName, int nIndex, LPCTSTR pIPAddress, LPCTSTR pNetMask)  
    • {  
    •     BOOL            bResult = FALSE;  
    •     HINSTANCE       hDhcpDll;  
    •     DHCPNOTIFYPROC  pDhcpNotifyProc;  
    •     WCHAR wcAdapterName[256];  
    •       
    •     MultiByteToWideChar(CP_ACP, 0, lpszAdapterName, -1, wcAdapterName,256);  
    •   
    •     if((hDhcpDll = LoadLibrary("dhcpcsvc")) == NULL)  
    •         return FALSE;  
    •   
    •     if((pDhcpNotifyProc = (DHCPNOTIFYPROC)GetProcAddress(hDhcpDll, "DhcpNotifyConfigChange")) != NULL)  
    •         if((pDhcpNotifyProc)(NULL, wcAdapterName, TRUE, nIndex, inet_addr(pIPAddress), inet_addr(pNetMask), 0) == ERROR_SUCCESS)  
    •             bResult = TRUE;  
    •   
    •     FreeLibrary(hDhcpDll);  
    •     return bResult;  
    • }  

Guess you like

Origin www.cnblogs.com/liuzhaoyzz/p/11703175.html