GetType on complex structure

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
 
P

Paul G. Tobey [eMVP]

Just thought I'd point out that GetAdaptersInfo() is already wrapped in
OpenNETCF... It doesn't do anything fancy, just sends a byte array and then
interprets the results in various [get] properties, but, if all you need is
something that works, take a look.

Paul T.

mobilemobile said:
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
 
G

Guest

Paul, thanks for your reply.

Yeah, I saw the OpenNETCF thing -- I think that the source code there is
what led me to GetAdaptersInfo() in the first place. But my client wants to
avoid 3rd party.

I was trying to get the sample at
http://www.pinvoke.net/default.aspx/iphlpapi.GetAdaptersInfo to work, which
is a really elegant solution for desktop (the VB sample). I really like
using explicitly stated structures -- I think it's better for maintenance,
less bits and bytes. I've got a bit of a workaround for it, using class
constructors like
http://www.intel.com/cd/ids/developer/asmo-na/eng/dc/pca/knowledgebase/82802.htm.

Just wondering why (specifically) Marshal.PtrToStructure and Marshal.SizeOf
don't work -- I'm looking for the rule so I can avoid in the future. Is it
because the structures contain reference types?

Steve

Steve

Paul G. Tobey said:
Just thought I'd point out that GetAdaptersInfo() is already wrapped in
OpenNETCF... It doesn't do anything fancy, just sends a byte array and then
interprets the results in various [get] properties, but, if all you need is
something that works, take a look.

Paul T.

mobilemobile said:
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
 
P

Paul G. Tobey [eMVP]

You can use the source for OpenNETCF separately from any full package,
although I certainly understand wanting to understand the source of the
problem...

Paul T.

mobilemobile said:
Paul, thanks for your reply.

Yeah, I saw the OpenNETCF thing -- I think that the source code there is
what led me to GetAdaptersInfo() in the first place. But my client wants
to
avoid 3rd party.

I was trying to get the sample at
http://www.pinvoke.net/default.aspx/iphlpapi.GetAdaptersInfo to work,
which
is a really elegant solution for desktop (the VB sample). I really like
using explicitly stated structures -- I think it's better for maintenance,
less bits and bytes. I've got a bit of a workaround for it, using class
constructors like
http://www.intel.com/cd/ids/developer/asmo-na/eng/dc/pca/knowledgebase/82802.htm.

Just wondering why (specifically) Marshal.PtrToStructure and
Marshal.SizeOf
don't work -- I'm looking for the rule so I can avoid in the future. Is
it
because the structures contain reference types?

Steve

Steve

Paul G. Tobey said:
Just thought I'd point out that GetAdaptersInfo() is already wrapped in
OpenNETCF... It doesn't do anything fancy, just sends a byte array and
then
interprets the results in various [get] properties, but, if all you need
is
something that works, take a look.

Paul T.

mobilemobile said:
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
 
G

Guest

Avoid third party? So they want you to develop exactly what we already have
and we give away for free, and they'll pay you for the time to do this
rather than implementing something unique that adds value to the
application? Some days I just don't get what some management people are
thinking.

-Chris



mobilemobile said:
Paul, thanks for your reply.

Yeah, I saw the OpenNETCF thing -- I think that the source code there is
what led me to GetAdaptersInfo() in the first place. But my client wants
to
avoid 3rd party.

I was trying to get the sample at
http://www.pinvoke.net/default.aspx/iphlpapi.GetAdaptersInfo to work,
which
is a really elegant solution for desktop (the VB sample). I really like
using explicitly stated structures -- I think it's better for maintenance,
less bits and bytes. I've got a bit of a workaround for it, using class
constructors like
http://www.intel.com/cd/ids/developer/asmo-na/eng/dc/pca/knowledgebase/82802.htm.

Just wondering why (specifically) Marshal.PtrToStructure and
Marshal.SizeOf
don't work -- I'm looking for the rule so I can avoid in the future. Is
it
because the structures contain reference types?

Steve

Steve

Paul G. Tobey said:
Just thought I'd point out that GetAdaptersInfo() is already wrapped in
OpenNETCF... It doesn't do anything fancy, just sends a byte array and
then
interprets the results in various [get] properties, but, if all you need
is
something that works, take a look.

Paul T.

mobilemobile said:
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
 
G

Guest

Thanks for the reply, Paul.

Part of it is to show the other developers there the actual C
routines/structures and how P/Invoke works, instead of just giving them a
black box in case they need to do something similar in the future.

Steve

Paul G. Tobey said:
You can use the source for OpenNETCF separately from any full package,
although I certainly understand wanting to understand the source of the
problem...

Paul T.

mobilemobile said:
Paul, thanks for your reply.

Yeah, I saw the OpenNETCF thing -- I think that the source code there is
what led me to GetAdaptersInfo() in the first place. But my client wants
to
avoid 3rd party.

I was trying to get the sample at
http://www.pinvoke.net/default.aspx/iphlpapi.GetAdaptersInfo to work,
which
is a really elegant solution for desktop (the VB sample). I really like
using explicitly stated structures -- I think it's better for maintenance,
less bits and bytes. I've got a bit of a workaround for it, using class
constructors like
http://www.intel.com/cd/ids/developer/asmo-na/eng/dc/pca/knowledgebase/82802.htm.

Just wondering why (specifically) Marshal.PtrToStructure and
Marshal.SizeOf
don't work -- I'm looking for the rule so I can avoid in the future. Is
it
because the structures contain reference types?

Steve

Steve

Paul G. Tobey said:
Just thought I'd point out that GetAdaptersInfo() is already wrapped in
OpenNETCF... It doesn't do anything fancy, just sends a byte array and
then
interprets the results in various [get] properties, but, if all you need
is
something that works, take a look.

Paul T.

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
 
G

Guest

Hi Chris, thanks for the reply.

The client is a small company that's been around for over 30 years. They've
been burned in their past by 3rd parties that went away and were burned
either by not having source (not the issue here), or not having the personnel
to interpret whatever source there was.

Steve

Avoid third party? So they want you to develop exactly what we already have
and we give away for free, and they'll pay you for the time to do this
rather than implementing something unique that adds value to the
application? Some days I just don't get what some management people are
thinking.

-Chris



mobilemobile said:
Paul, thanks for your reply.

Yeah, I saw the OpenNETCF thing -- I think that the source code there is
what led me to GetAdaptersInfo() in the first place. But my client wants
to
avoid 3rd party.

I was trying to get the sample at
http://www.pinvoke.net/default.aspx/iphlpapi.GetAdaptersInfo to work,
which
is a really elegant solution for desktop (the VB sample). I really like
using explicitly stated structures -- I think it's better for maintenance,
less bits and bytes. I've got a bit of a workaround for it, using class
constructors like
http://www.intel.com/cd/ids/developer/asmo-na/eng/dc/pca/knowledgebase/82802.htm.

Just wondering why (specifically) Marshal.PtrToStructure and
Marshal.SizeOf
don't work -- I'm looking for the rule so I can avoid in the future. Is
it
because the structures contain reference types?

Steve

Steve

Paul G. Tobey said:
Just thought I'd point out that GetAdaptersInfo() is already wrapped in
OpenNETCF... It doesn't do anything fancy, just sends a byte array and
then
interprets the results in various [get] properties, but, if all you need
is
something that works, take a look.

Paul T.

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
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top