想要用程式來變更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

arrow
arrow
    全站熱搜

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