GetIfTable2 - wie funktionierts richtig?

Windowsspezifisches Forum , API ,..
Beiträge, die plattformübergreifend sind, gehören ins 'Allgemein'-Forum.
freak
PureBasic Team
Beiträge: 766
Registriert: 29.08.2004 00:20
Wohnort: Stuttgart

Re: GetIfTable2 - wie funktionierts richtig?

Beitrag von freak »

Man kann das in C (zumindest bei VC) angeben weches alignment eine struktur braucht. Der Compiler stellt dann sicher das das auch bei Verwendungen in anderen Strukturen korrekt bleibt. Desshalb gibt es keine feste Regel.

Bei x64 sind standardmäßig alle Typen >=8 an 8-Byte-Grenzen ausgerichtet, bei x86 ist das nicht immer so.

Im Zweifelsfall muss man sich eben die Header ansehen und schauen wie die Typen definiert sind, wenn das dann nicht zu der Größe der Struktur passt dann gibt es irgendwo padding. NET_IF_CONNECTION_TYPE ist zum Beispiel eine Enumeration, die haben normalerweise immer 32bit.

Man kann auch den Code von DarkDragon erweitern das er zu jedem Feld Offset und Größe ausgiebt, dann sieht man das padding sofort.
GPI
Beiträge: 1511
Registriert: 29.08.2004 13:18
Kontaktdaten:

Re: GetIfTable2 - wie funktionierts richtig?

Beitrag von GPI »

Irgendwie hab ich sowas geahnt. Ist schon irgendwie lustig bei C - es ist standardisiert und trotzdem verhalten sich alle anders ;)

Zumindest weis ich in Zukunft, wo ich suchen muss.

Falls es wer braucht: Hier mein Code (ermittelt den Traffic der einzelnen Netzwerkadaptern - lauffähig ab vista)

Code: Alles auswählen

Global iphlpapi.l
Procedure GetIfTable2(a)
  iphlpapi=OpenLibrary(#PB_Any,"Iphlpapi.dll")
  ProcedureReturn CallFunction(iphlpapi,"GetIfTable2",a)  
EndProcedure
Procedure  FreeMibTable(a)
  a=CallFunction(iphlpapi,"FreeMibTable",a)   
  CloseLibrary(iphlpapi)
  ProcedureReturn a  
EndProcedure

#IF_MAX_STRING_SIZE    = 256
#IF_MAX_PHYS_ADDRESS_LENGTH =32

Structure MIB_IF_ROW2 
  InterfaceLuid.q ; Ein Quad    0
  InterfaceIndex.l             ;8
  InterfaceGuid.b[4+2+2+8]     ;12
  Alias.u[#IF_MAX_STRING_SIZE +1];28
  Description.u[#IF_MAX_STRING_SIZE +1];542
  PhysicalAddressLength.l;1056
  PhysicalAddress.b[#IF_MAX_PHYS_ADDRESS_LENGTH];1060
  PermanentPhysicalAddress.b[#IF_MAX_PHYS_ADDRESS_LENGTH];1092
  Mtu.l;1124
  Type.l;1128
  TunnelType.l;1132
  MediaType.l;1136
  PhysicalMediumType.l;1140
  AccessType.l;1144
  DirectionType.l;1148
  InterfaceAndOperStatusFlags.l;1152
  ;   #struct {
  ;     BOOLEAN HardwareInterface  :1;
  ;     BOOLEAN FilterInterface  :1;
  ;     BOOLEAN ConnectorPresent   :1;
  ;     BOOLEAN NotAuthenticated  :1;
  ;     BOOLEAN NotMediaConnected  :1;
  ;     BOOLEAN Paused  :1;
  ;     BOOLEAN LowPower  :1;
  ;     BOOLEAN EndPointInterface  :1;
  ;   } InterfaceAndOperStatusFlags;
  OperStatus.l;1156
  AdminStatus.l;1160
  MediaConnectState.l;1164
  NetworkGuid.b[4+2+2+8];1168
  ConnectionType.l;1184 - QUAD?!
  dummydata1.l
  TransmitLinkSpeed.q;1192
  ReceiveLinkSpeed.q;1200
  InOctets.q;
  InUcastPkts.q;
  InNUcastPkts.q;
  InDiscards.q;
  InErrors.q;
  InUnknownProtos.q;
  InUcastOctets.q;
  InMulticastOctets.q;
  InBroadcastOctets.q;
  OutOctets.q;
  OutUcastPkts.q;
  OutNUcastPkts.q;
  OutDiscards.q;
  OutErrors.q;
  OutUcastOctets.q;
  OutMulticastOctets.q;
  OutBroadcastOctets.q;
  OutQLen.q;
  
EndStructure

Structure Traffic
  Name.s
  Traffic.q
EndStructure


Procedure.s FormatByte(a)
  If a<1024
    ProcedureReturn Str(a)+" B"
  Else
    b.f=a/1024.
    If b<1024
      ProcedureReturn StrF(b,2)+" KB"
    Else
      b.f/1024.
      ProcedureReturn StrF(b,2)+" MB"
    EndIf
  EndIf
EndProcedure

Procedure GetTraffic(List traffic.traffic())
  ClearList(traffic())
  buf.l
  If GetIfTable2(@buf)=#ERROR_SUCCESS
    count=PeekL(buf)
    *line.mib_if_row2=buf+8;<- eigentlich müßte es+4 heißen, aber dann stimmt was nicht!
    gesamt.q=0
    For i=1 To count
      If (*line\InterfaceAndOperStatusFlags &1)
        ;  Debug "----"
        ;Debug "index:"+Str(*line\InterfaceIndex)
        
        
        ;Debug Bin(*line\InterfaceAndOperStatusFlags)
        ;Debug PeekS(@*line\Description,#IF_MAX_STRING_SIZE,#PB_Unicode)
        AddElement(traffic())
        traffic()\Name = PeekS(@*line\Alias,#IF_MAX_STRING_SIZE,#PB_Unicode)
        traffic()\traffic=(*line\InOctets+*line\OutOctets)
        gesamt+*line\InOctets+*line\OutOctets
      EndIf
      
      *line+SizeOf(mib_if_row2)  
    Next
    
    AddElement(traffic())
    traffic()\Name = "Gesamt"
    traffic()\Traffic = gesamt
    
    FreeMibTable(buf)
    
  EndIf
EndProcedure
CodeArchiv Rebirth: Deutsches Forum Github Hilfe ist immer gern gesehen!
DarkDragon
Beiträge: 6291
Registriert: 29.08.2004 08:37
Computerausstattung: Hoffentlich bald keine mehr
Kontaktdaten:

Re: GetIfTable2 - wie funktionierts richtig?

Beitrag von DarkDragon »

Damit nun alle Unklarheiten beseitigt sind: :mrgreen:

Code: Alles auswählen

Element                          Offset   Size
InterfaceLuid                         0      8
InterfaceIndex                        8      4
InterfaceGuid                        12     16
Alias                                28    514
Description                         542    514
PhysicalAddressLength              1056      4
PhysicalAddress                    1060     32
PermanentPhysicalAddress           1092     32
Mtu                                1124      4
Type                               1128      4
TunnelType                         1132      4
MediaType                          1136      4
PhysicalMediumType                 1140      4
AccessType                         1144      4
DirectionType                      1148      4
InterfaceAndOperStatusFlags        1152      1
OperStatus                         1156      4
AdminStatus                        1160      4
MediaConnectState                  1164      4
NetworkGuid                        1168     16
ConnectionType                     1184      4
TransmitLinkSpeed                  1192      8
ReceiveLinkSpeed                   1200      8
InOctets                           1208      8
InUcastPkts                        1216      8
InNUcastPkts                       1224      8
InDiscards                         1232      8
InErrors                           1240      8
InUnknownProtos                    1248      8
InUcastOctets                      1256      8
InMulticastOctets                  1264      8
InBroadcastOctets                  1272      8
OutOctets                          1280      8
OutUcastPkts                       1288      8
OutNUcastPkts                      1296      8
OutDiscards                        1304      8
OutErrors                          1312      8
OutUcastOctets                     1320      8
OutMulticastOctets                 1328      8
OutBroadcastOctets                 1336      8
OutQLen                            1344      8
Drücken Sie eine beliebige Taste . . .
Mit dem hier generiert:

Code: Alles auswählen

int main(int argc, char* argv[])
{
    printf("Element                          Offset   Size\n");
    printf("InterfaceLuid                    %6d %6d\n", offsetof(MIB_IF_ROW2, InterfaceLuid), sizeof(((MIB_IF_ROW2*)(NULL))->InterfaceLuid));
    printf("InterfaceIndex                   %6d %6d\n", offsetof(MIB_IF_ROW2, InterfaceIndex), sizeof(((MIB_IF_ROW2*)(NULL))->InterfaceIndex));
    printf("InterfaceGuid                    %6d %6d\n", offsetof(MIB_IF_ROW2, InterfaceGuid), sizeof(((MIB_IF_ROW2*)(NULL))->InterfaceGuid));
    printf("Alias                            %6d %6d\n", offsetof(MIB_IF_ROW2, Alias), sizeof(((MIB_IF_ROW2*)(NULL))->Alias));
    printf("Description                      %6d %6d\n", offsetof(MIB_IF_ROW2, Description), sizeof(((MIB_IF_ROW2*)(NULL))->Description));
    printf("PhysicalAddressLength            %6d %6d\n", offsetof(MIB_IF_ROW2, PhysicalAddressLength), sizeof(((MIB_IF_ROW2*)(NULL))->PhysicalAddressLength));
    printf("PhysicalAddress                  %6d %6d\n", offsetof(MIB_IF_ROW2, PhysicalAddress), sizeof(((MIB_IF_ROW2*)(NULL))->PhysicalAddress));
    printf("PermanentPhysicalAddress         %6d %6d\n", offsetof(MIB_IF_ROW2, PermanentPhysicalAddress), sizeof(((MIB_IF_ROW2*)(NULL))->PermanentPhysicalAddress));
    printf("Mtu                              %6d %6d\n", offsetof(MIB_IF_ROW2, Mtu), sizeof(((MIB_IF_ROW2*)(NULL))->Mtu));
    printf("Type                             %6d %6d\n", offsetof(MIB_IF_ROW2, Type), sizeof(((MIB_IF_ROW2*)(NULL))->Type));
    printf("TunnelType                       %6d %6d\n", offsetof(MIB_IF_ROW2, TunnelType), sizeof(((MIB_IF_ROW2*)(NULL))->TunnelType));
    printf("MediaType                        %6d %6d\n", offsetof(MIB_IF_ROW2, MediaType), sizeof(((MIB_IF_ROW2*)(NULL))->MediaType));
    printf("PhysicalMediumType               %6d %6d\n", offsetof(MIB_IF_ROW2, PhysicalMediumType), sizeof(((MIB_IF_ROW2*)(NULL))->PhysicalMediumType));
    printf("AccessType                       %6d %6d\n", offsetof(MIB_IF_ROW2, AccessType), sizeof(((MIB_IF_ROW2*)(NULL))->AccessType));
    printf("DirectionType                    %6d %6d\n", offsetof(MIB_IF_ROW2, DirectionType), sizeof(((MIB_IF_ROW2*)(NULL))->DirectionType));
    printf("InterfaceAndOperStatusFlags      %6d %6d\n", offsetof(MIB_IF_ROW2, InterfaceAndOperStatusFlags), sizeof(((MIB_IF_ROW2*)(NULL))->InterfaceAndOperStatusFlags));
    printf("OperStatus                       %6d %6d\n", offsetof(MIB_IF_ROW2, OperStatus), sizeof(((MIB_IF_ROW2*)(NULL))->OperStatus));
    printf("AdminStatus                      %6d %6d\n", offsetof(MIB_IF_ROW2, AdminStatus), sizeof(((MIB_IF_ROW2*)(NULL))->AdminStatus));
    printf("MediaConnectState                %6d %6d\n", offsetof(MIB_IF_ROW2, MediaConnectState), sizeof(((MIB_IF_ROW2*)(NULL))->MediaConnectState));
    printf("NetworkGuid                      %6d %6d\n", offsetof(MIB_IF_ROW2, NetworkGuid), sizeof(((MIB_IF_ROW2*)(NULL))->NetworkGuid));
    printf("ConnectionType                   %6d %6d\n", offsetof(MIB_IF_ROW2, ConnectionType), sizeof(((MIB_IF_ROW2*)(NULL))->ConnectionType));
    printf("TransmitLinkSpeed                %6d %6d\n", offsetof(MIB_IF_ROW2, TransmitLinkSpeed), sizeof(((MIB_IF_ROW2*)(NULL))->TransmitLinkSpeed));
    printf("ReceiveLinkSpeed                 %6d %6d\n", offsetof(MIB_IF_ROW2, ReceiveLinkSpeed), sizeof(((MIB_IF_ROW2*)(NULL))->ReceiveLinkSpeed));
    printf("InOctets                         %6d %6d\n", offsetof(MIB_IF_ROW2, InOctets), sizeof(((MIB_IF_ROW2*)(NULL))->InOctets));
    printf("InUcastPkts                      %6d %6d\n", offsetof(MIB_IF_ROW2, InUcastPkts), sizeof(((MIB_IF_ROW2*)(NULL))->InUcastPkts));
    printf("InNUcastPkts                     %6d %6d\n", offsetof(MIB_IF_ROW2, InNUcastPkts), sizeof(((MIB_IF_ROW2*)(NULL))->InNUcastPkts));
    printf("InDiscards                       %6d %6d\n", offsetof(MIB_IF_ROW2, InDiscards), sizeof(((MIB_IF_ROW2*)(NULL))->InDiscards));
    printf("InErrors                         %6d %6d\n", offsetof(MIB_IF_ROW2, InErrors), sizeof(((MIB_IF_ROW2*)(NULL))->InErrors));
    printf("InUnknownProtos                  %6d %6d\n", offsetof(MIB_IF_ROW2, InUnknownProtos), sizeof(((MIB_IF_ROW2*)(NULL))->InUnknownProtos));
    printf("InUcastOctets                    %6d %6d\n", offsetof(MIB_IF_ROW2, InUcastOctets), sizeof(((MIB_IF_ROW2*)(NULL))->InUcastOctets));
    printf("InMulticastOctets                %6d %6d\n", offsetof(MIB_IF_ROW2, InMulticastOctets), sizeof(((MIB_IF_ROW2*)(NULL))->InMulticastOctets));
    printf("InBroadcastOctets                %6d %6d\n", offsetof(MIB_IF_ROW2, InBroadcastOctets), sizeof(((MIB_IF_ROW2*)(NULL))->InBroadcastOctets));
    printf("OutOctets                        %6d %6d\n", offsetof(MIB_IF_ROW2, OutOctets), sizeof(((MIB_IF_ROW2*)(NULL))->OutOctets));
    printf("OutUcastPkts                     %6d %6d\n", offsetof(MIB_IF_ROW2, OutUcastPkts), sizeof(((MIB_IF_ROW2*)(NULL))->OutUcastPkts));
    printf("OutNUcastPkts                    %6d %6d\n", offsetof(MIB_IF_ROW2, OutNUcastPkts), sizeof(((MIB_IF_ROW2*)(NULL))->OutNUcastPkts));
    printf("OutDiscards                      %6d %6d\n", offsetof(MIB_IF_ROW2, OutDiscards), sizeof(((MIB_IF_ROW2*)(NULL))->OutDiscards));
    printf("OutErrors                        %6d %6d\n", offsetof(MIB_IF_ROW2, OutErrors), sizeof(((MIB_IF_ROW2*)(NULL))->OutErrors));
    printf("OutUcastOctets                   %6d %6d\n", offsetof(MIB_IF_ROW2, OutUcastOctets), sizeof(((MIB_IF_ROW2*)(NULL))->OutUcastOctets));
    printf("OutMulticastOctets               %6d %6d\n", offsetof(MIB_IF_ROW2, OutMulticastOctets), sizeof(((MIB_IF_ROW2*)(NULL))->OutMulticastOctets));
    printf("OutBroadcastOctets               %6d %6d\n", offsetof(MIB_IF_ROW2, OutBroadcastOctets), sizeof(((MIB_IF_ROW2*)(NULL))->OutBroadcastOctets));
    printf("OutQLen                          %6d %6d\n", offsetof(MIB_IF_ROW2, OutQLen), sizeof(((MIB_IF_ROW2*)(NULL))->OutQLen)); 

    system("PAUSE");
    return 0;
}
Gibts dafür eigentlich keine Definitionsdateien wo man nicht erst alle includes abklappern muss?

Und noch was: für GUIDs gibts doch in PB bereits ne Struktur oder nicht? Das wär doch irgendwie sinnvoller als ein byte-array.
Angenommen es gäbe einen Algorithmus mit imaginärer Laufzeit O(i * n), dann gilt O((i * n)^2) = O(-1 * n^2) d.h. wenn man diesen Algorithmus verschachtelt ist er fertig, bevor er angefangen hat.
DarkDragon
Beiträge: 6291
Registriert: 29.08.2004 08:37
Computerausstattung: Hoffentlich bald keine mehr
Kontaktdaten:

Re: GetIfTable2 - wie funktionierts richtig?

Beitrag von DarkDragon »

Hallo,

Ich hab noch was hierfür gefunden das dürfte evtl. allen helfen:
Wenn man im Microsoft Visual C++ 9.0 (dürfte auch bei anderen Versionen gehen) sowas aufruft:

Code: Alles auswählen

cl.exe /reportAllClassLayout test.cpp
werden alle Struktur- und Klassenmitglieder der inkludierten Klassen/Strukturen mit Offset ausgegeben.

Beispielsweise:

Code: Alles auswählen

class CBaseStreamControl    size(104):
    +---
    | +--- (base class IAMStreamControl)
    | | +--- (base class IUnknown)
 0    | | | {vfptr}
    | | +---
    | +---
 4    | StreamControlState m_StreamState
 8    | StreamControlState m_StreamStateOnStop
      | <alignment member> (size=4)
16    | m_tStartTime
24    | m_tStopTime
32    | m_dwStartCookie
36    | m_dwStopCookie
40    | m_bIsFlushing
44    | m_bStopSendExtra
48    | m_bStopExtraSent
52    | CCritSec m_CritSec
76    | CAMEvent m_StreamEvent
80    | m_pRefClock
84    | m_pSink
88    | _FilterState m_FilterState
      | <alignment member> (size=4)
96    | m_tRunStart
    +---

class __s_GUID    size(16):
    +---
 0    | Data1
 4    | Data2
 6    | Data3
 8    | Data4
    +---
Ich glaube kaum dass GUID eine Klasse ist. Desshalb steht wohl auch __s_ davor.
Angenommen es gäbe einen Algorithmus mit imaginärer Laufzeit O(i * n), dann gilt O((i * n)^2) = O(-1 * n^2) d.h. wenn man diesen Algorithmus verschachtelt ist er fertig, bevor er angefangen hat.
Antworten