VC知識庫文章 – 不重起Windows直接更改IP地址

來源:互聯網
上載者:User
 導讀:

不重起Windows直接更改IP地址
作者:浙江省溫嶺電信局 王駿

註:本文適用於WINDOWS NT/2000/XP/2003

下載本文樣本工程

原始碼運行如下:

設定IP地址只需要更改註冊表中關於適配器的相應設定,但更改後需要重新啟動系統才會生效,而AddIPAddress函數只能添加IP而不是更改當前的IP,我們在Windows NT/2000介面上操作不需要重新啟動就可以生效,那系統到底做了什麼額外的工作才使IP設定直接生效呢?筆者通過跟蹤explorer.exe中API的調用發現在netcfgx.dll中調用了dhcpcsvc.dll中一個未公開的API:DhcpNotifyConfigChange,現將不重新啟動WINDOWS直接更改IP地址的詳細方法介紹如下:

一、擷取適配器名稱

這裡指的適配器名稱要區別於適配器描述,比如我的一塊網卡,適配器描述是:Realtek RTL8139(A) PCI Fast Ethernet Adapter,適配器名稱為:{66156DC3-44A4-434C-B8A9-0E5DB4B3EEAD}。擷取適配器名稱的方法有多種:

1.1 調用IP helper API取得適配器名稱

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{ // 遍曆所有適配器if(pAdapterInfo->Type == MIB_IF_TYPE_ETHERNET)// 判斷是否為乙太網路介面{// pAdapterInfo->Description 是適配器描述// pAdapterInfo->AdapterName 是適配器名稱}pAdapterInfo = pAdapterInfo->Next;}while(pAdapterInfo);}delete pAdapterInfoBkp;

1.2 讀取註冊表取得適配器名稱

在Windows2000中可以通過遍曆 HKEY_LOCAL_MACHINE/System/CurrentControlSet/Control/Class/{4d36e972-e325-11ce-bfc1-08002be10318}/000n/ (n是從0開始編號的數字)所有介面, 在Windows NT中可以讀取HKEY_LOCAL_MACHINE/SOFTWARE/Microsoft/Windows NT/CurrentVersion/NetworkCards中的資訊,下面以Windows2000為例:

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資料需要在後面再加個0nIP += 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){BOOLbResult = FALSE;HINSTANCEhDhcpDll;DHCPNOTIFYPROCpDhcpNotifyProc;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;}

(全文完)
本文轉自
http://www.vckbase.com/document/viewdoc/?id=851

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.