我们的宿舍楼老是ip冲突,每次都手动设置,非常麻烦,于是动手做了一个自动设置ip的小工具。
原理很简单,就是检测网内可用ip ,然后修改注册表,重启网卡。用到IP HELPER,VC。NET
附上源代码,与大家交流一下。
// ipooo.h
/*-------------------------------------------------------------------------
//1. 获取网卡名称
//2. 根据网卡名称获取当前ip信息
//3. 修改注册表
//4. 重启网卡
--------------------------------------------------------------------------*/
//-------------------------------------------------------------------------
// include
//-------------------------------------------------------------------------
#include <windows.h>
#include <stdio.h>
#include <tchar.h>
#include <iphlpapi.h>
#include <winsock.h>
#include "resource.h"
#pragma comment(lib,"wsock32.lib")
#pragma comment(lib,"iphlpapi.lib")
const int L=16;
typedef int (CALLBACK* DHCPNOTIFYPROC)(LPWSTR, LPWSTR, BOOL, DWORD, DWORD, DWORD, int);
//-------------------------------------------------------------------------
HICON icon;
PIP_ADAPTER_INFO pInfo=NULL;
MIB_IPADDRTABLE *pIPAddrTable;
ULONG ulSize=0;
char* netcardname; // 网卡名称
char ncdes[256]; // 网卡描述
int index; // 网卡序号
char gateway[L];
char ipaddress[L];
char netmask[L];
char dns[10*L];
DWORD dwSize = 0;
DWORD dwRetVal;
in_addr ipaddr;
ULONG NTEContext = 0;
ULONG NTEInstance = 0;
// ip是否为自动分配
BOOL isDhcp = FALSE;
//--------------------------------------------------------------------------
int GetNetcardName();
int GetNetConfig();
// 如果dhcp为非启用状态
int GetIpTable();
int ModifyReg();
int ResetNet();
BOOL NotifyIPChange(LPCTSTR lpszAdapterName, int nIndex, LPCTSTR pIPAddress, LPCTSTR pNetMask);
BOOL isOnNet(char* ip);
int SetIpAuto();
// 如果dhcp为启用状态
// 获取网络设置
int GetDhcpConfig();
//--------------------------------------------------------------------------
int GetIpTable()
{
pIPAddrTable = (MIB_IPADDRTABLE*)malloc(sizeof(MIB_IPADDRTABLE));
if(GetIpAddrTable(pIPAddrTable, &dwSize, 0) == ERROR_INSUFFICIENT_BUFFER)
{
free(pIPAddrTable);
pIPAddrTable = (MIB_IPADDRTABLE*) malloc(dwSize);
}
if((dwRetVal = GetIpAddrTable(pIPAddrTable, &dwSize, 0)) != NO_ERROR)
{
MessageBox(NULL, "获取ip表失败!/n","错误",MB_OK);
return(-1);
}
/*// 获取掩码
memset(&ipaddr, 0, sizeof(in_addr));
ipaddr.s_addr = (unsigned long)pIPAddrTable->table[0].dwMask;
strcpy(imask, inet_ntoa((struct in_addr)ipaddr));
int i;
for(i=0; i < pIPAddrTable->dwNumEntries; i++)
{
memset(&ipaddr, 0, sizeof(in_addr));
ipaddr.s_addr = (unsigned long)pIPAddrTable->table[i].dwAddr;
memset(tmp,0,TMPNUM);
sprintf(tmp,"/tAddress: %s/n", inet_ntoa((struct in_addr)ipaddr));
strcat(iplist, tmp);
memset(&ipaddr, 0, sizeof(in_addr));
ipaddr.s_addr = (unsigned long)pIPAddrTable->table[i].dwMask;
memset(tmp,0,TMPNUM);
sprintf(tmp,"/tMask: %s/n", inet_ntoa((struct in_addr)ipaddr));
strcat(iplist, tmp);
memset(tmp,0,TMPNUM);
sprintf(tmp,"/tIndex: %ld/n", pIPAddrTable->table[i].dwIndex);
strcat(iplist, tmp);
memset(&ipaddr, 0, sizeof(in_addr));
ipaddr.s_addr = (unsigned long)pIPAddrTable->table[i].dwBCastAddr;
memset(tmp,0,TMPNUM);
sprintf(tmp,"/tBCast: %s/n", inet_ntoa((struct in_addr)ipaddr));
strcat(iplist, tmp);
memset(tmp,0,TMPNUM);
sprintf(tmp,"/tReasm: %ld/n", pIPAddrTable->table[i].dwReasmSize);
strcat(iplist, tmp);
}*/
return(0);
}
int GetNetcardName()
{
GetAdaptersInfo(pInfo,&ulSize);
pInfo=(PIP_ADAPTER_INFO)malloc(ulSize);
if(GetAdaptersInfo(pInfo,&ulSize)==NO_ERROR)
{
while(pInfo)
{
if(pInfo->Type == MIB_IF_TYPE_ETHERNET)
{
netcardname = pInfo->AdapterName;
//index = pInfo->Index;
if(pInfo->DhcpEnabled)
{
isDhcp = TRUE;
}
memcpy(ncdes, pInfo->Description,256);
break;
}
else
{
MessageBox(NULL,"不能识别网络设备!","错误",MB_OK);
}
pInfo = pInfo->Next;
}
return(0);
}
MessageBox(NULL, "获取网卡信息失败!", "错误",MB_OK);
return(-1);
}
int GetNetConfig()
{
PBYTE data;
DWORD buffer_length;
DWORD type = REG_MULTI_SZ;
HKEY hRoot = HKEY_LOCAL_MACHINE;
HKEY hKey;
char szSubKey[256];
DWORD des = REG_OPENED_EXISTING_KEY;
sprintf(szSubKey, "SYSTEM//CurrentControlSet//Services//Tcpip//Parameters//Interfaces//%s",netcardname);
// 查找键值
LONG ret = RegCreateKeyEx(hRoot, szSubKey, 0, NULL,
REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hKey, &des);
if(ret != ERROR_SUCCESS)
{
MessageBox(NULL, "读取注册表失败!", "错误",MB_OK);
return(-1);
}
// 获取ip地址
RegQueryValueEx(hKey, "IPAddress", 0, &type, NULL, &buffer_length);
data = (PBYTE)malloc(buffer_length);
ret = RegQueryValueEx(hKey, "IPAddress", 0, &type, data, &buffer_length);
if(ret != ERROR_SUCCESS)
{
MessageBox(NULL, "读取注册表失败!", "错误",MB_OK);
return(-1);
}
memset(ipaddress, 0, L);
sprintf(ipaddress,"%s",(char*)data);
// 获取网关
RegQueryValueEx(hKey, "DefaultGateway", 0, &type, NULL, &buffer_length);
data = (PBYTE)malloc(buffer_length);
ret = RegQueryValueEx(hKey, "DefaultGateway", 0, &type, data, &buffer_length);
if(ret != ERROR_SUCCESS)
{
MessageBox(NULL, "读取注册表失败!", "错误",MB_OK);
return(-1);
}
memset(gateway, 0, L);
sprintf(gateway,"%s",(char*)data);
// 获取掩码
RegQueryValueEx(hKey, "SubnetMask", 0, &type, NULL, &buffer_length);
data = (PBYTE)malloc(buffer_length);
ret = RegQueryValueEx(hKey, "SubnetMask", 0, &type, data, &buffer_length);
if(ret != ERROR_SUCCESS)
{
MessageBox(NULL, "读取注册表失败!", "错误",MB_OK);
return(-1);
}
memset(netmask, 0, L);
sprintf(netmask,"%s",(char*)data);
// 关闭注册表句柄
RegCloseKey(hKey);
return(0);
}
int ModifyReg()
{
DWORD type = REG_MULTI_SZ;
HKEY hRoot = HKEY_LOCAL_MACHINE;
HKEY hKey;
char szSubKey[256];
DWORD des = REG_OPENED_EXISTING_KEY;
char buf[256];
sprintf(szSubKey, "SYSTEM//CurrentControlSet//Services//Tcpip//Parameters//Interfaces//%s",netcardname);
// 查找键值
LONG ret = RegCreateKeyEx(hRoot, szSubKey, 0, NULL,
REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hKey, &des);
if(ret != ERROR_SUCCESS)
{
MessageBox(NULL, "读取注册表失败!", "错误",MB_OK);
return(-1);
}
char mIpaddress[100];
char mGateway[100];
char mNetmask[100];
strncpy(mIpaddress, ipaddress, 98);
strncpy(mGateway, gateway, 98);
strncpy(mNetmask, netmask, 98);
int nIp = strlen(mIpaddress);
*(mIpaddress + nIp +1) = 0x00;
nIp += 2;
int nGateway = strlen(mGateway);
*(mGateway + nGateway +1) = 0x00;
nGateway += 2;
int nMask = strlen(mNetmask);
*(mNetmask + nMask +1) = 0x00;
nMask += 2;
// 设置ip地址
ret = RegSetValueEx(hKey, "IPAddress", 0, type, (PBYTE)mIpaddress, nIp);
if(ret != ERROR_SUCCESS)
{
MessageBox(NULL, "设置ip地址失败!", "错误",MB_OK);
return(-1);
}
// 设置网关
ret = RegSetValueEx(hKey, "DefaultGateway", 0, type, (PBYTE)mGateway, nGateway);
if(ret != ERROR_SUCCESS)
{
MessageBox(NULL, "设置网关失败!!", "错误",MB_OK);
return(-1);
}
// 设置掩码
ret = RegSetValueEx(hKey, "SubnetMask", 0, type, (PBYTE)mNetmask, nMask);
if(ret != ERROR_SUCCESS)
{
MessageBox(NULL, "设置掩码失败!", "错误",MB_OK);
return(-1);
}
if(isDhcp)
{
// 如果先前起用了dhcp 现在要禁用 必须设置dns
BYTE isd[4];
for(int uu=0; uu<4; uu++)
{
isd[uu] = 0;
}
ret = RegSetValueEx(hKey, "EnableDHCP", 0, REG_DWORD, (PBYTE)isd, sizeof(DWORD));
if(ret != ERROR_SUCCESS)
{
MessageBox(NULL, "禁止dhcp失败!", "错误",MB_OK);
return(-1);
}
// 如果先前起用了dhcp 现在要禁用 必须设置dns
ret = RegSetValueEx(hKey, "NameServer", 0, REG_SZ, (unsigned char*)dns, strlen(dns));
if(ret != ERROR_SUCCESS)
{
MessageBox(NULL, "设置dns失败!", "错误",MB_OK);
return(-1);
}
}
// 关闭注册表句柄
RegCloseKey(hKey);
return(0);
}
int ResetNet()
{
if(NotifyIPChange(netcardname, index, ipaddress, netmask) == FALSE)
{
return(-1);
}
return(0);
}
//-----------------------------------------------------------------
// 通知IP地址的改变
//-----------------------------------------------------------------
BOOL NotifyIPChange(LPCTSTR lpszAdapterName, int nIndex, LPCTSTR pIPAddress, LPCTSTR pNetMask)
{
HMODULE hDhcpDll;
DHCPNOTIFYPROC pDhcpNotifyProc;
WCHAR wcAdapterName[256];
MultiByteToWideChar(CP_ACP, 0, lpszAdapterName, -1, wcAdapterName,256);
if((hDhcpDll = LoadLibrary("dhcpcsvc")) == NULL)
{
MessageBox(NULL, "连接到dhcpcsvc失败!", "ip设置", MB_OK);
return FALSE;
}
if((pDhcpNotifyProc = (DHCPNOTIFYPROC)GetProcAddress(hDhcpDll, "DhcpNotifyConfigChange")) != NULL)
{
if(isDhcp)
{
isDhcp = FALSE;
// 禁止dhcp
if((pDhcpNotifyProc)(NULL, wcAdapterName, TRUE, 0, inet_addr(pIPAddress), inet_addr(pNetMask), 2) == ERROR_SUCCESS)
{
FreeLibrary(hDhcpDll);
return TRUE;
}
}
else
{
if((pDhcpNotifyProc)(NULL, wcAdapterName, TRUE, 0, inet_addr(pIPAddress), inet_addr(pNetMask), 0) == ERROR_SUCCESS)
{
FreeLibrary(hDhcpDll);
return TRUE;
}
}
}
FreeLibrary(hDhcpDll);
return FALSE;
}
//----------------------------------
// 自动设置ip地址
//----------------------------------
int SetIpAuto()
{
int i,n=0,dot=0;
char* baseip;
char* tip;
for(i=0; i<strlen(ipaddress); i++)
{
n++;
if(ipaddress[i] == '.')
{
dot++;
}
if(dot == 3)
{
break;
}
}
baseip = (char*)malloc(n+1);
memset(baseip, 0, n+1);
memcpy(baseip, ipaddress, n);
tip = (char*)malloc(L);
for(i=2; i<254; i++)
{
sprintf(tip, "%s%d", baseip, i);
if(isOnNet(tip))
{
// 设置为当前ip
memset(ipaddress, 0, L);
memcpy(ipaddress, tip, L);
return(0);
}
}
return(-1);
}
//----------------------------------
// 判断某一ip地址是否有人使用
//----------------------------------
BOOL isOnNet(char* tip)
{
BOOL isfond = FALSE;
BOOL isonhost = FALSE;
unsigned long newIP;
unsigned long newMASK;
newIP = inet_addr(tip);
newMASK = inet_addr(netmask);
dwRetVal = AddIPAddress(newIP, newMASK, pIPAddrTable->table[0].dwIndex, &NTEContext, &NTEInstance);
if(dwRetVal == NO_ERROR)
{
// 重新获取列表 判断新添加的ip是否真正成功
memset(pIPAddrTable, 0, sizeof(MIB_IPADDRTABLE));
if((dwRetVal = GetIpAddrTable(pIPAddrTable, &dwSize, 0)) != NO_ERROR)
{
printf("Call to GetIpAddrTable failed./n");
}
ipaddr.s_addr = (unsigned long)pIPAddrTable->table[1].dwAddr;
if(strcmp(inet_ntoa((struct in_addr)ipaddr), "0.0.0.0") != 0)
{
// 找到可用ip
// 退出循环进行设置
isfond = TRUE;
//return TRUE;
}
}
else if(dwRetVal == ERROR_DUP_DOMAINNAME)
{
// 如果当前ip在本机已经存在
isonhost = TRUE;
//return TRUE;
}
// 删除ip项
if ((dwRetVal = DeleteIPAddress(NTEContext)) != NO_ERROR) {
printf("Call to DeleteIPAddress failed./n");
}
else
{
printf("Delete IP address sucess./n");
}
// 重新获取ip表
memset(pIPAddrTable, 0, sizeof(MIB_IPADDRTABLE));
if((dwRetVal = GetIpAddrTable(pIPAddrTable, &dwSize, 0)) != NO_ERROR)
{
printf("Call to GetIpAddrTable failed./n");
}
return (isonhost || isfond);
}
// 如果dhcp为启用状态
// 获取网络设置
int GetDhcpConfig()
{
PBYTE data;
DWORD buffer_length;
DWORD type = REG_MULTI_SZ;
HKEY hRoot = HKEY_LOCAL_MACHINE;
HKEY hKey;
char szSubKey[256];
DWORD des = REG_OPENED_EXISTING_KEY;
sprintf(szSubKey, "SYSTEM//CurrentControlSet//Services//Tcpip//Parameters//Interfaces//%s",netcardname);
// 查找键值
LONG ret = RegCreateKeyEx(hRoot, szSubKey, 0, NULL,
REG_OPTION_NON_VOLATILE, KEY_ALL_ACCESS, NULL, &hKey, &des);
if(ret != ERROR_SUCCESS)
{
MessageBox(NULL, "读取注册表失败!", "错误",MB_OK);
return(-1);
}
// 获取ip地址
RegQueryValueEx(hKey, "DhcpIPAddress", 0, &type, NULL, &buffer_length);
data = (PBYTE)malloc(buffer_length);
ret = RegQueryValueEx(hKey, "DhcpIPAddress", 0, &type, data, &buffer_length);
if(ret != ERROR_SUCCESS)
{
MessageBox(NULL, "读取注册表失败!", "错误",MB_OK);
return(-1);
}
memset(ipaddress, 0, L);
sprintf(ipaddress,"%s",(char*)data);
// 获取网关
RegQueryValueEx(hKey, "DhcpDefaultGateway", 0, &type, NULL, &buffer_length);
data = (PBYTE)malloc(buffer_length);
ret = RegQueryValueEx(hKey, "DhcpDefaultGateway", 0, &type, data, &buffer_length);
if(ret != ERROR_SUCCESS)
{
MessageBox(NULL, "读取注册表失败!", "错误",MB_OK);
return(-1);
}
memset(gateway, 0, L);
sprintf(gateway,"%s",(char*)data);
// 获取掩码
RegQueryValueEx(hKey, "DhcpSubnetMask", 0, &type, NULL, &buffer_length);
data = (PBYTE)malloc(buffer_length);
ret = RegQueryValueEx(hKey, "DhcpSubnetMask", 0, &type, data, &buffer_length);
if(ret != ERROR_SUCCESS)
{
MessageBox(NULL, "读取注册表失败!", "错误",MB_OK);
return(-1);
}
memset(netmask, 0, L);
sprintf(netmask,"%s",(char*)data);
type = REG_SZ;
// 获取dns 和备用dns 保存起来供以后使用
RegQueryValueEx(hKey, "DhcpNameServer", 0, &type, NULL, &buffer_length);
data = (PBYTE)malloc(buffer_length);
ret = RegQueryValueEx(hKey, "DhcpNameServer", 0, &type, data, &buffer_length);
if(ret != ERROR_SUCCESS)
{
MessageBox(NULL, "读取注册表失败!", "错误",MB_OK);
return(-1);
}
memset(dns, 0, L);
sprintf(dns,"%s",(char*)data);
// 关闭注册表句柄
RegCloseKey(hKey);
return(0);
}
// ipooo.c
#include "ipooo.h"
BOOL _stdcall DlgProc(HWND, UINT, WPARAM, LPARAM);
int _stdcall WinMain(HINSTANCE hinstance, HINSTANCE, LPSTR, int)
{
icon = LoadIcon(hinstance, (LPCTSTR)IDI_ICON1);
if(GetNetcardName() != -1)
{
if(!isDhcp)
{
if(GetNetConfig() == -1)
{
exit(0);
}
}
else
{
if(GetDhcpConfig() == -1)
{
exit(0);
}
}
}
else
{
exit(0);
}
if(GetIpTable() == -1)
{
MessageBox(NULL, "获取ip表失败!", "错误", MB_OK);
exit(0);
}
int nresult = ::DialogBoxParam(
hinstance,
(LPCTSTR)IDD_DIALOG1,
NULL,DlgProc,NULL);
if(nresult == IDOK)
{
}
return(0);
}
BOOL _stdcall DlgProc(HWND hdlg, UINT message, WPARAM wparam, LPARAM lparam)
{
switch(message)
{
case WM_INITDIALOG:
{
SendMessage(hdlg, WM_SETICON, ICON_BIG, (long)icon);
SetWindowText(GetDlgItem(hdlg, IDC_EDIT1), ipaddress);
SetWindowText(GetDlgItem(hdlg, IDC_EDIT2), netmask);
SetWindowText(GetDlgItem(hdlg, IDC_EDIT3), gateway);
SetWindowText(GetDlgItem(hdlg, IDC_EDIT4), ncdes);
}
break;
case WM_COMMAND:
switch(LOWORD(wparam))
{
case IDOK:
{
EndDialog(hdlg, IDOK);
}
break;
case IDC_BUTTON1:
{
GetWindowText(GetDlgItem(hdlg, IDC_EDIT1), ipaddress, L);
GetWindowText(GetDlgItem(hdlg, IDC_EDIT2), netmask, L);
GetWindowText(GetDlgItem(hdlg, IDC_EDIT3), gateway, L);
if(isOnNet(ipaddress))
{
// 修改注册表
if(ModifyReg() != -1)
{
if(ResetNet() == -1)
{
MessageBox(NULL, "设置ip失败!", "ip设置", MB_OK);
}
else
{
MessageBox(NULL, "设置ip成功!", "ip设置", MB_OK);
}
}
}
else
{
MessageBox(NULL, "当前ip正在被人使用!", "失败", MB_OK);
}
}
break;
case IDC_BUTTON2:
{
GetWindowText(GetDlgItem(hdlg, IDC_EDIT1), ipaddress, L);
GetWindowText(GetDlgItem(hdlg, IDC_EDIT2), netmask, L);
GetWindowText(GetDlgItem(hdlg, IDC_EDIT3), gateway, L);
if(SetIpAuto() != -1)
{
// 修改注册表
if(ModifyReg() != -1)
{
if(ResetNet() == -1)
{
MessageBox(NULL, "设置ip失败!", "ip设置", MB_OK);
}
else
{
MessageBox(NULL, "设置ip成功!", "ip设置", MB_OK);
// 更新显示信息
SetWindowText(GetDlgItem(hdlg, IDC_EDIT1), ipaddress);
SetWindowText(GetDlgItem(hdlg, IDC_EDIT2), netmask);
SetWindowText(GetDlgItem(hdlg, IDC_EDIT3), gateway);
}
}
}
else
{
MessageBox(NULL,"此段已被无可设置ip地址!","失败",MB_OK);
}
}
break;
}
break;
}
return(0);
}