不重启Windows直接更改IP地址

来源:互联网 发布:服装ie软件 编辑:程序博客网 时间:2024/04/29 00:54
不重起Windows直接更改IP地址  
  作者:浙江省温岭电信局   王骏  
   
  设置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数据需要在后面再加个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;  
  }   
 
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 脸过敏干燥起皮怎么办 脸上皮肤干燥起皮怎么办 身上皮肤干燥起皮怎么办 皮肤暗黄有色斑怎么办 我皮肤干燥暗黄怎么办 脸上有皮肤暗黄怎么办 皮肤暗黄毛孔大怎么办 脸上很干燥起皮怎么办 脸上的皮肤起皮怎么办 身体的皮肤好干怎么办 滴油雾化器炸油怎么办 已经发炎的痘痘怎么办 被养生馆骗了怎么办 做完微针结痂了怎么办 秋季脸干燥起皮怎么办 身上的皮肤太干怎么办 板材眼镜腿松了怎么办 超声刀后喝酒了怎么办 开眼角疤痕增生了怎么办 开了眼角有增生怎么办 全切双眼皮留疤怎么办 开内眼角留疤了怎么办 开眼角长了颗粒怎么办 开刀后疤痕庝痛怎么办 眼角开得太尖了怎么办 眼角开得太大了怎么办 开眼角后增生了怎么办 下颌骨宽怎么办不整容 脸两边骨头太宽怎么办 接了睫毛眼睛疼怎么办 下颌骨错位脸歪怎么办 假体隆鼻感冒了怎么办 打了玻尿酸怀孕怎么办 鼻子上有出血点怎么办 内眼角开小了怎么办 上眼皮肿怎么办小妙招 嫁接的睫毛乱了怎么办 睫毛掉进眼睛里怎么办 痘痘留下的疤痕怎么办 宫颈癌前病变1级怎么办 纹身后结痂很厚怎么办