Jump to content
Xtreme .Net Talk

Recommended Posts

Posted

Hi,

 

I've been attempting to get this to work for around 5 hours now, getting a little tired of it failing me :S

 

Please can somebody tell me where I'm going wrong, actually - I know where I'm going wrong but I don't know how to fix it.

 

   <StructLayout(LayoutKind.Sequential)> Public Class MIB_IFTABLE
       Public dwNumEntries As Integer
       <MarshalAs(UnmanagedType.SafeArray)> Public table() As MIB_IFROW
   End Class

   <StructLayout(LayoutKind.Sequential)> Public Class MIB_IFROW
       <VBFixedArray(511)> Public wszName() As Byte '511
       'Public wszName As Byte()
       Public dwIndex As Int32
       Public dwType As Int32
       Public dwMtu As Int32
       Public dwSpeed As Int32
       Public dwPhysAddrLen As Int32
       <VBFixedArray(7)> Public bPhysAddr() As Byte '7
       'Public bPhysAddr() As Byte
       Public dwAdminStatus As Int32
       Public dwOperStatus As Int32
       Public dwLastChange As Int32
       Public dwInOctets As Int32
       Public dwInUcastPkts As Int32
       Public dwInNUcastPkts As Int32
       Public dwInDiscards As Int32
       Public dwInErrors As Int32
       Public dwInUnknownProtos As Int32
       Public dwOutOctets As Int32
       Public dwOutUcastPkts As Int32
       Public dwOutNUcastPkts As Int32
       Public dwOutDiscards As Int32
       Public dwOutErrors As Int32
       Public dwOutQLen As Int32
       Public dwDescrLen As Int32
       <VBFixedArray(255)> Public bDescr() As Byte '255
       'Public bDescr() As Byte
   End Class

 

Above are the classes used. I cannot use Structures for some reason, it says:

 

Additional information: Can not marshal field table of type MIB_IFTABLE: This type can not be marshaled as a structure field.

 

(Note this only happens when I un-comment out the table variable in the MIB_IFTABLE structure)

 

This is the error I get with the code I use below:

 

An unhandled exception of type 'System.Runtime.InteropServices.SafeArrayTypeMismatchException' occurred in mscorlib.dll

 

Additional information: Mismatch has occurred between the runtime type of the array and the sub type recorded in the metadata.

 

       Dim lRetSize As Int32, lRows As Int32, ret As Long
       Dim IfRowTable As New MIB_IFTABLE
       Dim pStruct As IntPtr = IntPtr.Zero

       ret = GetIfTable(pStruct, lRetSize, 0)
       pStruct = Marshal.AllocHGlobal(lRetSize)

       ret = GetIfTable(pStruct, lRetSize, 0)
       IfRowTable = Marshal.PtrToStructure(pStruct, GetType(MIB_IFTABLE))
       Marshal.FreeHGlobal(pStruct)

 

It is strange, because when I comment out the table variable, it gives me the value of 1311096 in dwNumEntries. This value *should* be two (2 network devices, loopback + NIC)

 

Thank you for any help/advice in advance, Tom

Posted

Alright I've figured it all out, in fact, I did so like 2 hours after my original post. I'll paste in the code for a class I have written.

 

Imports System.Runtime.InteropServices

Class clsNetworkStats

#Region " DECLARES "

   Private Const MAX_INTERFACE_NAME_LEN As Long = 256
   Private Const ERROR_SUCCESS As Long = 0
   Private Const MAXLEN_IFDESCR As Long = 256
   Private Const MAXLEN_PHYSADDR As Long = 8

   <StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Unicode)> Private Structure MIB_IFROW
       <MarshalAs(UnmanagedType.ByValTStr, sizeconst:=MAX_INTERFACE_NAME_LEN)> Public wszName As String
       Public dwIndex As UInt32
       Public dwType As UInt32
       Public dwMtu As UInt32
       Public dwSpeed As UInt32
       Public dwPhysAddrLen As UInt32
       <MarshalAs(UnmanagedType.ByValArray, sizeconst:=MAXLEN_PHYSADDR)> Public bPhysAddr() As Byte
       Public dwAdminStatus As UInt32
       Public dwOperStatus As UInt32
       Public dwLastChange As UInt32
       Public dwInOctets As UInt32
       Public dwInUcastPkts As UInt32
       Public dwInNUcastPkts As UInt32
       Public dwInDiscards As UInt32
       Public dwInErrors As UInt32
       Public dwInUnknownProtos As UInt32
       Public dwOutOctets As UInt32
       Public dwOutUcastPkts As UInt32
       Public dwOutNUcastPkts As UInt32
       Public dwOutDiscards As UInt32
       Public dwOutErrors As UInt32
       Public dwOutQLen As UInt32
       Public dwDescrLen As UInt32
       <MarshalAs(UnmanagedType.ByValArray, sizeconst:=MAXLEN_IFDESCR)> Public bDescr() As Byte
   End Structure

   Public Structure IFROW_HELPER
       Public Name As String
       Public Index As Integer
       Public Type As Integer
       Public Mtu As Integer
       Public Speed As Integer
       Public PhysAddrLen As Integer
       Public PhysAddr As String
       Public AdminStatus As Integer
       Public OperStatus As Integer
       Public LastChange As Integer
       Public InOctets As Integer
       Public InUcastPkts As Integer
       Public InNUcastPkts As Integer
       Public InDiscards As Integer
       Public InErrors As Integer
       Public InUnknownProtos As Integer
       Public OutOctets As Integer
       Public OutUcastPkts As Integer
       Public OutNUcastPkts As Integer
       Public OutDiscards As Integer
       Public OutErrors As Integer
       Public OutQLen As Integer
       Public Description As String
       Public InMegs As String
       Public OutMegs As String
   End Structure

   <DllImport("iphlpapi")> Private Shared Function GetIfTable(ByRef pIfRowTable As Byte, ByRef pdwSize As Int32, ByVal bOrder As Int32) As Int32
   End Function

   <DllImport("iphlpapi")> Private Shared Function GetIfEntry(ByRef pIfRow As MIB_IFROW) As Int32
   End Function

#End Region

   Private m_Adapters As ArrayList

   Public Sub New(Optional ByVal IgnoreLoopBack As Boolean = True)

       Dim lRetSize As Int32, lRows As Int32, ret As Long, i As Byte
       Dim ifrow As New MIB_IFROW
       Dim buff(0) As Byte

       '--////////////////////////////////////////////////////////////////////////////////////////////
       ret = GetIfTable(0&, lRetSize, 0)
       ret = GetIfTable(buff(0), lRetSize, 0)
       lRows = buff(0)

       m_Adapters = New ArrayList(lRows)

       For i = 1 To lRows
           ifrow = New MIB_IFROW
           ifrow.dwIndex = Convert.ToUInt32(i)
           ret = GetIfEntry(ifrow)
           Dim ifhelp As IFROW_HELPER = PrivToPub(ifrow)
           If IgnoreLoopBack = True Then
               If ifhelp.Description.IndexOf("Loopback") < 0 Then
                   m_Adapters.Add(ifhelp)
               End If
           Else
               m_Adapters.Add(ifhelp)
           End If
       Next
       '--////////////////////////////////////////////////////////////////////////////////////////////

   End Sub

   Public Function GetAdapter(ByVal index As Integer) As IFROW_HELPER

       Return m_Adapters(index)

   End Function

   <DebuggerStepThrough()> Private Function PrivToPub(ByVal pri As MIB_IFROW) As IFROW_HELPER

       Dim ifhelp As New IFROW_HELPER

       ifhelp.Name = pri.wszName.Trim
       ifhelp.Index = Convert.ToInt32(pri.dwIndex)
       ifhelp.Type = Convert.ToInt32(pri.dwType)
       ifhelp.Mtu = Convert.ToInt32(pri.dwMtu)
       ifhelp.Speed = Convert.ToInt32(pri.dwSpeed)
       ifhelp.PhysAddrLen = Convert.ToInt32(pri.dwPhysAddrLen)
       ifhelp.PhysAddr = System.Text.Encoding.ASCII.GetString(pri.bPhysAddr)
       ifhelp.AdminStatus = Convert.ToInt32(pri.dwAdminStatus)
       ifhelp.OperStatus = Convert.ToInt32(pri.dwOperStatus)
       ifhelp.LastChange = Convert.ToInt32(pri.dwLastChange)
       ifhelp.InOctets = Convert.ToInt32(pri.dwInOctets)
       ifhelp.InUcastPkts = Convert.ToInt32(pri.dwInUcastPkts)
       ifhelp.InNUcastPkts = Convert.ToInt32(pri.dwInNUcastPkts)
       ifhelp.InDiscards = Convert.ToInt32(pri.dwInDiscards)
       ifhelp.InErrors = Convert.ToInt32(pri.dwInErrors)
       ifhelp.InUnknownProtos = Convert.ToInt32(pri.dwInUnknownProtos)
       ifhelp.OutOctets = Convert.ToInt32(pri.dwOutOctets)
       ifhelp.OutUcastPkts = Convert.ToInt32(pri.dwOutUcastPkts)
       ifhelp.OutNUcastPkts = Convert.ToInt32(pri.dwOutNUcastPkts)
       ifhelp.OutDiscards = Convert.ToInt32(pri.dwOutDiscards)
       ifhelp.OutErrors = Convert.ToInt32(pri.dwOutErrors)
       ifhelp.OutQLen = Convert.ToInt32(pri.dwOutQLen)
       ifhelp.Description = System.Text.Encoding.ASCII.GetString(pri.bDescr, 0, Convert.ToInt32(pri.dwDescrLen))

       ifhelp.InMegs = ToMegs(ifhelp.InOctets)
       ifhelp.OutMegs = ToMegs(ifhelp.OutOctets)

       Return ifhelp

   End Function

   <DebuggerStepThrough()> Private Function ToMegs(ByVal lSize As Long) As String

       Dim sDenominator As String = " B"
       'If lSize > 1024 Then lSize = (lSize / 1024) * 1000 'Windows styleee filesizing :)
       If lSize > 1000 Then
           sDenominator = " KB"
           lSize = lSize / 1000
       ElseIf lSize <= 1000 Then
           sDenominator = " B"
           lSize = lSize
       End If

       ToMegs = Format(lSize, "###,###0") & sDenominator

   End Function

End Class

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...