Код:
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] 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;
<...>
GetIfEntry2: function(var pIfRow2 : PMibIfRow2): DWORD; stdcall;
FLibHandle := LoadLibrary('IpHlpAPI.DLL');
@GetIfTable2 := GetProcAddress(FLibHandle, 'GetIfTable2');
@GetIfEntry2 := GetProcAddress(FLibHandle, 'GetIfEntry2');
// Выделяем память для указателей
pIfTable2:=PMIB_IF_TABLE2 (GlobalAlloc(GPTR, SizeOf(MIB_IF_TABLE2)));
if (pIfTable2=nil) then Memo1.Lines.Add('Ошибка при выделении памяти под GetIfTable2!');
...
//инициализация GetIfTable2 чтобы получить размер dwSize
dwSize:=sizeof(MIB_IF_TABLE2);
resultat:=GetIfTable2(pIfTable2);
if (resultat=ERROR_NOT_ENOUGH_MEMORY) then
begin
GlobalFree(Cardinal(pIfTable2));
pIfTable2:=PMIB_IF_TABLE2 (GlobalAlloc(GPTR, dwSize));
if (pIfTable2=nil) then Memo1.Lines.Add('Ошибка выделения памяти MIB_IF_TABLE2');
end;
//второй вызов GetIfTable2Ex который должен завершиться без ошибок
resultat:=GetIfTable2(pIfTable2);
if (resultat=NO_ERROR) then
begin
if (pIfTable2.NumEntries>0) then
begin
PIfRow2:=PMIB_IF_ROW2 (GlobalAlloc(GPTR,sizeof(MIB_IF_ROW2)));
if (PIfRow2=nil) then
begin
Memo1.Lines.Add('Ошибка выделения памяти MIB_IF_ROW2');
if (pIfRow2<>nil) then
begin
GlobalFree(Cardinal(pIfTable2));
pIfTable2:=nil;
end
end
end
end
else
begin
oshibka:=GetLastError();
Memo1.Lines.Add('Ошибка при вызове функции GetIfTable2Ex: '+IntToStr(oshibka));
end;
//перебираем все записи в таблице
if pIfTable2.NumEntries>0 then
begin
for I:= 0 to pIfTable2.NumEntries do
GetMem(pIfRow2, SizeOf(MIB_IF_ROW2));
pIfRow2.InterfaceIndex:=pIfTable2.Table[I].InterfaceIndex;
pIfRow2.InterfaceLuid:= pIfTable2.Table[I].InterfaceLuid;
dwRetVal:=GetIfEntry2(pIfRow2);
if (dwRetVal = NO_ERROR) then
begin
if ((pIfRow2.Alias<>nil) and (pIfRow2.aType=IF_TYPE_ETHERNET_CSMACD) and (pIfRow2.PhysicalMediumType = NdisPhysicalMedium802_3) and (pIfRow2.OperStatus=IfOperStatusUp) and (pIfRow2.InterfaceAndOperStatusFlags=1)) then
begin
Memo1.Lines.Add(pIfRow2.Alias);
Memo1.Lines.Add(pIfRow2.Description);
Memo1.Lines.Add(RoundEx(pIfRow2.InOctets/1024/1024,2));
Memo1.Lines.Add(RoundEx(pIfRow2.OutOctets/1024/1024,2));
end;
end
else Memo1.Lines.Add('Ошибка при получении информации GetIfEntry2');
end;
end;
end;
Структура pIfTable2 заполняется и работает, а структура pIfRow2 заполнена нулями при любом значении InterfaceIndex и функция GetIfRow2 выдает ошибку 2: FILE_NOT_FOUND
Не пойму в чем дело, аналогичный код на C++ работает исправно, проверил как на Visual Studio 2012 , так и на Embarcadero C++