G
Guest
I doing P/Invoke on GetAdaptersInfo (the code follows, with the structures
for GetAdaptersInfo).
I'm getting a NonSupportedException on the code line:
Dim Entry As IP_ADAPTER_INFO = CType(Marshal.PtrToStructure(pEntry,
GetType(IP_ADAPTER_INFO)), IP_ADAPTER_INFO)
I took it piece by piece, and the exception is occurring on the
Marshal.PtrToStructure call. I've got a workaround (by using class
constructors with the pointer as the argument, kinda brute force), but I just
wanted to make sure that there was no way to make this work (or what is the
specific reason it doesn't work).
I also get a NonSupportedException for
Marshal.SizeOf(GetType(IP_ADAPTER_INFO)).
So, what's the specific reason that these two Marshal methods don't work --
is it just too complex a structure?
Thanks for any help,
Steve
===================================================
Public Const MAX_ADAPTER_NAME_LENGTH As Int32 = 256
Public Const MAX_ADAPTER_ADDRESS_LENGTH As Int32 = 8
Public Const MAX_ADAPTER_DESCRIPTION_LENGTH As Int32 = 128
<StructLayout(LayoutKind.Sequential)> _
Public Class IP_ADDRESS_STRING
<MarshalAs(UnmanagedType.ByValTStr, SizeConst:=(4 * 4))> _
Dim value As String
End Class
<StructLayout(LayoutKind.Sequential)> _
Public Class IP_ADDR_STRING
Public [Next] As IntPtr
Public IpAddress As IP_ADDRESS_STRING
Public Mask As IP_ADDRESS_STRING
Public Context As Int32
End Class
<StructLayout(LayoutKind.Sequential)> _
Public Class IP_ADAPTER_INFO
Public [Next] As IntPtr
Public ComboIndex As Int32
<MarshalAs(UnmanagedType.ByValTStr,
SizeConst:=(MAX_ADAPTER_NAME_LENGTH + 4))> _
Public Name As String
<MarshalAs(UnmanagedType.ByValTStr,
SizeConst:=(MAX_ADAPTER_DESCRIPTION_LENGTH + 4))> _
Public Description As String
Public AddressLength As Int32
<MarshalAs(UnmanagedType.ByValArray,
SizeConst:=(MAX_ADAPTER_ADDRESS_LENGTH))> _
Public Address() As Byte
Public Index As Int32
Public Type As Int32
Public DhcpEnabled As Int32
Public CurrentIpAddress As IP_ADDR_STRING ' Int32 -- this is a
*IP_ADDR_STRING (ptr) in original structure
Public IpAddressList As IP_ADDR_STRING
Public GatewayList As IP_ADDR_STRING
Public DhcpServer As IP_ADDR_STRING
Public HaveWins As Int32
Public PrimaryWinsServer As IP_ADDR_STRING
Public SecondaryWinsServer As IP_ADDR_STRING
Public LeaseObtained As DateTime ' Int32 -- original
structure: time_t
Public LeaseExpires As DateTime ' Int32 -- original
structure: time_t
End Sub
End Class
<DllImport("iphlpapi.dll")> _
Private Shared Function GetAdaptersInfo( _
ByVal pAdapterInfo As IntPtr, _
ByRef pBufOutLen As UInt64) As Int32
End Function
Public Shared Sub GetAdapters()
Dim structSize As Int32 = 1192 '
Marshal.SizeOf(GetType(IP_ADAPTER_INFO)) -- doesn't work in NETcf
Dim pArray As IntPtr = Marshal.AllocHGlobal(structSize)
Dim len As UInt64 = Convert.ToUInt64(structSize)
Dim ret As Int32 = GetAdaptersInfo(pArray, len) ' if
ERROR_BUFFER_OVERFLOW, len returned with needed buffer size
If ret = ERROR_BUFFER_OVERFLOW Then ' Buffer was
too small, reallocate the correct size for the buffer.
pArray = Marshal.ReAllocHGlobal(pArray, New
IntPtr(Convert.ToInt64(len)))
ret = GetAdaptersInfo(pArray, len)
End If
If ret = ERROR_SUCCESS Then ' Call
succeeded
Dim pEntry As IntPtr = pArray
Do ' Retrieve
the adapter info from the memory address.
Dim Entry As IP_ADAPTER_INFO =
CType(Marshal.PtrToStructure(pEntry, GetType(IP_ADAPTER_INFO)),
IP_ADAPTER_INFO)
pEntry = Entry.Next
Loop Until IntPtr.op_Equality(pEntry, IntPtr.Zero)
End If
Marshal.FreeHGlobal(pArray)
End Sub
for GetAdaptersInfo).
I'm getting a NonSupportedException on the code line:
Dim Entry As IP_ADAPTER_INFO = CType(Marshal.PtrToStructure(pEntry,
GetType(IP_ADAPTER_INFO)), IP_ADAPTER_INFO)
I took it piece by piece, and the exception is occurring on the
Marshal.PtrToStructure call. I've got a workaround (by using class
constructors with the pointer as the argument, kinda brute force), but I just
wanted to make sure that there was no way to make this work (or what is the
specific reason it doesn't work).
I also get a NonSupportedException for
Marshal.SizeOf(GetType(IP_ADAPTER_INFO)).
So, what's the specific reason that these two Marshal methods don't work --
is it just too complex a structure?
Thanks for any help,
Steve
===================================================
Public Const MAX_ADAPTER_NAME_LENGTH As Int32 = 256
Public Const MAX_ADAPTER_ADDRESS_LENGTH As Int32 = 8
Public Const MAX_ADAPTER_DESCRIPTION_LENGTH As Int32 = 128
<StructLayout(LayoutKind.Sequential)> _
Public Class IP_ADDRESS_STRING
<MarshalAs(UnmanagedType.ByValTStr, SizeConst:=(4 * 4))> _
Dim value As String
End Class
<StructLayout(LayoutKind.Sequential)> _
Public Class IP_ADDR_STRING
Public [Next] As IntPtr
Public IpAddress As IP_ADDRESS_STRING
Public Mask As IP_ADDRESS_STRING
Public Context As Int32
End Class
<StructLayout(LayoutKind.Sequential)> _
Public Class IP_ADAPTER_INFO
Public [Next] As IntPtr
Public ComboIndex As Int32
<MarshalAs(UnmanagedType.ByValTStr,
SizeConst:=(MAX_ADAPTER_NAME_LENGTH + 4))> _
Public Name As String
<MarshalAs(UnmanagedType.ByValTStr,
SizeConst:=(MAX_ADAPTER_DESCRIPTION_LENGTH + 4))> _
Public Description As String
Public AddressLength As Int32
<MarshalAs(UnmanagedType.ByValArray,
SizeConst:=(MAX_ADAPTER_ADDRESS_LENGTH))> _
Public Address() As Byte
Public Index As Int32
Public Type As Int32
Public DhcpEnabled As Int32
Public CurrentIpAddress As IP_ADDR_STRING ' Int32 -- this is a
*IP_ADDR_STRING (ptr) in original structure
Public IpAddressList As IP_ADDR_STRING
Public GatewayList As IP_ADDR_STRING
Public DhcpServer As IP_ADDR_STRING
Public HaveWins As Int32
Public PrimaryWinsServer As IP_ADDR_STRING
Public SecondaryWinsServer As IP_ADDR_STRING
Public LeaseObtained As DateTime ' Int32 -- original
structure: time_t
Public LeaseExpires As DateTime ' Int32 -- original
structure: time_t
End Sub
End Class
<DllImport("iphlpapi.dll")> _
Private Shared Function GetAdaptersInfo( _
ByVal pAdapterInfo As IntPtr, _
ByRef pBufOutLen As UInt64) As Int32
End Function
Public Shared Sub GetAdapters()
Dim structSize As Int32 = 1192 '
Marshal.SizeOf(GetType(IP_ADAPTER_INFO)) -- doesn't work in NETcf
Dim pArray As IntPtr = Marshal.AllocHGlobal(structSize)
Dim len As UInt64 = Convert.ToUInt64(structSize)
Dim ret As Int32 = GetAdaptersInfo(pArray, len) ' if
ERROR_BUFFER_OVERFLOW, len returned with needed buffer size
If ret = ERROR_BUFFER_OVERFLOW Then ' Buffer was
too small, reallocate the correct size for the buffer.
pArray = Marshal.ReAllocHGlobal(pArray, New
IntPtr(Convert.ToInt64(len)))
ret = GetAdaptersInfo(pArray, len)
End If
If ret = ERROR_SUCCESS Then ' Call
succeeded
Dim pEntry As IntPtr = pArray
Do ' Retrieve
the adapter info from the memory address.
Dim Entry As IP_ADAPTER_INFO =
CType(Marshal.PtrToStructure(pEntry, GetType(IP_ADAPTER_INFO)),
IP_ADAPTER_INFO)
pEntry = Entry.Next
Loop Until IntPtr.op_Equality(pEntry, IntPtr.Zero)
End If
Marshal.FreeHGlobal(pArray)
End Sub