Visual Basic, .NET, ASP, VBScript
 

   
   
     

Форум - Создание справочника Windows API

Страница: 1 |

 

  Вопрос: GetAdaptersInfo инфо о второй сетевухе не могу пол Добавлено: 04.09.05 12:06  

Автор вопроса:  student-uni
ПРоблема такая,
при одном сетевом интерфейсе GetAdaptersInfo работает шикарно.
Но что делать если сетевых интерфейса два, и инфа мне нужна о втором ?

Посмторите пожалуйста код внизу и скажите, что может я не так делаю.

Текст взят из МСДН поэтому кое какие детали опущены.

Итак GetAdaptersInfo требует на вход два параметра
1. Указатель на структуру IP_ADAPTER_INFO куда собственно
пишется вся инфа об интерфейсе и
2. длина участка памяти, причем если вместо структуры дать 0& то она сама даёт нам необходимую длину.

Напомню вид структуры:

Type IP_ADAPTER_INFO
            Next As Long - адрес следующего блока
            ComboIndex As Long
            AdapterName As String * MAX_ADAPTER_NAME_LENGTH - имя
            Description As String * MAX_ADAPTER_DESCRIPTION_LENGTH
            AddressLength As Long
            Address(MAX_ADAPTER_ADDRESS_LENGTH - 1) As Byte
            Index As Long
            Type As Long
            DhcpEnabled As Long
            CurrentIpAddress As Long
            IpAddressList As IP_ADDR_STRING
            GatewayList As IP_ADDR_STRING
            DhcpServer As IP_ADDR_STRING
            HaveWins As Byte
            PrimaryWinsServer As IP_ADDR_STRING
            SecondaryWinsServer As IP_ADDR_STRING
            LeaseObtained As Long
            LeaseExpires As Long
End Type

Пишем свою функцию внутри которой будет работать АПИшка GetAdaptersInfo и определим в нашей функции следующие переменные

Public Function МояФункция() As String
Dim error As Long
Dim FixedInfoSize As Long
Dim AdapterInfoSize As Long - здесь храним размер блока - параметр №2 функции GetAdaptersInfo

Dim i As Integer
Dim PhysicalAddress As String
Dim NewTime As Date
Dim AdapterInfo As IP_ADAPTER_INFO
Это объект типа той структуры что идёт в параметр №1 функции GetAdaptersInfo

Dim AddrStr As IP_ADDR_STRING
Dim FixedInfo As FIXED_INFO
Dim Buffer As IP_ADDR_STRING
Dim pAddrStr As Long
Dim pAdapt As Long
Dim Buffer2 As IP_ADAPTER_INFO
Dim FixedInfoBuffer() As Byte
Dim AdapterInfoBuffer() As Byte

Шаг первый

AdapterInfoSize = 0
error = GetAdaptersInfo(ByVal 0&, AdapterInfoSize)

вынуждаем функцию показать нужный размер.
Для справки скажу при одном интерфейсе размер выдаётся 640 /наверно байт/, а при наличии двух интерфейсов - 1280.

Шаг второй

ReDim AdapterInfoBuffer(AdapterInfoSize - 1)

Задаём произвольному массиву определённый размер,
который нв практике соответственно 639 и 1279 /массив считается с нуля, поэтому на один меньше/

Шаг третий

error = GetAdaptersInfo(AdapterInfoBuffer(0), AdapterInfoSize)

Повтороно вызываем функцию, но теперь у неё во втором параметре
правильный размер, а в первом подсовываем ей вместо её любимой
структуры наш массив, куда она успешно закачает всю инфу,
и массив ей придётся в пору по размеру.
Напомню размер при одном интерфейсе 639 при двух 1279.
/Закачивает она кстати каждый раз в самые разные закутки памяти/
Но при этом AdapterInfoBuffer(0) всегда указывает на начало данных.

(все эти error на практике ещё проверяются, но по ним всё окей,
так что я эти куски кода опустил)

Шаг четвёртый

CopyMemory AdapterInfo, AdapterInfoBuffer(0), AdapterInfoSize

Копируем в объект AdapterInfo который типа структуры с инфой IP_ADAPTER_INFO весь наш буфер AdapterInfoBuffer(0) он указывает
на начало области копирования, а AdapterInfoSize показывает размер.
 и теперь мы можем доставать все элементы что были в структуре IP_ADAPTER_INFO например:

AdapterInfo.Next - адрес следующего блока
AdapterInfo.ComboIndex
AdapterInfo.AdapterName

и так далее.

Так вот это всё канает для первого интерфейса.

Но при двух интерфейсах эта гадина резервирует в два раза
больше памяти!! Значит в этом же массиве содержится
также инфа о втором интерфейсе !!!

Вопрос к знатокам : как же мне достать её блин!!!
/инфу о втором интерфейсе/

Пробовал

CopyMemory AdapterInfo, AdapterInfoBuffer(640), AdapterInfoSize=640

Болт. В смысле параметры не изменили своего значения
Напр AdapterInfo.Next показывает то же самое
AdapterInfo.Index то же

Пробовал

CopyMemory AdapterInfo, AdapterInfo.Index, AdapterInfoSize=640

типа всунуть ей адрес на второй блок - тоже не проходит.


Повторю резюме

в результате
Шага третьего

error = GetAdaptersInfo(AdapterInfoBuffer(0), AdapterInfoSize)

По адресу на который указывает первый/нулевой/ элемент массива
AdapterInfoBuffer(0), записаны данные длиной AdapterInfoSize
равной в случае двух адаптеров 1280 которые по своей структуре
соответствуют Type IP_ADAPTER_INFO
Т.е
скопировав

CopyMemory AdapterInfo, AdapterInfoBuffer(0), AdapterInfoSize

где цель - AdapterInfo- объект типа нашей структуры
можно получать доступ к элементам структуры
и извлекать информацию о первом адаптере

AdapterInfo.Next - адрес следующего блока
AdapterInfo.ComboIndex
AdapterInfo.AdapterName

и так далее по всем элементам структуры /см выше/

Вопрос: как добраться до структуированных
данных о втором адаптере ?
/предполагаю они в этом же массиве/

Спасибо всем за потраченное время.

В случае успеха - обязуюсь выложить
работающий код. Будет Незаменимая прибамбаска для перезаписи
Routing table при ВПН и др соединениях.

Всем привет.



Ответить

  Ответы Всего ответов: 9  

Номер ответа: 1
Автор ответа:
 Sharp


Лидер форума

ICQ: 216865379 

Вопросов: 106
Ответов: 9979
 Web-сайт: sharpc.livejournal.com
 Профиль | | #1
Добавлено: 04.09.05 13:00
Там же написано - AdapterInfo.Next - адрес следующего блока, а в MSDN и пример есть:
if ((dwRetVal = GetAdaptersInfo( pAdapterInfo, &ulOutBufLen)) == NO_ERROR) {
  pAdapter = pAdapterInfo;
  while (pAdapter) {
    ...
    pAdapter = pAdapter->Next;
  }
}

Другими словами, после CopyMemory AdapterInfo, AdapterInfoBuffer(0), AdapterInfoSize надо CopyMemory AdapterInfo, AdapterInfo.Next, AdapterInfoSize
только уже ByVal AdapterInfo.Next

Ответить

Номер ответа: 2
Автор ответа:
 student-uni



Вопросов: 122
Ответов: 257
 Профиль | | #2 Добавлено: 04.09.05 14:32
CopyMemory AdapterInfo, AdapterInfo.Next, AdapterInfoSize
Пробовал см выше /опечатался AdapterInfo.Index написал, но на самом деле AdapterInfo.Next пробовал/
Не идёт. Как минимум надо ещё и размер уменьшить на 640 - второй параметр!! Не думаешь ?
В принципе я вылез из положения но через ж...
И чего-то работает только в среде
а после компиляции - нет
Runtime еррор 10
Array is fixed oder temporary locked
Вот такая фигня

Есть ещё идеи по поводу нормального
решения проблемы ?

Ответить

Номер ответа: 3
Автор ответа:
 Sharp


Лидер форума

ICQ: 216865379 

Вопросов: 106
Ответов: 9979
 Web-сайт: sharpc.livejournal.com
 Профиль | | #3
Добавлено: 04.09.05 15:27
Проверь руки или юзай то, что я набросал минут за 20:
'
' Coded by Sharp (sharp_c[dog]yandex[dot]ru)
' 04.09.2005
'

Private Declare Function GetAdaptersInfo Lib "IPHLPAPI.dll" (ByRef pAdapterInfo As Any, ByRef pOutBufLen As Long) As Long
Private Declare Sub CopyMemoryRR Lib "kernel32.dll" Alias "RtlMoveMemory" (ByRef Destination As Any, ByRef Source As Any, ByVal Length As Long)
Private Declare Sub CopyMemoryRV Lib "kernel32.dll" Alias "RtlMoveMemory" (ByRef Destination As Any, ByVal Source As Any, ByVal Length As Long)

Private Const MAX_ADAPTER_ADDRESS_LENGTH As Long = 8
Private Const MAX_ADAPTER_DESCRIPTION_LENGTH As Long = (128 + 4)
Private Const MAX_ADAPTER_NAME_LENGTH As Long = (256 + 4)
Private Const MAX_IP_STRING_LENGTH As Long = 16

Private Const MIB_IF_TYPE_OTHER As Long = 1
Private Const MIB_IF_TYPE_ETHERNET As Long = 6
Private Const MIB_IF_TYPE_TOKENRING As Long = 9
Private Const MIB_IF_TYPE_FDDI As Long = 15
Private Const MIB_IF_TYPE_PPP As Long = 23
Private Const MIB_IF_TYPE_LOOPBACK As Long = 24
Private Const MIB_IF_TYPE_SLIP As Long = 28


'typedef struct _IP_MASK_STRING{
'    char String[4 * 4];
'};

Private Type IP_MASK_STRING
    s As String * MAX_IP_STRING_LENGTH
End Type

'typedef struct _IP_ADDRESS_STRING{
'    char String[4 * 4];
'};

Private Type IP_ADDRESS_STRING
    s As String * MAX_IP_STRING_LENGTH
End Type

'typedef struct _IP_ADDR_STRING{
'    struct _IP_ADDR_STRING* Next;
'    IP_ADDRESS_STRING IpAddress;
'    IP_MASK_STRING IpMask;
'    ;DWORD Context;
'};

Private Type IP_ADDR_STRING
    lpNext As Long
    IpAddress As IP_ADDRESS_STRING
    IpMask As IP_MASK_STRING
    Context As Long
End Type

'typedef struct _IP_ADAPTER_INFO{
'    struct _IP_ADAPTER_INFO* Next;
'    ;DWORD ComboIndex;
'    char AdapterName[MAX_ADAPTER_NAME_LENGTH + 4];
'    char Description[MAX_ADAPTER_DESCRIPTION_LENGTH + 4];
'    UINT AddressLength;
'    BYTE Address[MAX_ADAPTER_ADDRESS_LENGTH];
'    ;DWORD Index;
'    UINT Type;
'    UINT DhcpEnabled;
'    PIP_ADDR_STRING CurrentIpAddress;
'    IP_ADDR_STRING IpAddressList;
'    IP_ADDR_STRING GatewayList;
'    IP_ADDR_STRING DhcpServer;
'    BOOL HaveWins;
'    IP_ADDR_STRING PrimaryWinsServer;
'    IP_ADDR_STRING SecondaryWinsServer;
'    time_t LeaseObtained;
'    time_t LeaseExpires;
'};

Private Type IP_ADAPTER_INFO
    lpNext As Long
    ComboIndex As Long
    AdapterName As String * MAX_ADAPTER_NAME_LENGTH
    ;Description As String * MAX_ADAPTER_DESCRIPTION_LENGTH
    AddressLength As Long
    Address As String * MAX_ADAPTER_ADDRESS_LENGTH
    Index As Long
    Type As Long
    ;DhcpEnabled As Long
    CurrentIpAddress As Long
    IpAddressList As IP_ADDR_STRING
    GatewayList As IP_ADDR_STRING
    ;DhcpServer As IP_ADDR_STRING
    HaveWins As Integer
    PrimaryWinsServer As IP_ADDR_STRING
    SecondaryWinsServer As IP_ADDR_STRING
    LeaseObtained As Long
    LeaseExpires As Long
End Type


Private Sub Command1_Click()
    Text1 = GetAdaptersInformation()
End Sub

Private Function GetAdaptersInformation() As String
    Dim buff() As Byte
    Dim pLen As Long
    Dim iai As IP_ADAPTER_INFO
    Dim res As String
    Dim lNext As Long
    pLen = 0
    GetAdaptersInfo Null, pLen
    If pLen = 0 Then
        GetAdaptersInformation = "No adapters" & vbCrLf
    Else
        ReDim buff(pLen)
        GetAdaptersInfo buff(0), pLen
        CopyMemoryRR iai, buff(0), 640
        res = res & GetAdapterInformation(iai)
        Do While iai.lpNext <> 0
            lNext = iai.lpNext
            CopyMemoryRV iai, lNext, 640
            res = res & GetAdapterInformation(iai)
        Loop
        GetAdaptersInformation = res
    End If
End Function

Private Function GetAdapterInformation(iai As IP_ADAPTER_INFO) As String
    Dim res As String
    res = res & "Adapter: " & sz2String(iai.AdapterName) & vbCrLf
    res = res & ";Description: " & sz2String(iai.Description) & vbCrLf
    res = res & "Phys.address: " & String2PhysAddr(iai.Address, iai.AddressLength) & vbCrLf
    res = res & "Index: " & CStr(iai.Index) & vbCrLf
    Select Case iai.Type
        Case MIB_IF_TYPE_OTHER:     res = res & "Type: Other" & vbCrLf
        Case MIB_IF_TYPE_ETHERNET:  res = res & "Type: Ethernet" & vbCrLf
        Case MIB_IF_TYPE_TOKENRING: res = res & "Type: TokenRing" & vbCrLf
        Case MIB_IF_TYPE_FDDI:      res = res & "Type: FDDI" & vbCrLf
        Case MIB_IF_TYPE_PPP:       res = res & "Type: PPP" & vbCrLf
        Case MIB_IF_TYPE_LOOPBACK:  res = res & "Type: Loopback" & vbCrLf
        Case MIB_IF_TYPE_SLIP:      res = res & "Type: SLIP" & vbCrLf
    End Select
    res = res & ";DHCP server: "
    If iai.DhcpEnabled Then
        res = res & sz2String(iai.DhcpServer.IpAddress.s) & vbCrLf
        res = res & ";DHCP obtained: " & CStr(DateAdd("s", iai.LeaseObtained, "01.01.1970";)) & vbCrLf
        res = res & ";DHCP expires: " & CStr(DateAdd("s", iai.LeaseExpires, "01.01.1970";)) & vbCrLf
    Else
        res = res & "No" & vbCrLf
    End If
    res = res & ";Default gateway: " & sz2String(iai.GatewayList.IpAddress.s) & vbCrLf
    res = res & "IP address: " & GetIPList(iai.IpAddressList) & vbCrLf
    res = res & "WINS: "
    If iai.HaveWins Then
        res = res & "primary - " & sz2String(iai.PrimaryWinsServer.IpAddress.s) & "; " & _
                    "secondary - " & sz2String(iai.PrimaryWinsServer.IpAddress.s) & vbCrLf
    Else
        res = res & "No" & vbCrLf
    End If
    GetAdapterInformation = res & vbCrLf
End Function

Private Function String2PhysAddr(Addr As String, AddrLen As Long)
    Dim res As String
    Dim s As String
    For i = 1 To AddrLen
        s = Hex(Asc(Mid(Addr, i, 1)))
        res = res & IIf(Len(s) = 1, "0", "";) & s & "-"
    Next
    String2PhysAddr = Left(res, Len(res) - 1)
End Function

Private Function GetIPList(ipl As IP_ADDR_STRING) As String
    Dim lNext As Long
    Dim res As String
    Dim ias As IP_ADDR_STRING
    CopyMemoryRR ias, ipl, 40
    res = res & sz2String(ias.IpAddress.s) & "/" & sz2String(ias.IpMask.s) & "; "
    Do While ias.lpNext <> 0
        lNext = ias.lpNext
        CopyMemoryRV ias, lNext, 40
        res = res & sz2String(ias.IpAddress.s) & "/" & sz2String(ias.IpMask.s) & "; "
    Loop
    GetIPList = Left(res, Len(res) - 2)
End Function

Private Function sz2String(s As String) As String
    sz2String = Left(s, InStr(s, vbNullChar) - 1)
End Function

Ответить

Номер ответа: 4
Автор ответа:
 student-uni



Вопросов: 122
Ответов: 257
 Профиль | | #4 Добавлено: 04.09.05 16:53
Ма-ма!

Но работает!

Спасибо большое. Пошёл разбираться.

Ответить

Номер ответа: 5
Автор ответа:
 student-uni



Вопросов: 122
Ответов: 257
 Профиль | | #5 Добавлено: 09.09.05 21:46
Ещё вопросик можно ?

я перегоняю на дот Нет и у меня проблема,

подскажи, где почитать про CopyMemoryRR и RV Lib "kernel32.dll"

дело в том, что any в дот нете НЕТ /извините за каламбур/

вместо него мне надо указать что в качестве
аргумента будет структура.
Это хорошо проходит с

GetAdaptersInfo Lib "IPHLPAPI.dll" (ByRef pAdapterInfo As /и вместо ЭНИ - IP_ADAPTER_INFO/

Но в случае с CopyMemoryRR ты даёшь ей на вход разные структуры, сначала IP_ADAPTER_INFO, а потом IP_ADDRESS_STRING . Тебе это позволяет ЭНИ.
Но у меня ЭНИ нет. Как думаешь, как правильно
задекларировать CopyMemoryRR ?



Ответить

Номер ответа: 6
Автор ответа:
 Sharp


Лидер форума

ICQ: 216865379 

Вопросов: 106
Ответов: 9979
 Web-сайт: sharpc.livejournal.com
 Профиль | | #6
Добавлено: 10.09.05 03:08
С дотнетом не работал, но там наверняка есть специальный класс для этого дела, который можно найти часа за 2 в MSDN. Рекомендую сделать DLL на VB6 и вызывать ее из дотнета.

Ответить

Номер ответа: 7
Автор ответа:
 Sharp


Лидер форума

ICQ: 216865379 

Вопросов: 106
Ответов: 9979
 Web-сайт: sharpc.livejournal.com
 Профиль | | #7
Добавлено: 17.09.05 06:11
Нашел случайно: KB223025

Ответить

Номер ответа: 8
Автор ответа:
 Mr.Smile



ICQ: 427682013 

Вопросов: 14
Ответов: 464
 Профиль | | #8 Добавлено: 24.04.12 23:29
Допилил код Sharp'а (неправильно выводился MAC-адрес устройств)
(внести изменения в тот, что вверху от 04.09.05 15:27)
  1. Type IP_ADAPTER_INFO
  2.     '<прежний код>
  3.     Address(MAX_ADAPTER_ADDRESS_LENGTH - 1) As Byte
  4.     '<прежний код>
  5. End Type
  6.  
  7. Private Function GetAdapterInformation(tIAI As IP_ADAPTER_INFO) As String
  8.     '<прежний код>
  9.     res = res & "Phys.address: " & String2PhysAddr(tIAI.Address(), tIAI.AddressLength) & vbCrLf
  10.     '<прежний код>
  11. End Function
  12.  
  13. Private Function String2PhysAddr(Addr() As Byte, AddrLen As Long)
  14.     Dim res As String
  15.     Dim s As String
  16.     Dim i As Integer
  17.     For i = 1 To AddrLen - 1
  18.         s = Hex(Addr(i))
  19.         res = res & IIf(Len(s) = 1, "0" & s, s)
  20.         If i < AddrLen - 1 Then
  21.             res = res & "-"
  22.         End If
  23.     Next
  24.     String2PhysAddr = res
  25. End Function

Ответить

Номер ответа: 9
Автор ответа:
 Mr.Smile



ICQ: 427682013 

Вопросов: 14
Ответов: 464
 Профиль | | #9 Добавлено: 24.04.12 23:39
Поправка: в функции String2PhysAddr For i = 0, а не 1!

Ответить

Страница: 1 |

Поиск по форуму



© Copyright 2002-2011 VBNet.RU | Пишите нам