想要用程式來變更WinCE的網路卡IP,微軟可能認為嵌入式系統的網卡IP在設備安裝後就不會更動,原因未知,但就是未提供方便API方便修改,因此想要更改IP就必須從修改Registry註冊表下手。

首先,要修改網卡IP就必須先知道網卡資訊在註冊表的位置與CreateFile時需要用的設備名稱。對於「設備名稱」,若系統只有單一網卡通常都會是"NDS0:",若是多張網卡就要找該網卡的Index了,沒錯,就是到BuiltIn區找驅動程式的設定,到下面位置取得下列兩參數:

[HKEY_LOCAL_MACHINE\Drivers\BuiltIn\網卡名稱]
   "Prefix"="NDS" 
   "InstanceIndex"=dword:1 

NDS代表的是網路設備,例如串列設備是COM,不同的網卡是用不同的InstanceIndex做區隔,此兩參數組起便是設備名稱,此範例為NDS1:。找到設備名稱同時也會確定網卡名稱,這裡稍為提點一下,網卡名稱有可能會多層,如"CS89001"、"PCI\RTL81391"。

 

查完網卡名稱和設備名稱後,順便可以瞧瞧網卡資訊在註冊表,其位置在:

[HKEY_LOCAL_MACHINE\Comm\網卡名稱\Parms\TcpIp] 
   "EnableDHCP"=dword:0 
   "DefaultGateway"="192.168.0.1" 
   "DNS"="168.95.1.1" 
   "IpAddress"="192.168.0.2" 
   "Subnetmask"="255.255.255.0" 

這便是我們修改的目標。由於我是用.NET環境開發,因此直接用
    Microsoft.Win32.Registry.SetValue
進行修改,範例如下:

Dim strKeyName As String = String.Format("HKEY_LOCAL_MACHINE\Comm\{0}\Parms\TCPIP", NDISAdapterName)
    Microsoft.Win32.Registry.SetValue(strKeyName, "EnableDHCP", 0)
    Microsoft.Win32.Registry.SetValue(strKeyName, "IpAddress", IP)
    Microsoft.Win32.Registry.SetValue(strKeyName, "SubnetMask", "255.255.255.0")
    Microsoft.Win32.Registry.SetValue(strKeyName, "DefaultGateway", "")

其中NDISAdapterName是設備名稱。

如此只是將網卡的註冊表修改完成,但實際網卡IP並未變更,需要作一次網卡的REBIND,這時就換CreateFile與DeviceIOControlg上場了:

Dim _NDISAdapterName() As Byte = System.Text.Encoding.Default.GetBytes(NDISAdapterName)

m_handle = CreateFile("NDS1:", 0, 0, Nothing, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, INVALID_HANDLE_VALUE)

DeviceIoControl(m_handle, IOCTL_NDIS_REBIND_ADAPTER, _NDISAdapterName, _NDISAdapterName.Length, Nothing, 0, v_ui, System.IntPtr.Zero)

CloseHandle(m_handle)

CreateFile、DeviceIOControl、CloseHandle要在.NET上運行當然是用P/Invoke引用Coredll.dll,至於OPEN_EXISTING、IOCTL_NDIS_REBIND_ADAPTER可以查.h檔。方便起見,以下我就直接提供我的P/Invoke程式碼,COPY/PASTE即可使用。

Const OPEN_EXISTING As UInt32 = 3
Const INVALID_HANDLE_VALUE As UInt32 = -1
Const IOCTL_NDIS_REBIND_ADAPTER As UInt32 = &H17002E

<DllImport("coredll.dll", EntryPoint:="CreateFileW")> _
Public Shared Function CreateFile(ByVal lpFileName As String, ByVal dwDesiredAccess As System.UInt32, ByVal dwShareMode As System.UInt32, ByVal lpSecurityAttributes As System.IntPtr, ByVal dwCreationDisposition As System.UInt32, ByVal dwFlagsAndAttributes As System.UInt32, ByVal hTemplateFile As System.IntPtr) As System.IntPtr
End Function

<DllImport("CoreDll.dll")> _
Public Shared Function DeviceIoControl(ByVal m_handle As System.IntPtr, ByVal dwIoControlCode As UInt32, ByVal npInBuffer() As Byte, ByVal nInBufferSize As UInt32, ByVal lpOutBuffer() As Byte, ByVal nOutBufferSize As UInt32, ByRef lpBytesReturned As UInt32, ByRef lpOverlapped As IntPtr) As Boolean
End Function

<DllImport("coredll.dll")> _
Public Shared Function CloseHandle(ByVal m_handle As IntPtr) As Integer
End Function

創作者介紹

傑克鼠的下午茶

傑克鼠 發表在 痞客邦 PIXNET 留言(3) 人氣()


留言列表 (3)

發表留言
  • kevin
  • 請問一下...DeviceIoControl(m_handle, IOCTL_NDIS_REBIND_ADAPTER, _NDISAdapterName, _NDISAdapterName.Length, Nothing, 0, v_ui, System.IntPtr.Zero) 中的 v_ui 是什麼值呢?? 我該如何設定~
    m_handle 是要宣告為什麼??

    大大的程式碼在我的VS.NET 2005 + CE 5.0中會出現這些錯誤....還請大大教教小弟!! 謝謝~~
  • v_ui用一宣告變數帶入即可
    m_handle可以用System.IntPtr宣告

    傑克鼠 於 2010/07/10 01:47 回覆

  • linyinghao
  • 請教一下..如何在wince下用.net讓網卡作IP release(釋放) ip renew(重新取得) 因為使用DHCP又在不同AP間跑來跑去 雖然AP設定相同,但是因為無線涵蓋範圍大,會造成訊號弱但IP持續被上一台AP抓住不放..感謝~
  • funky
  • 請問一下有範例檔案嗎??
    我試了好幾次似乎都有問題~謝謝!!
找更多相關文章與討論