Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Netzwerke (https://www.delphipraxis.net/14-netzwerke/)
-   -   Delphi Gateway IP über eine API auslesen? (https://www.delphipraxis.net/818-gateway-ip-ueber-eine-api-auslesen.html)

Thurgen 11. Sep 2002 11:23


Gateway IP über eine API auslesen?
 
Hi,

gibt es eine möglichkeit die Gateway IP über eine API Funktion auszulesen oder sowas? Bisher konnte ich die Gateway IP nur aus der Registry entnehmen, wobei das Problem ist das die Information bei jeder Windows Version woanders steht.

Christian Seehase 11. Sep 2002 11:31

Moin Thurgen,

dazu kannst Du, ab W98/W2K die Api GetAdaptersInfo benutzen.
In den davorliegenden Versionen stehen diese Informationen meines Wissens immer an der gleichen Stelle in der Registry, und können dort direkt ausgelesen werden. (ohne Gewähr, ich kann's gerade nicht nachprüfen)

Thurgen 11. Sep 2002 11:35

hm komisch ich kann GetAdaptersInfo in meiner SDK hilfe von Delphi 5.0 nicht finden. Gibts dazu irgendwo einen BSP code oder sowas?

Daniel 11. Sep 2002 11:42

Hallo,

zwar kein Beispiel-Code aber wenigstens schon mal die Dokumentation: MSDN-Library :: GetAdaptersInfo.

Christian Seehase 11. Sep 2002 11:47

Moin Thurgen,

die API Hilfe von D5 ist, gelinde gesagt, auch antiquarisch ;-)
Für die API empfiehlt es sich immer ein möglichst aktuelles Platform SDK von Microsoft zu benutzen.
Leider habe ich den Link gerade nicht zur Hand, aber wenn Du hier mal nach PSDK suchst, solltest Du ihn finden. Sollte es Deine Internetanbindung nicht ratsam erscheinen lassen das herunterzuladen (ich glaube so ca. 350MB) kannst Du es auch teilweise herunterladen, oder direkt über msdn.microsoft.com nach den aktuellen Informationen suchen.

Funktionen wie GetAdaptersInfo sind auch nicht in Delphi implementiert, so dass man sich diese Funktionen (und dazugehörige Datenstrukturen und Konstanten) selber importieren (deklarieren), bzw. fertige Übersetzungen benutzen muss.

Ich such' derweil nochmal meine Übersetzung raus.

Christian Seehase 11. Sep 2002 12:27

Moin Thurgen,

hier mal ein wenig Übersetzung:

Code:
const
  MAX_ADAPTER_DESCRIPTION_LENGTH = 128; // arb.
  MAX_ADAPTER_NAME_LENGTH        = 256; // arb.
  MAX_ADAPTER_ADDRESS_LENGTH     = 8;  // arb.
  DEFAULT_MINIMUM_ENTITIES       = 32; // arb.
  MAX_HOSTNAME_LEN               = 128; // arb.
  MAX_DOMAIN_NAME_LEN            = 128; // arb.
  MAX_SCOPE_ID_LEN               = 256; // arb.

  // aus ipifcons
  MIB_IF_TYPE_OTHER    = 1;
  MIB_IF_TYPE_ETHERNET = 6;
  MIB_IF_TYPE_TOKENRING = 9;
  MIB_IF_TYPE_FDDI     = 15;
  MIB_IF_TYPE_PPP      = 23;
  MIB_IF_TYPE_LOOPBACK = 24;
  MIB_IF_TYPE_SLIP     = 28;

type
  PIP_ADDRESS_STRING = ^IP_ADDRESS_STRING;
  IP_ADDRESS_STRING =
    packed record
      acString : array [1..16] of Char;
    end;

  PIP_MASK_STRING = ^PIP_MASK_STRING;
  IP_MASK_STRING = IP_ADDRESS_STRING;

  PIP_ADDR_STRING = ^IP_ADDR_STRING;
  IP_ADDR_STRING =
    packed record
      Next     : PIP_ADDR_STRING;
      IpAddress : IP_ADDRESS_STRING;
      IpMask   : IP_MASK_STRING;
      Context  : DWORD;
    end;

  time_t = int64;

  PIP_ADAPTER_INFO = ^IP_ADAPTER_INFO;
  IP_ADAPTER_INFO =
    packed record
      Next               : PIP_ADAPTER_INFO;
      ComboIndex         : DWORD;
      AdapterName        : array [1..MAX_ADAPTER_NAME_LENGTH+4] of Char ;
      Description        : array [1..MAX_ADAPTER_DESCRIPTION_LENGTH+4] of Char;
      AddressLength      : UINT;
      Address            : array [1..MAX_ADAPTER_ADDRESS_LENGTH] of Byte;
      Index              : DWORD;
      dwType             : UINT;
      DhcpEnabled        : UINT;
      CurrentIpAddress   : PIP_ADDR_STRING;
      IpAddressList      : IP_ADDR_STRING;
      GatewayList        : IP_ADDR_STRING;
      DhcpServer         : IP_ADDR_STRING;
      HaveWins           : Boolean;
      PrimaryWinsServer  : IP_ADDR_STRING;
      SecondaryWinsServer : IP_ADDR_STRING;
      LeaseObtained      : time_t;
      LeaseExpires       : time_t;
    end;

type
  TcsGetAdaptersInfo  = function(const pAdapterInfo : PIP_ADAPTER_INFO;const pOutBufLen : PULONG) : DWORD; stdcall;

var
  fDLLLoaded       : Boolean = false;
  hDLL             : DWORD  = 0;
  GetAdaptersInfo  : TcsGetAdaptersInfo = nil;
  pAdapterList     : PIP_ADAPTER_INFO = nil;
  dwLen            : DWORD = 0;
  aaiAdapters      : array of PIP_ADAPTER_INFO;
  iAdapterIndex    : integer = 0;
  fFatalError      : Boolean = false;


initialization
begin
  hDLL := GetModuleHandle('IPHLPAPI.DLL');
  if hDLL = 0 then
  begin
    fDLLLoaded := true;
    hDLL      := LoadLibrary('IPHLPAPI.DLL');
    if hDLL <> 0 then
    begin
      @GetAdaptersInfo := GetProcAddress(hDLL,'GetAdaptersInfo');
      if @GetAdaptersInfo = nil then
      begin
        MessageBox(0,'GetAdaptersInfo nicht gefunden','FEHLER',MB_ICONERROR or MB_OK);
        fFatalError := true;
      end;
    end
    else
    begin
      MessageBox(0,PChar('IPHLPAPI.DLL konnte nicht geladen werden.'+#13#10+SysErrorMessage(GetLastError)+#13#10+IntToStr(GetLastError)),'FEHLER',MB_ICONERROR or MB_OK);
        fFatalError := true;
    end;
  end;
  if fFatalError then
  begin
    exit;
  end;
end;

finalization
begin
  if hDLL <> 0 then
  begin
    if fDLLLoaded then
    begin
      FreeLibrary(hDLL);
    end;
  end;
  if Assigned(pAdapterList) then
  begin
    FreeMem(pAdapterList,dwLen);
  end;
end;

Thurgen 11. Sep 2002 12:36

Uff das sieht ja schon ganz gut aus, nur leider blicke ich da noch nicht so ganz durch da mein letztes Delphi Programm schon ein paar Jahre auf dem Buckel hat.

Wie bekomme ich aus dem Code einen einfach String raus der die Gateway IP enthält? <--N00b :)

MathiasSimmack 11. Sep 2002 15:35

Zitat:

Zitat von Christian Seehase
Leider habe ich den Link gerade nicht zur Hand, ...

Ich aber, steht in meinen Favoriten: http://www.microsoft.com/msdownload/...sdk/sdkupdate/, bzw.
http://www.microsoft.com/msdownload/.../psdk-full.htm

Allerdings muss ich jetzt jemanden anrufen und behaupten, dass er mein bester Kumpel wäre ... er hat nämlich DSL, und ich arbeite noch mit dem PSDK vom Mai. :wink:

Christian Seehase 11. Sep 2002 15:45

Moin Thurgen,

ich hab' mal ein Beispiel zusammengeschraubt.
Wichtig hierbei:
Ich gehe durch sämtliche zurückgegebenen Adapter, und lese dann die Gateways von allen aus, um diese IP dann in die ComboBox zu schreiben, allerdings ohne Zuordnung.

In Abänderung der letzen Info hab' ich die Funktion jetzt statisch importiert. Dass rächt sich z.B. auf einem Rechner, der kein 98/W2K ff hat.

Ich hoffe, Du kommst damit soweit klar, ansonsten wird Dich wohl niemand daran hindern nachzufragen ;-)


Code:
const
  MAX_ADAPTER_DESCRIPTION_LENGTH = 128; // arb.
  MAX_ADAPTER_NAME_LENGTH        = 256; // arb.
  MAX_ADAPTER_ADDRESS_LENGTH     = 8;  // arb.

type
  PIP_ADDRESS_STRING = ^IP_ADDRESS_STRING;
  IP_ADDRESS_STRING =
    packed record
      acString : array [1..16] of Char;
    end;

  PIP_MASK_STRING = ^PIP_MASK_STRING;
  IP_MASK_STRING = IP_ADDRESS_STRING;

  PIP_ADDR_STRING = ^IP_ADDR_STRING;
  IP_ADDR_STRING =
    packed record
      Next     : PIP_ADDR_STRING;
      IpAddress : IP_ADDRESS_STRING;
      IpMask   : IP_MASK_STRING;
      Context  : DWORD;
    end;

  time_t = int64;

  PIP_ADAPTER_INFO = ^IP_ADAPTER_INFO;
  IP_ADAPTER_INFO =
    packed record
      Next               : PIP_ADAPTER_INFO;
      ComboIndex         : DWORD;
      AdapterName        : array [1..MAX_ADAPTER_NAME_LENGTH+4] of Char ;
      Description        : array [1..MAX_ADAPTER_DESCRIPTION_LENGTH+4] of Char;
      AddressLength      : UINT;
      Address            : array [1..MAX_ADAPTER_ADDRESS_LENGTH] of Byte;
      Index              : DWORD;
      dwType             : UINT;
      DhcpEnabled        : UINT;
      CurrentIpAddress   : PIP_ADDR_STRING;
      IpAddressList      : IP_ADDR_STRING;
      GatewayList        : IP_ADDR_STRING;
      DhcpServer         : IP_ADDR_STRING;
      HaveWins           : Boolean;
      PrimaryWinsServer  : IP_ADDR_STRING;
      SecondaryWinsServer : IP_ADDR_STRING;
      LeaseObtained      : time_t;
      LeaseExpires       : time_t;
    end;

function GetAdaptersInfo(const pAdapterInfo : PIP_ADAPTER_INFO;const pOutBufLen : PULONG) : DWORD; stdcall; external 'IPHLPAPI.DLL' name 'GetAdaptersInfo';

implementation

{$R *.DFM}

procedure TfrmMAIN.FormShow(Sender: TObject);

var
  dwResult    : DWORD;
  dwLen       : DWORD;
  pAdapterWork : PIP_ADAPTER_INFO;
  pAdapterList : PIP_ADAPTER_INFO;
  iasWork     : IP_ADDR_STRING;

begin
  pAdapterList := nil;
  dwLen       := 0;
  dwResult    := GetAdaptersInfo(pAdapterList,@dwLen);
  if dwResult = ERROR_BUFFER_OVERFLOW then
  begin
    pAdapterList := AllocMem(dwLen);
    try
      dwResult := GetAdaptersInfo(pAdapterList,@dwLen);
      if dwResult = ERROR_SUCCESS then
      begin
        pAdapterWork := pAdapterList;
        cobGateway.Clear;
        repeat
          iasWork := pAdapterWork.GatewayList;
          while iasWork.Next <> nil do
          begin
            cobGateway.Items.Add(trim(iasWork.IpAddress.acString));
            iasWork := iasWork.Next^;
          end;
          cobGateway.Items.Add(trim(iasWork.IpAddress.acString));
          pAdapterWork := pAdapterWork.Next;
        until pAdapterWork = nil;
        if cobGateway.Items.Count > 0 then
        begin
          cobGateway.ItemIndex := 0;
        end;
      end;
    finally
      FreeMem(pAdapterList,dwLen);
    end;
  end;
end;
@Mathias:
Prima. Ich hab' vor kurzem erst nachgeschaut, und da war erst Mai drin. Dann kann ich heute Abend ja mal das Update einspielen und den Link auf die Middleware Ergänzungen vergessen. Die sollten da jetzt enthalten sein.

Thurgen 11. Sep 2002 22:06

kannst du das bitte gerade mal als kleines bsp Project erstellen und die Datein im Forum posten? Stehe immer noch etwas auf dem Schlauch, das ist mein erstes Delphi Programm das ich seit 3 Jahren wieder mache :)

Christian Seehase 11. Sep 2002 23:17

Moin Thurgen,

kleine Anleitung:
  1. Neue Anwendung
  2. Name Formular frmMAIN
  3. Eine ComboBox auf das Formular ziehen
  4. Name ComboBox cobGateway
  5. Jetzt den Teil meines Beispieles vor implementation an die entsprechende Stelle in Unit1 kopieren
  6. auf die Ereignisse des Formulares
  7. Doppelclick auf OnShow
  8. Den unteren Teil meines Beispieles dort hineinkopieren
  9. fertig

Thurgen 12. Sep 2002 09:25

super vielen dank es hat geklapt. Komisch war nur das er .FormShow nicht genommen hat. Das Programm lief erst nachdem ich .FormCreate benutzt habe.

Also nochmal vielen dank, ihr wart mir echt eine grosse Hilfe. Mit Delphi habe ich bis jetzt noch nie was Programmiert. Nur früher habe ich sehr viel mit Turbo Pascal gearbeitet, aber da gabs noch keine API Funktionen :)

Gruss,

Michael

PS: eine API die mir schnell und einfach den Namen der Grafikkarte zurück gibt habt ihr nicht auch noch im ärmel oder? :)

Christian Seehase 12. Sep 2002 09:30

Moin Thurgen,

dass er FormShow nicht genommen hat war mein Fehler.
Hättest Du erst den Doppelclick auf das Ereignis gemacht, dann den Code eingetragen, und dann das Formular umbenannt, hätte es wohl funktioniert.

BTW:
In gewisser Weise gab es auch zu TP Zeiten eine API, allerdings die von DOS.
Z.B. Stichwort INT 21h.

Thurgen 12. Sep 2002 12:09

nochmal eine kleine Frage, kann ich aus der Funktion auch noch den Namen der NIC auslesen ohne das der o.g. code nochmal gross Verändert werden muss auslesen?

Christian Seehase 12. Sep 2002 12:36

Moin Thurgen,

wenn Du direkt nach der repeat Zeile diese Zeile einträgst

Code:
ShowMessage(trim(pAdapterWork.AdapterName));
wird Dir der interne Name angezeigt.

Tauscht Du .AdapterName gegen .Description aus, so wird Dir das angezeigt, was Du wohl meinst.

Thurgen 12. Sep 2002 21:49

Super, vielen dank.

pAdapterWork.AdapterName gibt mir aber komischerweise immer einen leer String zurück und

.Description gibt mir 'Novel 2000 Adapter' zurück. Richtig ist aber 'ACTON EN1660 Plug and Play LAN-Karte'

aber egal, wird so erstmal auch funktionieren.

Christian Seehase 12. Sep 2002 23:40

Moin Thurgen,

der AdapterName ist der interne Name (üblicher Weise eine GUID), und Description ist der lesbare Name.

Woher hast Du denn den "richtigen" Text?

Thurgen 13. Sep 2002 07:08

Das ist der den er unter Systemsteuerung > System > Netzwerk anzeigt

Christian Seehase 13. Sep 2002 09:39

Moin Thurgen,

ich hab' mal in der Registry gewühlt. ;-)

Das ist ein Wert der u.a. unter

HKEY_LOCAL_MACHINE\System\CurrentControlSet\Enum\P CI

und dort in einem Unterkey in einem Wert Names FriendlyName zu finden ist. (Zumindest bei einer PCI Karte).

Wie man diesen per API erhält, oder wie man sich zu diesem in der Registry gezielt hinnavigiert, kann ich allerdings auch nicht sagen, dafür hatte ich bislang keinen Bedarf.

Thurgen 13. Sep 2002 10:43

So habe ich das am Anfang auch probiert aber das kannst du vergessen. Den string findest du da nur bei win 98/ME, bei den anderen Versionen steht er woanders und da sind auch nur wie schon gesagt PCI Karten aufgelistet. ISA NICs die nach wie vor noch in vielen drin sind (bei mir auch) werden da nicht gelistet.

Tod787 10. Jul 2008 12:57

Re: Gateway IP über eine API auslesen?
 
Also ich würde den Code auch gerne mal ausprobieren nur bekomme ich beim Compilieren die Meldung:

Zitat:

[Pascal Fehler] Unit1.pas(34): E2086 Typ 'PIP_MASK_STRING' ist nicht vollständig definiert
Habe das Formular der Einfachheit TForm1 gnannt und die Combobox auch wieder Combobox1. Aber auch mit den ursprünglichen Bezeichnungen kommt der Fehler. Muss ich evtl noch was einbinden?

Delphi-Quellcode:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TForm1 = class(TForm)
    ComboBox1: TComboBox;
    procedure FormCreate(Sender: TObject);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;

  const
  MAX_ADAPTER_DESCRIPTION_LENGTH = 128; // arb.
  MAX_ADAPTER_NAME_LENGTH        = 256; // arb.
  MAX_ADAPTER_ADDRESS_LENGTH     = 8;  // arb.

type
  PIP_ADDRESS_STRING = ^IP_ADDRESS_STRING;
  IP_ADDRESS_STRING =
    packed record
      acString : array [1..16] of Char;
    end;

  PIP_MASK_STRING = ^PIP_MASK_STRING;
  IP_MASK_STRING = IP_ADDRESS_STRING;

  PIP_ADDR_STRING = ^IP_ADDR_STRING;
  IP_ADDR_STRING =
    packed record
      Next     : PIP_ADDR_STRING;
      IpAddress : IP_ADDRESS_STRING;
      IpMask   : IP_MASK_STRING;
      Context  : DWORD;
    end;

  time_t = int64;

  PIP_ADAPTER_INFO = ^IP_ADAPTER_INFO;
  IP_ADAPTER_INFO =
    packed record
      Next               : PIP_ADAPTER_INFO;
      ComboIndex         : DWORD;
      AdapterName        : array [1..MAX_ADAPTER_NAME_LENGTH+4] of Char ;
      Description        : array [1..MAX_ADAPTER_DESCRIPTION_LENGTH+4] of Char;
      AddressLength      : UINT;
      Address            : array [1..MAX_ADAPTER_ADDRESS_LENGTH] of Byte;
      Index              : DWORD;
      dwType             : UINT;
      DhcpEnabled        : UINT;
      CurrentIpAddress   : PIP_ADDR_STRING;
      IpAddressList      : IP_ADDR_STRING;
      GatewayList        : IP_ADDR_STRING;
      DhcpServer         : IP_ADDR_STRING;
      HaveWins           : Boolean;
      PrimaryWinsServer  : IP_ADDR_STRING;
      SecondaryWinsServer : IP_ADDR_STRING;
      LeaseObtained      : time_t;
      LeaseExpires       : time_t;
    end;

function GetAdaptersInfo(const pAdapterInfo : PIP_ADAPTER_INFO;const pOutBufLen : PULONG) : DWORD; stdcall; external 'IPHLPAPI.DLL' name 'GetAdaptersInfo';
implementation

{$R *.dfm}

procedure TForm1.FormCreate(Sender: TObject);
var
  dwResult    : DWORD;
  dwLen       : DWORD;
  pAdapterWork : PIP_ADAPTER_INFO;
  pAdapterList : PIP_ADAPTER_INFO;
  iasWork     : IP_ADDR_STRING;

begin
  pAdapterList := nil;
  dwLen       := 0;
  dwResult    := GetAdaptersInfo(pAdapterList,@dwLen);
  if dwResult = ERROR_BUFFER_OVERFLOW then
  begin
    pAdapterList := AllocMem(dwLen);
    try
      dwResult := GetAdaptersInfo(pAdapterList,@dwLen);
      if dwResult = ERROR_SUCCESS then
      begin
        pAdapterWork := pAdapterList;
        ComboBox1.Clear;
        repeat
          iasWork := pAdapterWork.GatewayList;
          while iasWork.Next <> nil do
          begin
            ComboBox1.Items.Add(trim(iasWork.IpAddress.acString));
            iasWork := iasWork.Next^;
          end;
          ComboBox1.Items.Add(trim(iasWork.IpAddress.acString));
          pAdapterWork := pAdapterWork.Next;
        until pAdapterWork = nil;
        if ComboBox1.Items.Count > 0 then
        begin
          ComboBox1.ItemIndex := 0;
        end;
      end;
    finally
      FreeMem(pAdapterList,dwLen);
    end;
  end;
end;

end.

SirThornberry 10. Jul 2008 13:10

Re: Gateway IP über eine API auslesen?
 
schau dir doch mal die Zeile genau an:
Delphi-Quellcode:
PIP_MASK_STRING = ^PIP_MASK_STRING;
wie kann PIP_MASK_STRING gleichzeitig ^PIP_MASK_STRING sein? Hast du dich da vielleicht vertippt? :wink:
das führende P steht übrigens für Pointertyp. Und das was da im Quelltext steht wäre die Erstellung eines Pointertypes auf einen Pointertyp. Einfach die entsprechende Zeile mal ein Weilchen anschauen und dann überlegen was daran wohl falsch ist.

Tod787 10. Jul 2008 13:46

Re: Gateway IP über eine API auslesen?
 
ok mit

Delphi-Quellcode:
  PIP_MASK_STRING = ^PIP_ADDRESS_STRING;
  IP_MASK_STRING = IP_ADDRESS_STRING;
geht es jetzt :)

SirThornberry 11. Jul 2008 15:39

Re: Gateway IP über eine API auslesen?
 
das funktioniert wirklich? richtig ist es meiner Meinung nach so:
Delphi-Quellcode:
PIP_MASK_STRING = ^TIP_MASK_STRING;
Denn das Prinzip der Benennung sieht eigentilch so aus:
Delphi-Quellcode:
PYourType = ^TYourType;
Es wird also vom normalen Typen ein Pointertyp erstellt daher auch das P anstelle des T

Tod787 16. Jul 2008 09:57

Re: Gateway IP über eine API auslesen?
 
Sorry für die Verspätug. Bin umgestiegen auf WMI. Fällt mir deutlich einfacher :)


Alle Zeitangaben in WEZ +1. Es ist jetzt 20:16 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz