M
Michael M.
Hi all, I am trying to use the GetExtendedTcpTable API function and I having
some problems.
The program generates memory access errors, but not every time I run it
(about 1 n 3 times).
I first tried using StructureToPtr to read the TCP data, but then changed to
reading it 4 bytes at a time which did not make much diffrence in stability.
It does actualy return all the data correctly, but it crashes almost
randomly.
I think the problem might be something to do with the value returned in
dwTcpTableSize because when I check it's value it can be arround 380 when
there are only 4 TCP table records (each of which are 24 bytes long + 4
bytes for item count 96+4 ?).
I have included the whole function below followed by the API declaration. I
have used aliases for some types because it helps me convert the APIs from
MSDN so I have included my imports section.
Please help Thanks,
Michael.
<VB.Net 2005 on XP Pro SP2>
Imports
____________________________________
Imports System.Runtime.InteropServices
'** C++ Conversions Aliases. ***
Imports DWORD = System.UInt32
Imports BOOL = System.Boolean
'********************************
Function
____________________________________
Public Function GetExtendedTCPdata() As Integer
'* Use IP Version 4
Dim AF_INET As Integer = 2
'* Wlll store the TCP TABLE ROW Count.
Dim dwTcpTableSize As DWORD = 0
Dim RetVal As Integer
'* Get The Size of the TCP Table Data
RetVal = GetExtendedTcpTable(IntPtr.Zero, dwTcpTableSize, 1, AF_INET, 5, 0)
'* Create a Buffer
Dim iptrToTcpTableArray As IntPtr =
Marshal.AllocHGlobal(Marshal.SizeOf(dwTcpTableSize))
RetVal = GetExtendedTcpTable(iptrToTcpTableArray, dwTcpTableSize, 1,
AF_INET, 5, 0)
'* Create a List to hold the managed TCP ROWS after
Dim ListOfTcpRows As New List(Of MIB_TCPROW_OWNER_PID)
If RetVal = ERROR_SUCCESS Then
Dim dwTCPRowCount As DWORD
'* Get the total number / count of TCP ROWS.
dwTCPRowCount = Marshal.ReadInt32(iptrToTcpTableArray, 0)
'* Offset for walking through the unmanaged structures
Dim intOffset As Integer = 0
For I As DWORD = 0 To dwTCPRowCount - 1
Dim TCP_ROW As MIB_TCPROW_OWNER_PID ' * Structure 24 Bytes Long
'* Read a sngle data structure from unmanaged memory 4 bytes at a time then
increment offset and loop
With TCP_ROW
..dwState = Marshal.ReadInt32(iptrToTcpTableArray, intOffset + 4)
..dwLocalAddr = Marshal.ReadInt32(iptrToTcpTableArray, intOffset + 8)
..dwLocalPort = Marshal.ReadInt32(iptrToTcpTableArray, intOffset + 12)
..dwRemoteAddr = Marshal.ReadInt32(iptrToTcpTableArray, intOffset + 16)
..dwRemotePort = Marshal.ReadInt32(iptrToTcpTableArray, intOffset + 20)
..dwOwningPid = Marshal.ReadInt32(iptrToTcpTableArray, intOffset + 24)
End With
'* Add the filled TCP ROW into the List.
ListOfTcpRows.Add(TCP_ROW)
'* Increment the byte offset by 24 bytes (1 TCP ROW)
intOffset += 24
Next
End If
'* Free the allocated memory that holds the TCP DATA ROWS
Marshal.FreeHGlobal(iptrToTcpTableArray)
GC.Collect()
'TODO return the data in a generics list
Return 0 ' ListOfTcpRows
End Function
API DECLARATION
________________
Public Declare Unicode Function GetExtendedTcpTable Lib _
"IPHLPAPI.DLL" _
( _
ByVal pTcpTable As IntPtr, _
ByRef pDwSize As DWORD, _
ByVal bOrder As BOOL, _
ByVal ulAf As Integer, _
ByVal TCP_TABLE_CLASS As Integer, _
ByVal Reserved As Integer) As Integer
some problems.
The program generates memory access errors, but not every time I run it
(about 1 n 3 times).
I first tried using StructureToPtr to read the TCP data, but then changed to
reading it 4 bytes at a time which did not make much diffrence in stability.
It does actualy return all the data correctly, but it crashes almost
randomly.
I think the problem might be something to do with the value returned in
dwTcpTableSize because when I check it's value it can be arround 380 when
there are only 4 TCP table records (each of which are 24 bytes long + 4
bytes for item count 96+4 ?).
I have included the whole function below followed by the API declaration. I
have used aliases for some types because it helps me convert the APIs from
MSDN so I have included my imports section.
Please help Thanks,
Michael.
<VB.Net 2005 on XP Pro SP2>
Imports
____________________________________
Imports System.Runtime.InteropServices
'** C++ Conversions Aliases. ***
Imports DWORD = System.UInt32
Imports BOOL = System.Boolean
'********************************
Function
____________________________________
Public Function GetExtendedTCPdata() As Integer
'* Use IP Version 4
Dim AF_INET As Integer = 2
'* Wlll store the TCP TABLE ROW Count.
Dim dwTcpTableSize As DWORD = 0
Dim RetVal As Integer
'* Get The Size of the TCP Table Data
RetVal = GetExtendedTcpTable(IntPtr.Zero, dwTcpTableSize, 1, AF_INET, 5, 0)
'* Create a Buffer
Dim iptrToTcpTableArray As IntPtr =
Marshal.AllocHGlobal(Marshal.SizeOf(dwTcpTableSize))
RetVal = GetExtendedTcpTable(iptrToTcpTableArray, dwTcpTableSize, 1,
AF_INET, 5, 0)
'* Create a List to hold the managed TCP ROWS after
Dim ListOfTcpRows As New List(Of MIB_TCPROW_OWNER_PID)
If RetVal = ERROR_SUCCESS Then
Dim dwTCPRowCount As DWORD
'* Get the total number / count of TCP ROWS.
dwTCPRowCount = Marshal.ReadInt32(iptrToTcpTableArray, 0)
'* Offset for walking through the unmanaged structures
Dim intOffset As Integer = 0
For I As DWORD = 0 To dwTCPRowCount - 1
Dim TCP_ROW As MIB_TCPROW_OWNER_PID ' * Structure 24 Bytes Long
'* Read a sngle data structure from unmanaged memory 4 bytes at a time then
increment offset and loop
With TCP_ROW
..dwState = Marshal.ReadInt32(iptrToTcpTableArray, intOffset + 4)
..dwLocalAddr = Marshal.ReadInt32(iptrToTcpTableArray, intOffset + 8)
..dwLocalPort = Marshal.ReadInt32(iptrToTcpTableArray, intOffset + 12)
..dwRemoteAddr = Marshal.ReadInt32(iptrToTcpTableArray, intOffset + 16)
..dwRemotePort = Marshal.ReadInt32(iptrToTcpTableArray, intOffset + 20)
..dwOwningPid = Marshal.ReadInt32(iptrToTcpTableArray, intOffset + 24)
End With
'* Add the filled TCP ROW into the List.
ListOfTcpRows.Add(TCP_ROW)
'* Increment the byte offset by 24 bytes (1 TCP ROW)
intOffset += 24
Next
End If
'* Free the allocated memory that holds the TCP DATA ROWS
Marshal.FreeHGlobal(iptrToTcpTableArray)
GC.Collect()
'TODO return the data in a generics list
Return 0 ' ListOfTcpRows
End Function
API DECLARATION
________________
Public Declare Unicode Function GetExtendedTcpTable Lib _
"IPHLPAPI.DLL" _
( _
ByVal pTcpTable As IntPtr, _
ByRef pDwSize As DWORD, _
ByVal bOrder As BOOL, _
ByVal ulAf As Integer, _
ByVal TCP_TABLE_CLASS As Integer, _
ByVal Reserved As Integer) As Integer