Autor |
Beitrag |
Manfred
      
Beiträge: 90
|
Verfasst: Di 10.05.16 16:02
Hallo Leidgenossen,
vor einiger Zeit habe ich unter Delphi 6 eine Routine in diesem Forum gefunden, die mir das Auslesen der MAC-Adresse ermöglicht:
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71: 72: 73: 74: 75: 76: 77: 78: 79: 80: 81: 82: 83: 84: 85: 86: 87: 88: 89: 90: 91: 92: 93: 94: 95: 96: 97: 98: 99: 100: 101: 102: 103: 104: 105: 106: 107: 108: 109: 110: 111: 112: 113: 114: 115: 116: 117: 118: 119: 120: 121:
| unit MyLAN;
interface
uses SysUtils,nb30;
function MACAddress():string;
implementation
FUNCTION GetAdapters: TLanaEnum; VAR NCB :TNCB; LanaEnum :TLanaEnum; ReturnCode :Char; BEGIN FillChar(NCB, SizeOf(NCB), 0); FillChar(LanaEnum, SizeOf(TLanaEnum), 0);
NCB.ncb_Command := CHAR(NCBENUM); NCB.ncb_buffer := @LanaEnum; NCB.ncb_length := Sizeof(LanaEnum);
ReturnCode := NetBios(@NCB);
IF ReturnCode <> #0 THEN BEGIN LanaEnum.Length := CHAR(0); LanaEnum.Lana[0] := ReturnCode; END;
Result := LanaEnum; END;
FUNCTION GetMacAddress(AdapterID : Integer) : String; TYPE TAdapterStatusA = record Adapt : TAdapterStatus; NameBuff : array[0..30] of TNameBuffer; end; VAR NCB :TNCB; ReturnCode :Char; AdapterStatus :TAdapterStatus; BEGIN FillChar( NCB, SizeOf(NCB), 0 );
NCB.ncb_command := Char(NCBRESET); NCB.ncb_lana_num := Char(AdapterID);
ReturnCode := NetBios(@NCB);
IF ReturnCode <> #0 THEN BEGIN Result:=Char(Ord(ReturnCode)*-1); Exit; END;
FillChar( NCB, SizeOf(NCB), 0 );
NCB.ncb_command := Char(NCBASTAT); NCB.ncb_lana_num := Char(AdapterID); NCB.ncb_buffer := @AdapterStatus; NCB.ncb_length := SizeOf(AdapterStatus); StrCopy(NCB.ncb_callname, '* ' );
ReturnCode := Netbios( @NCB );
IF ReturnCode <> #0 THEN BEGIN Result:=Char(Ord(ReturnCode)*-1); Exit; END;
result:=Format('%2.2x-%2.2x-%2.2x-%2.2x-%2.2x-%2.2x', [ORD(AdapterStatus.Adapter_address[0]), ORD(AdapterStatus.Adapter_address[1]), ORD(AdapterStatus.Adapter_address[2]), ORD(AdapterStatus.Adapter_address[3]), ORD(AdapterStatus.Adapter_address[4]), ORD(AdapterStatus.Adapter_address[5])]) end;
function MACAddress():string; VAR L_Enum :TLanaEnum; i,cnt : integer ; s : string ; BEGIN s := '' ; L_Enum := GetAdapters; cnt := byte(L_Enum.Length) ; for i:= 1 to cnt do begin s := s + getMACaddress(BYTE(L_Enum.Lana[i-1])); if i<cnt then s:=s+','; end ; result := s; end ;
end. |
Nun bin ich dabei, diese Routine für XE zu portieren und habe bislang die Char in AnsiChar-Variablen gewandelt:
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71: 72: 73: 74: 75: 76: 77: 78: 79: 80: 81: 82: 83: 84: 85: 86: 87: 88: 89: 90: 91: 92: 93: 94: 95: 96: 97: 98: 99: 100: 101: 102: 103: 104: 105: 106: 107: 108: 109: 110: 111: 112: 113: 114: 115: 116: 117: 118: 119: 120: 121:
| unit MyLAN;
interface
uses SysUtils,nb30;
function MACAddress():string;
implementation
FUNCTION GetAdapters: TLanaEnum; VAR NCB :TNCB; LanaEnum :TLanaEnum; ReturnCode :AnsiChar; BEGIN FillChar(NCB, SizeOf(NCB), 0); FillChar(LanaEnum, SizeOf(TLanaEnum), 0);
NCB.ncb_Command := AnsiCHAR(NCBENUM); NCB.ncb_buffer := @LanaEnum; NCB.ncb_length := Sizeof(LanaEnum);
ReturnCode := NetBios(@NCB);
IF ReturnCode <> #0 THEN BEGIN LanaEnum.Length := AnsiCHAR(0); LanaEnum.Lana[0] := ReturnCode; END;
Result := LanaEnum; END;
FUNCTION GetMacAddress(AdapterID : Integer) : String; TYPE TAdapterStatusA = record Adapt : TAdapterStatus; NameBuff : array[0..30] of TNameBuffer; end; VAR NCB :TNCB; ReturnCode :AnsiChar; AdapterStatus :TAdapterStatus; BEGIN FillChar( NCB, SizeOf(NCB), 0 );
NCB.ncb_command := AnsiChar(NCBRESET); NCB.ncb_lana_num := AnsiChar(AdapterID);
ReturnCode := NetBios(@NCB);
IF ReturnCode <> #0 THEN BEGIN Result:=AnsiChar(Ord(ReturnCode)*-1); Exit; END;
FillChar( NCB, SizeOf(NCB), 0 );
NCB.ncb_command := AnsiChar(NCBASTAT); NCB.ncb_lana_num := AnsiChar(AdapterID); NCB.ncb_buffer := @AdapterStatus; NCB.ncb_length := SizeOf(AdapterStatus); StrCopy(NCB.ncb_callname, '* ' );
ReturnCode := Netbios( @NCB );
IF ReturnCode <> #0 THEN BEGIN Result:=AnsiChar(Ord(ReturnCode)*-1); Exit; END;
result:=Format('%2.2x-%2.2x-%2.2x-%2.2x-%2.2x-%2.2x', [ORD(AdapterStatus.Adapter_address[0]), ORD(AdapterStatus.Adapter_address[1]), ORD(AdapterStatus.Adapter_address[2]), ORD(AdapterStatus.Adapter_address[3]), ORD(AdapterStatus.Adapter_address[4]), ORD(AdapterStatus.Adapter_address[5])]) end;
function MACAddress():string; VAR L_Enum :TLanaEnum; i,cnt : integer ; s : string ; BEGIN s := '' ; L_Enum := GetAdapters; cnt := byte(L_Enum.Length) ; for i:= 1 to cnt do begin s := s + getMACaddress(BYTE(L_Enum.Lana[i-1])); if i<cnt then s:=s+','; end ; result := s; end ;
end. |
Offenbar habe ich aber etwas übersehen.
Der NetBios-Aufruf in Zeile 30 endet mit dem Errorcode #7
Ich kenne mich einfach nicht mehr aus, wenn char<>char, word<>word und integer<>integer ist.
Kann mir jemand auf die Sprünge helfen?
Danke.
Moderiert von Christian S.: Code- durch Delphi-Tags ersetzt
Moderiert von Narses: Titel erweitert.
_________________ Computer können schneller rechnen als wir, deshalb machen sie auch mehr Fehler
|
|
baumina
      
Beiträge: 305
Erhaltene Danke: 61
Win 7
Delphi 10.2 Tokyo Enterprise
|
Verfasst: Di 10.05.16 16:13
Ist die Unit nb30 ebenfalls umgestellt worden?
|
|
Narses
      

Beiträge: 10183
Erhaltene Danke: 1256
W10ent
TP3 .. D7pro .. D10.2CE
|
Verfasst: Di 10.05.16 18:36
Moin!
Ohne jetzt im Detail auf die hier angesprochene Portierungsproblematik einzugehen (leider auch für die gleich folgende Referenz nicht ganz unzutreffend  , sorry, hab nicht viel Zeit): Ich halte es für mittlerweile ... sportlich  ... sich auf die Anwesenheit von NETBIOS-API-Funktionen in modernen Betriebssystemen zu verlassen (diese nb30-Unit wird wohl eine Kapsel für die NETBIOS-API sein, schätze ich mal  ). Heute schon nur noch mit hoher (und nicht mehr mit an Sicherheit grenzender) Wahrscheinlichkeit anzutreffen, aber das wird nicht mehr ewig so bleiben.
Vermutlich ist es besser, man geht ähnlich wie hier beschrieben vor und holt sich die lokale(n) IP-Adresse(n), die man dann per ARP-API (IPHELPER) in eine MAC-Adresse "übersetzt" (immer dran denken: man kann auch mehr als eine Netzwerkkarte haben, also auch mehr als eine MAC-Adresse!).
Ein anderer Ansatz könnte auch WMI sein, hier dürften sich ebenfalls mit hoher Wahrscheinlichkeit auch in Zukunft funktionsfähig die MAC-Adresse(n) ermitteln lassen.
cu
Narses
_________________ There are 10 types of people - those who understand binary and those who don´t.
|
|
Manfred 
      
Beiträge: 90
|
Verfasst: Di 10.05.16 21:17
Danke für die schnelle Antwort.
nb30 kapselt die netapi32.dll und bietet dafür Konstanten und Types an. Die Versionen für D6 und XE sind nicht identisch, da auch hier Char in AnsiChar etc. gewandelt wurden. Andere Abweichungen habe ich nicht gefunden.
Die API ist jedoch definitiv vorhanden, da die "alte" Version einwandfrei funktioniert. Und das lückenlos von Win XP bis 10 bei 32 und 64 Bit.
Mit der von Narses angebotenen Lösung würde ich gerne liebäugeln, doch es gibt ein Problem: Ich benötige ausschließlich die eigenen MAC-Adressen, nicht alle aus dem Netz.
---
Nachtrag: Auch die Unit Ping ist unter XE offenbar nicht auffindbar
_________________ Computer können schneller rechnen als wir, deshalb machen sie auch mehr Fehler
|
|
Narses
      

Beiträge: 10183
Erhaltene Danke: 1256
W10ent
TP3 .. D7pro .. D10.2CE
|
Verfasst: Di 10.05.16 22:35
Moin!
Manfred hat folgendes geschrieben : | Ich benötige ausschließlich die eigenen MAC-Adressen, nicht alle aus dem Netz. |
Davon war auch nicht die Rede.  Die lokale(n) IP-Adresse(n) ermitteln (also die eigene(n)) und dann über die ARP-API die MAC dazu bestimmen lassen.
Wie gesagt, WMI geht auch.
cu
Narses
_________________ There are 10 types of people - those who understand binary and those who don´t.
|
|
Manfred 
      
Beiträge: 90
|
Verfasst: Mi 11.05.16 09:54
Hallo Narses,
im Prinzip habe ich mit Deiner Unit aber das selbe Problem: Es lässt sich bei mit nicht unter XE compilieren, da die Unit "Ping" fehlt.
Diese ist offenbar für "GetIPByName" erforderlich.
_________________ Computer können schneller rechnen als wir, deshalb machen sie auch mehr Fehler
|
|
Narses
      

Beiträge: 10183
Erhaltene Danke: 1256
W10ent
TP3 .. D7pro .. D10.2CE
|
Verfasst: Mi 11.05.16 10:58
Moin!
Manfred hat folgendes geschrieben : | da die Unit "Ping" fehlt. |
In dem ARP-MAC-Beitrag war doch ein Link auf den Ping-Thread...
cu
Narses
//EDIT: WMI ist auch eine wirklich gute und zuverlässige Quelle für sowas. Gib mal in einer Kommandozeile das hier ein:  (als Demo)
Quelltext 1:
| wmic nic get description,macaddress |
_________________ There are 10 types of people - those who understand binary and those who don´t.
|
|
Manfred 
      
Beiträge: 90
|
Verfasst: Mi 11.05.16 14:34
Tut mir leid, hatte ich völlig übersehen.
Danke.
Das mit der Kommandozeile ist in der Tat genau das, was ich suche. Nun muss ich wmic nur noch ins Projekt integrieren.
_________________ Computer können schneller rechnen als wir, deshalb machen sie auch mehr Fehler
|
|
|