-
tytus (03.02.10 12:11) [0]Добрый день мастера.
С функциейGetIFTable (MIB_IF_ROW)
проблем нет.
Вот как я объявил соотв. типы:NET_LUID = record
case Integer of
0: (Value: DWORD); //UInt64 --> DWORD
1: (Reserved: DWORD; NetLuidIndex: DWORD; IfType: DWORD);
end;NET_IFINDEX = ULONG;PMIB_IF_ROW2 = ^MIB_IF_ROW2;
MIB_IF_ROW2 = packed record
InterfaceLuid: NET_LUID;
InterfaceIndex: NET_IFINDEX;
InterfaceGuid: TGUID;
Alias: array[0..IF_MAX_STRING_SIZE - 1] of WideChar;
Description: array[0..IF_MAX_STRING_SIZE - 1]of WideChar;
PhysicalAddressLength: ULONG
PhysicalAddress: array[0..IF_MAX_PHYS_ADDRESS_LENGTH - 1] of Byte;
PermanentPhysicalAddress: array[0..IF_MAX_PHYS_ADDRESS_LENGTH- 1]of Byte;
Mtu: Cardinal;
aType: Cardinal;//IFTYPE;
TunnelType: TUNNEL_TYPE;
MediaType: NDIS_MEDIUM;
PhysicalMediumType: NDIS_PHYSICAL_MEDIUM;
AccessType: NET_IF_ACCESS_TYPE;
DirectionType: NET_IF_DIRECTION_TYPE;
InterfaceAndOperStatusFlags: TInterfaceAndOperStatusFlags;
OperStatus: IF_OPER_STATUS;
AdminStatus: NET_IF_ADMIN_STATUS;
MediaConnectState: NET_IF_MEDIA_CONNECT_STATE;
NetworkGuid: TGUID;//NET_IF_NETWORK_GUID;
ConnectionType: NET_IF_CONNECTION_TYPE;
TransmitLinkSpeed: DWORD;//UInt64
ReceiveLinkSpeed: DWORD;
InOctets: DWORD;
InUcastPkts: DWORD;
InNUcastPkts: DWORD;
InDiscards: DWORD;
InErrors: DWORD;
InUnknownProtos: DWORD;
InUcastOctets: DWORD;
InMulticastOctets: DWORD;
InBroadcastOctets: DWORD;
OutOctets: DWORD;
OutUcastPkts: DWORD;
OutNUcastPkts: DWORD;
OutDiscards: DWORD;
OutErrors: DWORD;
OutUcastOctets: DWORD;
OutMulticastOctets: DWORD;
OutBroadcastOctets: DWORD;
OutQLen: DWORD;
end;PMIB_IF_TABLE2 = ^MIB_IF_TABLE2;
MIB_IF_TABLE2 = packed record
NumEntries: DWORD;
Table: array[0..ANY_SIZE - 1] of MIB_IF_ROW2;
end;var IfTable2: PMIB_IF_TABLE2;
res: integer;
hHeap: Cardinal;
begin
hHeap := GetProcessHeap;
IFTable2 := HeapAlloc(hHeap, HEAP_ZERO_MEMORY, buf_size);
res := GetIFTable2(IFTable2);
Каждый раз возвращаются другие значения IfTablwe2^.NumEntries , и всегда нереальные : 360125, 178552 и т.п.
Подскажите, как с этим бороться.)) -
tytus (05.02.10 12:46) [1]... разобрался с вызовом GetIfTable2.
Возвращает правильное кол-во интерфейсов.
Теперь вопрос в следующем.
Как читать записи?for i := 0 to IFTable2^.NumEntries - 1 do
begin
Log(IfTable2^.Table[i].Description);
end;
Так вот - или пустая строка, или неверное имя, к примеру
"iniport IP(v6)"
В доке сказано:
> Note that the returned MIB_IF_TABLE2 structure pointed to
> by the Table parameter may contain padding for alignment
> between the NumEntries member and the first MIB_IF_ROW2
> array entry in the Table member of the MIB_IF_TABLE2 structure.
>
Какя понял - речь идет о смещении для выравнивания между значением NumEntries и первым элементом массива MIB_IF_TABLE2.
Что за смещение и чему оно равно ??? -
Vladimir komissarov (12.02.10 14:34) [2]Здравствуйте, я сейчас столкнулся с проблемой getiftable и w7
и случайно попал сюда. Не могли бы Вы просветить как использовать getiftable2 для подсчета трафика? Заранее благодарен -
Vladimir komissarov (16.02.10 11:23) [3]tytus - здрвствуйте, у меня тоже NumEntries не работает, может я наступаю на те же грабли что и ты?
var
GetIfTable2:function(pIfTable2 : PMIB_IF_TABLE2): DWORD; stdcall;
// функция возвращает имя интерфейса по номеру
function tmrGetAdapters2(var InterfaceName: string; AdapterIndex : DWORD) : boolean;
implementation
function tmrGetAdapters2(var InterfaceName: string; AdapterIndex : DWORD) : boolean;
var
FLibHandle : THandle;
Table2: MIB_IF_TABLE2;
begin
Result := false;
FLibHandle := LoadLibrary('IPHLPAPI.DLL');
if FLibHandle = 0 then Exit;
@GetIfTable2 := GetProcAddress(FLibHandle, 'GetIfTable2');
if not Assigned(GetIfTable2) then
begin
FreeLibrary(FLibHandle);
Exit;
end;
if (GetIfTable2(@Table2) = 0) and
(AdapterIndex <= @Table2.NumEntries-1) then
begin
InterfaceName := String(@Table2.Table[AdapterIndex].Description);
Result := true
end
else Result := false;
FreeLibrary(FLibHandle);
end;
procedure TFormMain.ComboBox1Enter(Sender: TObject);
var i : integer;
IntName : string;
begin
with ComboBox1 do
begin
Items.Clear;
i := 0;
while tmrGetAdapters2(IntName, i) do
begin
Items.Add(IntName);
Inc(i);
end
end
end; -
tytus (22.02.10 16:57) [4]>Vladimir komissarov
Вся проблема с вызовом GetIfTable2 заключалась в неправильном описании MIB_IF_TABLE2. Вот правильное описание:PMIB_IF_ROW2 = ^MIB_IF_ROW2;
_MIB_IF_ROW2 = packed record
InterfaceLuid: NET_LUID;
InterfaceIndex: NET_IFINDEX;
InterfaceGuid: TGUID;
Alias: array[0..IF_MAX_STRING_SIZE] of WideChar;
Description: array[0..IF_MAX_STRING_SIZE] of WideChar;
PhysicalAddressLength: Cardinal;
PhysicalAddress: array[0..IF_MAX_PHYS_ADDRESS_LENGTH - 1] of Byte;
PermanentPhysicalAddress: array[0..IF_MAX_PHYS_ADDRESS_LENGTH - 1]of Byte;
Mtu: Cardinal;//ULONG;
aType: Cardinal;
TunnelType: Cardinal;
MediaType: Cardinal;
PhysicalMediumType: Cardinal;
AccessType: Cardinal;
DirectionType: Cardinal;
InterfaceAndOperStatusFlags: Cardinal;// 8 значений, поразрядное ИЛИ TInterfaceAndOperStatusFlags;
OperStatus: Cardinal;
AdminStatus: Cardinal;
MediaConnectState: Cardinal;
NetworkGuid: TGUID;
ConnectionType: Cardinal;
TransmitLinkSpeed: UInt64;
ReceiveLinkSpeed: UInt64;
InOctets: UInt64;
InUcastPkts: UInt64;
InNUcastPkts: UInt64;
InDiscards: UInt64;
InErrors: UInt64;
InUnknownProtos: UInt64;
InUcastOctets: UInt64;
InMulticastOctets: UInt64;
InBroadcastOctets: UInt64;
OutOctets: UInt64;
OutUcastPkts: UInt64;
OutNUcastPkts: UInt64;
OutDiscards: UInt64;
OutErrors: UInt64;
OutUcastOctets: UInt64;
OutMulticastOctets: UInt64;
OutBroadcastOctets: UInt64;
OutQLen: UInt64;
end;
MIB_IF_ROW2 = _MIB_IF_ROW2;
TMibIfRow2 = MIB_IF_ROW2;
PMibIfRow2 = PMIB_IF_ROW2;
TMibIfArray2 = array [0..ANY_SIZE - 1] of TMibIfRow2;
PMibIfArray2 = ^TMibIfArray2;
PMIB_IF_TABLE2 = ^MIB_IF_TABLE2;
_MIB_IF_TABLE2 = packed record
NumEntries: Cardinal;
Table: array[0..ANY_SIZE - 1] of _MIB_IF_ROW2;
end;
MIB_IF_TABLE2 = _MIB_IF_TABLE2;
TMibIfTable2 = MIB_IF_TABLE2;
PMibIfTable2 = PMIB_IF_TABLE2;
Збило меня с толку описание InterfaceAndOperStatusFlags в MSDN-е описано как структура из 8-ми элементов типа boolean. Вот я и думал - что это запись, а оказалось - простой Cardinal. Легко проверить и соотв. флаги - выдернуть патч-корд и посмотреть что изменилось!
На счет - GetIfEntry2 - пока не осилил. Возвращает или 87 (параметр задан неверно) или 2 - не знаю, что за ошибка. Посему нужный адаптер можно выбрать какIfTable2^.Table[Нужный адаптер];
Ну и в флаге InterfaceAndOperStatusFlags можно смотреть - аппаратный-ли интерфейс или логический.
Пишу на Delphi 2010 под Windows7.
Удачи. Напиши что получилось.
Вообще-то я написал свой IpHelper.pas, кое-что стянул из джедаев, кое-что - из родного MSDN. Если что - пиши в форум.
P.S. IF_MAX_STRING_SIZE = 256. Итого - от 0.. до ..256 = 257 Символов в UNICODE.
IF_MAX_PHYS_ADDRESS_LENGTH = 32. -
tytus (22.02.10 17:03) [5]>Vladimir komissarov
На счет подсчета трафика.
Там значения в UInt64.
Я делал так:function IfBytesToStr(aValue: UInt64): string;
var
int_value: Int64;
begin
int_value := Int64Rec(aValue).Hi + Int64Rec(aValue).Lo;
if Int64(int_value) = 0 then
Result := '0 байт'
else
if Int64(int_value) < 100 then
Result := IntToStr(int_value) + ' байт'
else
Result := FormatFloat('0,00', int_value) + ' байт';
end;
Передавать нужноOutUcastOctets
иInUcastOctets
, тогда значения будут точно такие-же как в свойствах сетевого подключения.
Напишите результаты. -
Vladimir komissarov (24.02.10 15:54) [6]Спасибо, попробую и отпишу
-
ddrzhivago (19.03.10 17:57) [7]tytus
Mozhete privesti polnii kod kak opredelit fizicheskie MAC adresa? chto-to u menia ne poluchaetsia (u menia delphi2009 i win7 tozhe) -
tytus (31.03.10 14:20) [8]> ddrzhivago (19.03.10 17:57) [7]
MAC-адреса записаны в полях
PhysicalAddress
и
PermanentPhysicalAddress
Это массивы Unicode символов. D12 нормально должен "понять".
PhysicalAddressLength - длина массива (кол-во символов).
Если = 0 - то и MAC-адреса нету.
На вскидку не помню, а проверить в данный момент времени немогу. -
Aidar (15.01.11 07:21) [9]est' primery na Delphi???????????//