vc 不重启切换IP地址

来源:互联网 发布:mac option 看不到u盘 编辑:程序博客网 时间:2024/04/28 08:19

// AdapterIPConfigDlg.cpp : implementation file
// 

#include "stdafx.h"
#include <string>
#include <vector>
//#include <Iphlpapi.h>
#include <winsock2.h>
#include "AdapterIPConfig.h"
#include "AdapterIPConfigDlg.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
 ON_BN_CLICKED(IDCANCEL, OnBnClickedCancel)
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();

 OnOK();

 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);
  OnCancel();
 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("192.168.2.100");
 //dwMask = inet_addr("255.255.255.0");
 //dwGate = inet_addr("192.168.2.1");

 dwIP = inet_addr("10.10.23.99");
 dwMask = inet_addr("255.255.255.0");
 dwGate = inet_addr("10.10.23.254");

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

void CAdapterIPConfigDlg::OnBnClickedCancel()
{
 // TODO: Add your control notification handler code here
 OnCancel();
}
 

原创粉丝点击