none
关于修改本地IP的问题 RRS feed

  • 问题

  • 本人现在手上有个 功能要实现 
    其实很简单 
    就是从程序 修改IP 

    环境 winxp vs2005 
    我也从网上搜索到一些方法 
    比如 
    http://www.vckbase.com/document/viewdoc/?id=851

    也下载了工程源码进行学习 
    release后的程序 运行后能正确的修改IP 

    但是DEBUG运行的时候会 
    出现一个错误窗口 

    信息如下: 

    Windows 已在 AdapterIPConfig.exe 中触发一个断点。 

    其原因可能是堆被损坏,这也说明 AdapterIPConfig.exe 中或它所加载的任何 DLL 中有 bug。 

    输出窗口可能提供了更多诊断信息 

    然后有2个选项 中断 和 继续 
    如果连续选择2次继续 
    和release的情况一样 能正常的修改IP 
    有没有高手来给我解释下 

    主要问题是在调用dhcpcsvc.dll 中的DhcpNotifyConfigChange函数的时候出的问题 
    麻烦高手解释下

    2011年1月4日 7:56

答案

  • Hi sghcpt,

      

      请问您有“清理解决方案”,然后生成吗?

      您还可以尝试以下解决办法:


    1.DLL中输出一个函数给EXE调用,专门用来释放由DLL分配的内存;
    2.GlobalAlloc()代替new,用GlobalFree()代替delete
    3.使用单一的堆,分配内存使用HeapAlloc(GetProcessHeap(),0,size),释放内存使用HeapFree(GetProcessHeap(),0,p)
    4.dllexeSettingsC/C++选项卡的Code GenerationUse Run-time liberary改成Debug Multithreaded DLL,在Release版本中改成Multithreaded DLL;这样使用一个CRT了——MSVCRT.DLL

     

     

    C语言

    C++语言

    Windows 平台

    COM

    IMalloc 接口

    BSTR

    申请

    malloc()

    new

    GlobalAlloc()

    CoTaskMemAlloc()

    Alloc()

    SysAllocString()

    重新申请

    realloc()

     

    GlobalReAlloc()

    CoTaskRealloc()

    Realloc()

    SysReAllocString()

    释放

    free()

    delete

    GlobalFree()

    CoTaskMemFree()

    Free()

    SysFreeString()

                 

     

     

    以上这些函数必须要按类型配合使用(比如:new 申请的内存,则必须用 delete 释放)。在 COM 内部,当然你可以随便使用任何类型的内存分配释放函数,但组件如果需要与客户进行内存的交互,则必须使用上表中的后三类函数族。IMalloc 接口又是对 CoTaskXXX() 函数族的一个包装。包装后,同时增强了一些功能,比如:IMalloc::GetSize()可以取得尺寸,使用 IMallocSpy 可以监视内存的使用。

     

    谢谢,

    Lucy


    Lucy Liu [MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    2011年1月10日 10:29
    版主

全部回复

  • 按照情况来看,您的程序还是有些隐患的。 Release 版本因为效率问题,不会将断言、边界检查等代码编译进程序。 因此,反而不会报错。 Debug 版本,对断言、边界检查、参数检查的代码都是编译的,因此,代码运行时检查会严格很多。 建议仔细检查一下DhcpNotifyConfigChange 函数调用的相关变量的值, 也可以将代码贴出来,大家一起分析一下。
    Would you know my name, if I saw you in heaven......
    2011年1月4日 21:59
    版主
  • To Michael Lee2

    多谢你的回答。下面是我的主要调用代码, 但不知道错在哪里。

    void CConfigIPDlg::OnBnClickedBtnSetip()
    {
    	// TODO: Add your control notification handler code here
    	int nIndex = m_comAdapter.GetCurSel();
    	int nLen = m_comAdapter.GetLBTextLen(nIndex);
    	CString strAdapter;
    	m_comAdapter.GetLBText(nIndex, strAdapter.GetBuffer(nLen));
    	strAdapter.ReleaseBuffer();
    	HKEY hKey;
    	CString strKeyName = _T("SYSTEM\\CurrentControlSet\\Services\\Tcpip\\Parameters\\Interfaces\\");
    	strKeyName += strAdapter;
    	if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, strKeyName, 0, KEY_WRITE, &hKey) != ERROR_SUCCESS)
    	{
    		::MessageBox(NULL, _T("RegOpenKey Failed."), _T("Error Info:"), 0);
    		return ;
    	}
    	BYTE bFirst= 0, bSecond = 0, bThird = 0, bFour = 0;
    	m_ipCtrl.GetAddress(bFirst, bSecond, bThird, bFour);
    	CString strValue, strFirst, strSecond, strThird, strFour;
    	strFirst.Format(_T("%d."), bFirst);
    	strSecond.Format(_T("%d."), bSecond);
    	strThird.Format(_T("%d."), bThird);
    	strFour.Format(_T("%d"), bFour);
    	strValue += strFirst;
    	strValue += strSecond;
    	strValue += strThird;
    	strValue += strFour;
    	USES_CONVERSION;
    	int dwBuf = strValue.GetLength() * 2 + 2; //why multible 2
    	BYTE* pBuf = new BYTE[dwBuf];
    	ZeroMemory(pBuf,dwBuf);
    	CopyMemory(pBuf, strValue.GetBuffer(), strValue.GetLength() * 2);
    	strValue.ReleaseBuffer();
    	if (RegSetValueEx(hKey, _T("IPAddress"), 0, REG_MULTI_SZ, pBuf, dwBuf) != ERROR_SUCCESS)
    	{
    		::MessageBox(NULL, _T("Call RegSetValueEx Function Failed"), _T("Error Info:"), 0);
    	}
    	RegCloseKey(hKey);
    	delete pBuf;
    	pBuf = NULL;
    	NotifyIPChange(strAdapter.GetBuffer(strAdapter.GetLength()), nIndex, strValue.GetBuffer(strValue.GetLength()));
    	strAdapter.ReleaseBuffer();
    	strValue.ReleaseBuffer();
    }
    
    typedef int (CALLBACK* DHCPNOTIFYPROC)(LPWSTR, LPWSTR, BOOL, DWORD, DWORD, DWORD, int);
    void CConfigIPDlg:: NotifyIPChange(LPWSTR lpszAdapterName, int nIndex, LPWSTR lpIPAddress)
     {
    	USES_CONVERSION;
    	BOOL bResult = FALSE;
    	HINSTANCE hDhcpDll;
    	DHCPNOTIFYPROC pDhcpNotifyProc;
    	if ((hDhcpDll = LoadLibrary(_T("dhcpcsvc"))) == NULL)
    	{
    		::MessageBox(NULL, _T("Load dhcpcsvc.dll failed"), _T("Error Info:"), 0);
    		return;
    	}
    	if ((pDhcpNotifyProc = (DHCPNOTIFYPROC)GetProcAddress(hDhcpDll, "DhcpNotifyConfigChange")) != NULL)
    	{
    		/*if ((pDhcpNotifyProc(NULL, lpszAdapterName, TRUE, nIndex, inet_addr(W2A(lpIPAddress)), inet_addr("255.255.255.0"), 0)) != ERROR_SUCCESS)
    		{
    			::MessageBox(NULL, _T("Call DhcpNotifyConfigChange Failed"), _T("Error Info:"), 0);
    			return ;
    		}*/
    		try
    		{
    			if ((pDhcpNotifyProc(NULL, lpszAdapterName, TRUE, nIndex, inet_addr(W2A(lpIPAddress)), inet_addr("255.255.255.0"), 0)) != ERROR_SUCCESS)
    			{
    				::MessageBox(NULL, _T("Call DhcpNotifyConfigChange Failed"), _T("Error Info:"), 0);
    				return ;
    			}
    		}
    		catch(CException& erroe)
    		{
    			;
    		}
    	}
    	FreeLibrary(hDhcpDll);
    

     

    2011年1月5日 0:24
  • Hi sghcpt,

    根据我的分析,您的问题很可能是运行库文件时的错误。

    您可以尝试以下解决方案。

    请打开项目属性-->配置属性-->C/C++-->代码生成-->运行时库,改成多线程调试DLL

    如果上面这些都没用,那么就不是库文件运行的错误了,请您试一下清理解决方案,然后重新生成。

     

    如果您的问题解决了,请把有用的回答标记为答案。

    谢谢,

    Lucy


    Lucy Liu [MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    2011年1月6日 8:34
    版主
  • To lucy-liu

    我尝试过你上面说的修改了,但效果还是一样,还是会出现上面的问题。我的系统是xp来的。

    2011年1月7日 0:50
  • Hi sghcpt,

      

      请问您有“清理解决方案”,然后生成吗?

      您还可以尝试以下解决办法:


    1.DLL中输出一个函数给EXE调用,专门用来释放由DLL分配的内存;
    2.GlobalAlloc()代替new,用GlobalFree()代替delete
    3.使用单一的堆,分配内存使用HeapAlloc(GetProcessHeap(),0,size),释放内存使用HeapFree(GetProcessHeap(),0,p)
    4.dllexeSettingsC/C++选项卡的Code GenerationUse Run-time liberary改成Debug Multithreaded DLL,在Release版本中改成Multithreaded DLL;这样使用一个CRT了——MSVCRT.DLL

     

     

    C语言

    C++语言

    Windows 平台

    COM

    IMalloc 接口

    BSTR

    申请

    malloc()

    new

    GlobalAlloc()

    CoTaskMemAlloc()

    Alloc()

    SysAllocString()

    重新申请

    realloc()

     

    GlobalReAlloc()

    CoTaskRealloc()

    Realloc()

    SysReAllocString()

    释放

    free()

    delete

    GlobalFree()

    CoTaskMemFree()

    Free()

    SysFreeString()

                 

     

     

    以上这些函数必须要按类型配合使用(比如:new 申请的内存,则必须用 delete 释放)。在 COM 内部,当然你可以随便使用任何类型的内存分配释放函数,但组件如果需要与客户进行内存的交互,则必须使用上表中的后三类函数族。IMalloc 接口又是对 CoTaskXXX() 函数族的一个包装。包装后,同时增强了一些功能,比如:IMalloc::GetSize()可以取得尺寸,使用 IMallocSpy 可以监视内存的使用。

     

    谢谢,

    Lucy


    Lucy Liu [MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    2011年1月10日 10:29
    版主