Routerschnittstellen mit MprAdminInterfaceEnum (mprapi.dll) auflis

26/02/2009 - 15:23 von Oliver Stallmann | Report spam
Hallo Newsgroup,

ich möchte die Liste aller Routerschnittstellen eines Windows
2003/2008-Router erstellen. Ich verwende die API-Funktion
MprAdminInterfaceEnum aus der mprapi.dll.

In meiner Sub EnumRouterInterfaces wird die Anzahl der Interfaces korrekt
ermittelt, aber bis auf den Namen des ersten Interfaces nur Unfug beim
marshallen aus dem unmanaged code zurückgeliefert. Ich vermute daher einen
Fehler bei der Definition der Struktur MPR_INTERFACE_0 oder beim Import der
API-Funktionen. Ich habe schon diverse Einstellungen geàndert, konnte den
Fehler jedoch nicht finden.

Vielleicht hat jemand einen Tipp für mich.

Ich poste hier mal meine ganze Klasse (wegen der Größe allerdings ungerne),
in der der gesamte code enthalten ist.

Oliver





Public Class Test

#Region " Constants "

Public Const MAX_INTERFACE_NAME_LEN As Integer = 256

#End Region

#Region " API functions "

''' <summary>
''' The MprAdminServerConnect function establishes a connection to a
router for the purpose of administering that router.
''' Call this function before making any other calls to the server.
Use the handle returned in subsequent calls to administer interfaces on the
server.
''' </summary>
''' <param name="lpwsServerName">A pointer to a null-terminated
Unicode string that specifies the name of the remote server.
''' If this parameter is Nothing, the function returns a handle to
the local machine.</param>
''' <param name="phMprServer">A pointer to a HANDLE variable that
receives a handle to the server.
''' Use this handle in subsequent calls to administer the
server.</param>
''' <returns>If the function succeeds, the return value is NO_ERROR.
''' If the function fails, the return value is one of the following
error codes.
''' ERROR_ACCESS_DENIED: The calling application does not have
sufficient privilege.
''' RPC_S_INVALID_BINDING: This function was called with phMprServer
parameter equal to Nothing.
''' RPC_S_UNKNOWN_IF: The specified computer is not running the
Routing and RAS service.</returns>
''' <remarks></remarks>
Public Declare Unicode Function MprAdminServerConnect Lib
"mprapi.dll" (ByVal lpwsServerName As String, _

<Out()> ByRef phMprServer As Integer) As Integer

''' <summary>
''' The MprAdminInterfaceEnum function enumerates all the interfaces
on a specified server.
''' </summary>
''' <param name="hMprServer">Handle to the router on which to
execute this call. Obtain this handle by calling
MprAdminServerConnect.</param>
''' <param name="dwLevel">A DWORD value that describes the format in
which the information is returned in the lplpbBuffer parameter. Must be
zero.</param>
''' <param name="lplpbBuffer">On successful completion, a pointer to
an array of MPR_TRANSPORT_0 structures. Free this memory buffer by calling
MprAdminBufferFree.</param>
''' <param name="dwPrefMaxLen">Specifies the preferred maximum
length of returned data (in 8-bit bytes). If this parameter is -1,
''' the buffer returned is large enough to hold all available
information.</param>
''' <param name="lpdwEntriesRead">Pointer to a DWORD variable. This
variable receives the total number of interfaces that were enumerated
''' from the current position in the enumeration.</param>
''' <param name="lpdwTotalEntries">Pointer to a DWORD variable. This
variable receives the total number of interfaces that could have been
''' enumerated from the current resume position.</param>
''' <param name="lpdwResumeHandle">Pointer to a DWORD variable. This
variable specifies a resume handle that can be used to continue the
''' enumeration. The handle should be zero on the first call, and
left unchanged on subsequent calls. If the return code is ERROR_MORE_DATA
''' then the call can be re-issued using the handle to retrieve more
data. If on return, the handle is NULL, the enumeration cannot be continued.
''' For other types of error returns, this handle is invalid. This
parameter is optional. If the calling application specifies NULL for this
parameter,
''' the function does not return a resume handle.</param>
''' <returns>If the function succeeds, the return value is NO_ERROR.
''' If the function fails, the return value is one of the following
error codes.
''' ERROR_ACCESS_DENIED: The calling application does not have
sufficient privileges.
''' ERROR_MORE_DATA: More information is available; the enumeration
can be continued.
''' ERROR_NOT_ENOUGH_MEMORY: Insufficient resources to complete the
operation.
''' ERROR_NOT_SUPPORTED: The value of dwLevel is invalid.</returns>
''' <remarks></remarks>
Public Declare Unicode Function MprAdminInterfaceEnum Lib
"mprapi.dll" (<[In]()> ByVal hMprServer As Integer, _

<[In]()> ByVal dwLevel As Integer, _

<Out()> ByRef lplpbBuffer As IntPtr, _

<[In]()> ByVal dwPrefMaxLen As Integer, _

<Out()> ByRef lpdwEntriesRead As Integer, _

<Out()> ByRef lpdwTotalEntries As Integer, _

<[In]()> ByRef lpdwResumeHandle As Integer) As Integer

''' <summary>
''' The MprAdminBufferFree function frees memory buffers returned by:
''' MprAdminDeviceEnum, MprAdminInterfaceGetInfo,
MprAdminInterfaceDeviceGetInfo,
''' MprAdminInterfaceEnum, MprAdminServerGetInfo,
MprAdminInterfaceTransportGetInfo, and MprAdminTransportGetInfo.
''' </summary>
''' <param name="Buffer">[in] Pointer to the memory buffer to
free.</param>
''' <returns>If the function succeeds, the return value is NO_ERROR.
''' If the function fails, the return value is the following error
code.
''' ERROR_INVALID_PARAMETER: The pBuffer parameter is NULL.</returns>
''' <remarks></remarks>
Public Declare Function MprAdminBufferFree Lib "mprapi.dll" (ByVal
Buffer As IntPtr) As Integer



#End Region

#Region " Enums "
' The ROUTER_INTERFACE_TYPE type enumerates the different kinds of
interfaces on a router.
Public Enum ROUTER_INTERFACE_TYPE As Integer
ROUTER_IF_TYPE_CLIENT = 0 ' The interface is for a remote
client.
ROUTER_IF_TYPE_HOME_ROUTER ' The interface is for a home router.
ROUTER_IF_TYPE_FULL_ROUTER ' The interface is for a full router.
ROUTER_IF_TYPE_DEDICATED ' The interface is always connected.
It is a LAN interface, or the interface is connected over a leased line.
ROUTER_IF_TYPE_INTERNAL ' The interface is an internal-only
interface.
ROUTER_IF_TYPE_LOOPBACK ' The interface is a loopback
interface.
ROUTER_IF_TYPE_DIALOUT ' The interface is a dial-on-demand
(DOD) interface.
End Enum

' The ROUTER_CONNECTION_STATE type enumerates the possible states of
an interface on a router.
Public Enum ROUTER_CONNECTION_STATE As Integer
ROUTER_IF_STATE_UNREACHABLE = 0 ' The interface is unreachable.
For a list of possible reasons, see Unreachability Reasons.
ROUTER_IF_STATE_DISCONNECTED ' The interface is reachable but
disconnected.
ROUTER_IF_STATE_CONNECTING ' The interface is in the
process of connecting.
ROUTER_IF_STATE_CONNECTED ' The interface is connected
End Enum

''' <summary>
''' The following table lists constant values that indicate why an
interface is unreachable.
''' </summary>
''' <remarks></remarks>
Public Enum UnreachabilityReasons As Integer
MPR_INTERFACE_ADMIN_DISABLED ' The administrator has disabled
the interface.
MPR_INTERFACE_CONNECTION_FAILURE ' The previous connection
attempt failed. Look at the dwLastError member for the error code.
MPR_INTERFACE_DIALOUT_HOURS_RESTRICTION ' Dial-out is not
allowed at the current time.
MPR_INTERFACE_OUT_OF_RESOURCES ' No ports or devices are
available for use.
MPR_INTERFACE_SERVICE_PAUSED ' The service is paused.
MPR_INTERFACE_NO_MEDIA_SENSE ' The network cable is disconnected
from the network card.
MPR_INTERFACE_NO_DEVICE ' The network card has been removed from
the machine.

End Enum
#End Region

#Region " Structures "

''' <summary>
''' The MPR_INTERFACE_0 structure contains information for a
particular router interface.
''' </summary>
''' <remarks></remarks>
<StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Unicode),
Serializable()> _
Public Structure MPR_INTERFACE_0
''' <summary>
''' Pointer to a Unicode string that contains the name of the
interface.
''' </summary>
''' <remarks></remarks>
<MarshalAs(UnmanagedType.ByValTStr,
SizeConst:=MAX_INTERFACE_NAME_LEN + 1)> Public wszInterfaceName As String '

''' <summary>
''' Handle to the interface.
''' </summary>
''' <remarks></remarks>
Public hInterface As Integer

''' <summary>
''' Specifies whether the interface is enabled. This member is
TRUE if the interface is enabled, FALSE if the interface is administratively
disabled.
''' </summary>
''' <remarks></remarks>
Public fEnabled As Boolean

''' <summary>
''' Specifies the type of interface.
''' </summary>
''' <remarks></remarks>
Public dwIfType As ROUTER_INTERFACE_TYPE

''' <summary>
''' Specifies the current state of the interface, for example
connected, disconnected, or unreachable.
''' For a list of possible states, see ROUTER_CONNECTION_STATE.
''' </summary>
''' <remarks></remarks>
Public dwConnectionState As ROUTER_CONNECTION_STATE

''' <summary>
''' Specifies a value that represents a reason why the interface
cannot be reached. See Unreachability Reasons for a list of possible values.
''' </summary>
''' <remarks></remarks>
Public fUnReachabilityReasons As UnreachabilityReasons ' INteger

''' <summary>
''' Specifies a nonzero value if the interface fails to connect.
''' </summary>
''' <remarks></remarks>
Public dwLastError As Integer

End Structure

#End Region


''' <summary>
''' Enumerate Routing and RAS interfaces of local Windows Server
2003/2008
''' </summary>
''' <remarks></remarks>
Public Shared Sub EnumRouterInterfaces()



Try

Dim sHandle As Integer = 0 ' Handle to RRas-Service
Dim ERROR_VALUE As Integer = 0 ' ExitCode of external API
function

' Get Handle of RRAS server
ERROR_VALUE = MprAdminServerConnect(Nothing, sHandle) '
//NULL for localhost router else Machine IP or Machine Name for remote router
If ERROR_VALUE <> 0 Then
Debug.WriteLine("Error " & ERROR_VALUE.ToString & ":
MprAdminServerConnect()")
Exit Try
End If


' Interface structure
Dim RouterInterface As MPR_INTERFACE_0
' Pointer to interface structure
Dim ptrMPR_INTERFACE_0 As IntPtr = IntPtr.Zero
Dim intCurrentInterfacesIndex As Integer = 0
Dim intTotalInterfCount As Integer = 0
Dim intResumeHandle As Integer = 0

' Get pointer to array of router interfaces
ERROR_VALUE = MprAdminInterfaceEnum(sHandle, 0,
ptrMPR_INTERFACE_0, -1, intCurrentInterfacesIndex, intTotalInterfCount,
intResumeHandle)

Try

' Enumerate all interfaces
Dim pCurrent As IntPtr = ptrMPR_INTERFACE_0
For i As Integer = 0 To intTotalInterfCount - 1

' Marshal interface data
' An dieser Stelle wird nur bei i=0 für RouterInterface.wszInterfaceName ein
korrekter Wert geliefert.

RouterInterface =
CType(Marshal.PtrToStructure(pCurrent, GetType(MPR_INTERFACE_0)),
MPR_INTERFACE_0)

Debug.WriteLine(RouterInterface.wszInterfaceName)

' move to next interface data
pCurrent = New IntPtr(pCurrent.ToInt32 +
Marshal.SizeOf(GetType(MPR_INTERFACE_0)))
Next

Finally
' FreeMemory
MprAdminBufferFree(ptrMPR_INTERFACE_0)
End Try

Catch ex As Exception
MsgBox(ex.ToString)
End Try


End Sub


End Class
 

Lesen sie die antworten

#1 Peter Fleischer
27/02/2009 - 06:31 | Warnen spam
"Oliver Stallmann" schrieb im
Newsbeitrag news:

ich möchte die Liste aller Routerschnittstellen eines Windows
2003/2008-Router erstellen. Ich verwende die API-Funktion
MprAdminInterfaceEnum aus der mprapi.dll.

In meiner Sub EnumRouterInterfaces wird die Anzahl der Interfaces korrekt
ermittelt, aber bis auf den Namen des ersten Interfaces nur Unfug beim
marshallen aus dem unmanaged code zurückgeliefert. Ich vermute daher einen
Fehler bei der Definition der Struktur MPR_INTERFACE_0 oder beim Import
der
API-Funktionen. Ich habe schon diverse Einstellungen geàndert, konnte den
Fehler jedoch nicht finden.

Vielleicht hat jemand einen Tipp für mich.

Ich poste hier mal meine ganze Klasse (wegen der Größe allerdings
ungerne),
in der der gesamte code enthalten ist.



Hi Oliver,
mir ist aufgefallen, dass in der Struktur ein Pointer erforderlich ist, du
aber die Zeichenkette vollstàndig in die Struktur eingebaut hast. Da dürfte
bei der Array-Rechnung ein falscher Schritt genutzt werden und du làufst in
deiner Schleife aus dem Speicher hinaus und bekommant natürlich ab zweitem
Durchlauf falsche Angaben.

''' <summary>
''' Pointer to a Unicode string that contains the name of the interface.
''' </summary>
''' <remarks></remarks>
<MarshalAs(UnmanagedType.ByValTStr, SizeConst:=MAX_INTERFACE_NAME_LEN +
1)> Public wszInterfaceName As String '

Weiterhin ist die Zuordnung der Aufzàhlungselemente zu den Werten zu prüfen.

Viele Grüsse
Peter

Ähnliche fragen