⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 adapteripconfigdlg.cpp

📁 不重启Windows直接更改IP地址
💻 CPP
字号:
// AdapterIPConfigDlg.cpp : implementation file
//	

#include "stdafx.h"
#include <string>
#include <vector>
//#include <Iphlpapi.h>
#include <winsock2.h>
#include "AdapterIPConfig.h"
#include "AdapterIPConfigDlg.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

#pragma comment(lib, "ws2_32.lib")
//#pragma comment(lib, "Iphlpapi.lib") 
using namespace std;


typedef int (CALLBACK* DHCPNOTIFYPROC)(LPWSTR, LPWSTR, BOOL, DWORD, DWORD, DWORD, int);

typedef struct tagAdapterInfo
{
	string strName;			// 适配器名称
	string strDriverDesc;	// 适配器描述
	string strIP;			// IP地址
	string strNetMask;		// 子网掩码
	string strNetGate;		// 网关
}ADAPTER_INFO;

BOOL GetAdapterInfo();
BOOL RegGetIP(ADAPTER_INFO *pAI, LPCTSTR lpszAdapterName, int nIndex = 0);

vector<ADAPTER_INFO*> AdapterInfoVector;


/////////////////////////////////////////////////////////////////////////////
// CAboutDlg dialog used for App About

class CAboutDlg : public CDialog
{
public:
	CAboutDlg();

// Dialog Data
	//{{AFX_DATA(CAboutDlg)
	enum { IDD = IDD_ABOUTBOX };
	//}}AFX_DATA

	// ClassWizard generated virtual function overrides
	//{{AFX_VIRTUAL(CAboutDlg)
	protected:
	virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
	//}}AFX_VIRTUAL

// Implementation
protected:
	//{{AFX_MSG(CAboutDlg)
	//}}AFX_MSG
	DECLARE_MESSAGE_MAP()
};

CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
	//{{AFX_DATA_INIT(CAboutDlg)
	//}}AFX_DATA_INIT
}

void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CAboutDlg)
	//}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
	//{{AFX_MSG_MAP(CAboutDlg)
		// No message handlers
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CAdapterIPConfigDlg dialog

CAdapterIPConfigDlg::CAdapterIPConfigDlg(CWnd* pParent /*=NULL*/)
	: CDialog(CAdapterIPConfigDlg::IDD, pParent)
{
	//{{AFX_DATA_INIT(CAdapterIPConfigDlg)
		// NOTE: the ClassWizard will add member initialization here
	//}}AFX_DATA_INIT
	// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}

void CAdapterIPConfigDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CAdapterIPConfigDlg)
	DDX_Control(pDX, IDC_ADAPTER_COMBO, m_ctlAdapters);
	DDX_Control(pDX, IDC_NETMASK, m_ctlNetMask);
	DDX_Control(pDX, IDC_NETGATE, m_ctlNetGate);
	DDX_Control(pDX, IDC_IPADDRESS, m_ctlIPAddress);
	//}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CAdapterIPConfigDlg, CDialog)
	//{{AFX_MSG_MAP(CAdapterIPConfigDlg)
	ON_WM_SYSCOMMAND()
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
	ON_CBN_SELCHANGE(IDC_ADAPTER_COMBO, OnSelchangeAdapter)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CAdapterIPConfigDlg message handlers

BOOL CAdapterIPConfigDlg::OnInitDialog()
{
	CDialog::OnInitDialog();

	// Add "About..." menu item to system menu.

	// IDM_ABOUTBOX must be in the system command range.
	ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
	ASSERT(IDM_ABOUTBOX < 0xF000);

	CMenu* pSysMenu = GetSystemMenu(FALSE);
	if (pSysMenu != NULL)
	{
		CString strAboutMenu;
		strAboutMenu.LoadString(IDS_ABOUTBOX);
		if (!strAboutMenu.IsEmpty())
		{
			pSysMenu->AppendMenu(MF_SEPARATOR);
			pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
		}
	}

	// Set the icon for this dialog.  The framework does this automatically
	//  when the application's main window is not a dialog
	SetIcon(m_hIcon, TRUE);			// Set big icon
	SetIcon(m_hIcon, FALSE);		// Set small icon
	
	GetAdapterInfo();	// 得到适配器信息

	// 添加到ComboBox
	for( size_t i = 0; i < AdapterInfoVector.size(); i++ )
		m_ctlAdapters.AddString(AdapterInfoVector[i]->strDriverDesc.c_str());

	m_ctlAdapters.SetCurSel(0);
	OnSelchangeAdapter();

	return TRUE;  // return TRUE  unless you set the focus to a control
}

void CAdapterIPConfigDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
	if ((nID & 0xFFF0) == IDM_ABOUTBOX)
	{
		CAboutDlg dlgAbout;
		dlgAbout.DoModal();
	}
	else
	{
		CDialog::OnSysCommand(nID, lParam);
	}
}

// If you add a minimize button to your dialog, you will need the code below
//  to draw the icon.  For MFC applications using the document/view model,
//  this is automatically done for you by the framework.

void CAdapterIPConfigDlg::OnPaint() 
{
	if (IsIconic())
	{
		CPaintDC dc(this); // device context for painting

		SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);

		// Center icon in client rectangle
		int cxIcon = GetSystemMetrics(SM_CXICON);
		int cyIcon = GetSystemMetrics(SM_CYICON);
		CRect rect;
		GetClientRect(&rect);
		int x = (rect.Width() - cxIcon + 1) / 2;
		int y = (rect.Height() - cyIcon + 1) / 2;

		// Draw the icon
		dc.DrawIcon(x, y, m_hIcon);
	}
	else
	{
		CDialog::OnPaint();
	}
}

// The system calls this to obtain the cursor to display while the user drags
//  the minimized window.
HCURSOR CAdapterIPConfigDlg::OnQueryDragIcon()
{
	return (HCURSOR) m_hIcon;
}


//-----------------------------------------------------------------
//	取得所有网卡信息
//-----------------------------------------------------------------
BOOL GetAdapterInfo()
{
	// 这里的代码适合WINDOWS2000,对于NT需要读取HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\NetworkCards
	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)
						{
							ADAPTER_INFO *pAI = new ADAPTER_INFO;
							pAI->strDriverDesc = (LPCTSTR)szData;
							dwBufSize = 256;
							if(RegQueryValueEx(hSubKey, "NetCfgInstanceID", 0, &dwDataType, szData, &dwBufSize) == ERROR_SUCCESS)
							{
								pAI->strName = (LPCTSTR)szData;
								RegGetIP(pAI, (LPCTSTR)szData);
							}
							AdapterInfoVector.push_back(pAI);	// 加入到容器中
						}
					}
				}
				RegCloseKey(hNdiIntKey);
			}
			RegCloseKey(hSubKey);
		}

		dwBufSize = 256;
	}	/* end of while */
		
	RegCloseKey(hKey);

	/*
	//	可以使用GetAdaptersInfo来取得网卡信息,但其显示的名称不是很具体

	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)
			{
				ADAPTER_INFO *pAI = new ADAPTER_INFO;
				pAI->strDriverDesc = pAdapterInfo->Description;
				pAI->strName = pAdapterInfo->AdapterName;
				RegGetIP(pAI, (LPCTSTR)pAdapterInfo->AdapterName);	// 因为IP_ADAPTER_INFO中未包含掩码信息,所以干脆直接读注册表
				AdapterInfoVector.push_back(pAI);
			}
			pAdapterInfo = pAdapterInfo->Next;
		} while(pAdapterInfo);
	}
	delete pAdapterInfoBkp;	
	*/
	return TRUE;
}

//-----------------------------------------------------------------
//	得到注册表中的IP信息
//	nIndex暂时未处理
//-----------------------------------------------------------------

BOOL RegGetIP(ADAPTER_INFO *pAI, LPCTSTR lpszAdapterName, int nIndex/* =0 */)
{
	ASSERT(pAI);

	HKEY hKey;
	string strKeyName = "SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters\\Interfaces\\";
	strKeyName += lpszAdapterName;
	if(RegOpenKeyEx(HKEY_LOCAL_MACHINE,
				strKeyName.c_str(),
				0,
				KEY_READ,
				&hKey) != ERROR_SUCCESS)
		return FALSE;

	unsigned char szData[256];
	DWORD dwDataType, dwBufSize;

	dwBufSize = 256;
	if(RegQueryValueEx(hKey, "IPAddress", 0, &dwDataType, szData, &dwBufSize) == ERROR_SUCCESS)
		pAI->strIP = (LPCTSTR)szData;

	dwBufSize = 256;
	if(RegQueryValueEx(hKey, "SubnetMask", 0, &dwDataType, szData, &dwBufSize) == ERROR_SUCCESS)
		pAI->strNetMask = (LPCTSTR)szData;

	dwBufSize = 256;
	if(RegQueryValueEx(hKey, "DefaultGateway", 0, &dwDataType, szData, &dwBufSize) == ERROR_SUCCESS)
		pAI->strNetGate = (LPCTSTR)szData;
	
	RegCloseKey(hKey);
	return TRUE;
}

//-----------------------------------------------------------------
//	设置注册表中的IP信息
//-----------------------------------------------------------------

BOOL RegSetIP(LPCTSTR lpszAdapterName, int nIndex, 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;
	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;
}

//-----------------------------------------------------------------
//	通知IP地址的改变
//-----------------------------------------------------------------

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;
}

//-----------------------------------------------------------------
//	设置IP地址
//	如果只绑定一个IP,nIndex = 0,暂时未处理一个网卡绑定多个地址
//-----------------------------------------------------------------

BOOL SetIP(LPCTSTR lpszAdapterName, int nIndex, LPCTSTR pIPAddress, LPCTSTR pNetMask, LPCTSTR pNetGate)
{
	if(!RegSetIP(lpszAdapterName, nIndex, pIPAddress, pNetMask, pNetGate))
		return FALSE;
	
	if(!NotifyIPChange(lpszAdapterName, nIndex, pIPAddress, pNetMask))
		return FALSE;

	return TRUE;
}

void CAdapterIPConfigDlg::OnOK() 
{
	char szIP[16];
	char szMask[16];
	char szGate[16];
	unsigned char *pIP, *pMask, *pGate;
	DWORD dwIP, dwMask, dwGate;
	int nSel = m_ctlAdapters.GetCurSel();

	m_ctlIPAddress.GetAddress(dwIP);
	m_ctlNetMask.GetAddress(dwMask);
	m_ctlNetGate.GetAddress(dwGate);

	pIP = (unsigned char*)&dwIP;
	pMask = (unsigned char*)&dwMask;
	pGate = (unsigned char*)&dwGate;

	sprintf(szIP, "%u.%u.%u.%u", *(pIP+3), *(pIP+2), *(pIP+1), *pIP);
	sprintf(szMask, "%u.%u.%u.%u", *(pMask+3), *(pMask+2), *(pMask+1), *pMask);
	sprintf(szGate, "%u.%u.%u.%u", *(pGate+3), *(pGate+2), *(pGate+1), *pGate);

	if(SetIP(AdapterInfoVector[nSel]->strName.c_str(), 0, szIP, szMask, szGate) == TRUE)
		::MessageBox(this->m_hWnd, "设置IP地址成功!", "操作结果", MB_OK | MB_ICONINFORMATION);
	else
		::MessageBox(this->m_hWnd, "设置IP地址失败!", "操作结果", MB_OK | MB_ICONERROR);
}


BOOL CAdapterIPConfigDlg::DestroyWindow() 
{
	// 做最后的清理
	for( size_t i = 0; i < AdapterInfoVector.size(); i++ )
		delete AdapterInfoVector[i];
	AdapterInfoVector.clear();

	return CDialog::DestroyWindow();
}

//---------------------------------------------------------
//	适配器组合框选择改变时调用
//---------------------------------------------------------

void CAdapterIPConfigDlg::OnSelchangeAdapter() 
{
	int nSel = m_ctlAdapters.GetCurSel();
	DWORD dwIP, dwMask, dwGate;

	dwIP = inet_addr(AdapterInfoVector[nSel]->strIP.c_str());
	dwMask = inet_addr(AdapterInfoVector[nSel]->strNetMask.c_str());
	dwGate = inet_addr(AdapterInfoVector[nSel]->strNetGate.c_str());

	unsigned char *pIP = (unsigned char*)&dwIP;
	unsigned char *pMask = (unsigned char*)&dwMask;
	unsigned char *pGate = (unsigned char*)&dwGate;

	m_ctlIPAddress.SetAddress(*pIP, *(pIP+1), *(pIP+2), *(pIP+3));
	m_ctlNetMask.SetAddress(*pMask, *(pMask+1), *(pMask+2), *(pMask+3));
	m_ctlNetGate.SetAddress(*pGate, *(pGate+1), *(pGate+2), *(pGate+3));
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -