CSDN首页 空间 新闻 论坛 Blog 下载 读书 网摘 搜索 .NET Java 视频 接项目 求职 在线学习 买书 程序员 通知
山寨机中的战斗机! 程序优化工程师到底对IT界有没有贡献
CSDN社区
搜索 收藏 打印 关闭
CSDN社区 >  VC/MFC >  网络编程

***************IP地址与网卡地址*********************

楼主ywfscu(乌雕)2005-05-30 13:41:06 在 VC/MFC / 网络编程 提问

怎么用vc编程修改这两个地址 问题点数:100、回复次数:5Top

1 楼bohut(●伯虎● )回复于 2005-05-30 13:49:51 得分 40

设置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;  
  }  
  Top

2 楼ywfscu(乌雕)回复于 2005-05-30 17:45:16 得分 0

这个是实现不重新启动的情况下改IP,那怎么改网卡的物理地址呢?Top

3 楼krh2001(边城浪子)回复于 2005-05-30 17:57:09 得分 20

知道怎么读,不知道怎么改,哎~Top

4 楼nodummy(三甲 之 Linux/Unix里面甭给我分,谁给我分我和谁急)回复于 2005-05-30 18:18:35 得分 20

全都是改注册表就可以解决的……Top

5 楼jzyhummel(篱影)回复于 2005-05-30 21:41:32 得分 20

本板精华里面有我和小猪总结的网卡地址相关的大部分信息,你最好能先看看再说Top

相关问题

  • IP地址与DLINK 530TX网卡硬件地址冲突问题
  • 可否将IP地址与网卡绑定?
  • linux下如何将IP与网卡的MAC地址绑定呢?
  • 怎样设置网卡的IP地址?
  • '网卡分配IP地址的问题
  • 网卡无法获得IP地址!
  • 通过IP地址得到网卡地址
  • 如何获得网卡(多个网卡)各自的型号及对应的IP地址?MAC地址
  • 请教高手:局域网内IP地址与网卡绑定的问题(还我自由!!)。。。
  • 请问一个网卡可以绑定两个IP地址吗?

关键词

  • windows2000
  • ip
  • 适配器
  • padapterinfo
  • uladapterinfosize
  • 地址
  • padapterinfobkp
  • 名称
  • 调用
  • 更改

得分解答快速导航

  • 帖主:ywfscu
  • bohut
  • krh2001
  • nodummy
  • jzyhummel

相关链接

  • Visual C++类图书
  • Visual C++类源码下载

广告也精彩

反馈

请通过下述方式给我们反馈
反馈
提问
网站简介|广告服务|VIP资费标准|银行汇款帐号|网站地图|帮助|联系方式|诚聘英才|English|问题报告
北京创新乐知广告有限公司 版权所有, 京 ICP 证 070598 号
世纪乐知(北京)网络技术有限公司 提供技术支持
Copyright © 2000-2008, CSDN.NET, All Rights Reserved
GongshangLogo