Страница: 1 |
Страница: 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-сайт:
Профиль | | #1
Добавлено: 04.09.05 13:00
Там же написано - AdapterInfo.Next - адрес следующего блока, а в MSDN и пример есть:
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-сайт:
Профиль | | #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;
'  WORD 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;
'  WORD ComboIndex;
' char AdapterName[MAX_ADAPTER_NAME_LENGTH + 4];
' char Description[MAX_ADAPTER_DESCRIPTION_LENGTH + 4];
' UINT AddressLength;
' BYTE Address[MAX_ADAPTER_ADDRESS_LENGTH];
'  WORD 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
 escription As String * MAX_ADAPTER_DESCRIPTION_LENGTH
AddressLength As Long
Address As String * MAX_ADAPTER_ADDRESS_LENGTH
Index As Long
Type As Long
 hcpEnabled As Long
CurrentIpAddress As Long
IpAddressList As IP_ADDR_STRING
GatewayList As IP_ADDR_STRING
 hcpServer 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 & "escription: " & 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 & "HCP server: "
If iai.DhcpEnabled Then
res = res & sz2String(iai.DhcpServer.IpAddress.s) & vbCrLf
res = res & "HCP obtained: " & CStr(DateAdd("s", iai.LeaseObtained, "01.01.1970") & vbCrLf
res = res & "HCP expires: " & CStr(DateAdd("s", iai.LeaseExpires, "01.01.1970") & vbCrLf
Else
res = res & "No" & vbCrLf
End If
res = res & "efault 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-сайт:
Профиль | | #6
Добавлено: 10.09.05 03:08
С дотнетом не работал, но там наверняка есть специальный класс для этого дела, который можно найти часа за 2 в MSDN. Рекомендую сделать DLL на VB6 и вызывать ее из дотнета.
Номер ответа: 7
Автор ответа:
Sharp
Лидер форума
ICQ: 216865379
Вопросов: 106
Ответов: 9979
Web-сайт:
Профиль | | #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)
Номер ответа: 9
Автор ответа:
Mr.Smile
ICQ: 427682013
Вопросов: 14
Ответов: 464
Профиль | | #9
Добавлено: 24.04.12 23:39
Поправка: в функции String2PhysAddr For i = 0, а не 1!