Hallo allemaal, ik ben nieuw op dit forum maar ben al sinds versie 1 al met delphi bezig en daarvoor met Pascal For Windows (ook van Borland) en Turbo Pascal onder Dos. Delphi vind ik echt geweldig. Met name de oneven versienummers heb ik lang en ver over hun bedoelde houdbaarheidsdatum gebruikt. Met de evennummer versies (2 en 4) die ik gehad heb was altijd iets instabiels aan de hand, maar dat zal wel aan mijn kopie hebben gelegen. Op het moment blijf ik nog steeds Delphi 5 trouw, ook al heb ik versie 7 ook al geruime tijd geïnstalleerd. Ik heb nog lang niet alles uit Delphi 5 gehaald, en dat Dot.Net, sorry maar meer lagen maken zaken alleen maar trager. Ik stam nog uit een tijd waar geheugenruimte en schijfruimte schaars was. Maar wees gerust, ook ik ben aan het DOT.NETten, maar dan met C# in Visual Studio (helaas).
Anyway: hier is wat code. Op het web zijn veel oplossingen te vinden om het fysieke adres van de ethernetkaart(en) van de lokale pc op te vragen in Delphi. Velen werken echter niet. De oplossing die ik heb uitgedoktert en opgedoken wordt niet zo vaak genoemd, maar hij werkt wel. Hij is getest in Win 98 SE en XP SP2. Deze methode (zie functie Get_EthernetAddresses) maakt gebruik van functie GetIfTable in de IPHLPAPI.DLL. Deze DLL is een onderdeel van Windows.
Functie Get_EthernetAddresses retourneert een lijst met de ethernetadressen (de "mac adressen") van alle ethernetkaarten in de computer. Als je goed naar de code kijkt zul je zien dat je ook andere gegevens kunt opvragen met GetIfTable als je de code wat aanpast. Kijk maar eens naar de gedefinieerde constanten. Veel plezier ermee, hopelijk heeft iemand hier iets aan.
Code:
unit ethernet_address;
interface
uses classes, sysutils;
const
MAX_INTERFACE_NAME_LEN = $100;
ERROR_SUCCESS = 0;
MAXLEN_IFDESCR = $100;
MAXLEN_PHYSADDR = 8;
MIB_IF_OPER_STATUS_NON_OPERATIONAL = 0 ;
MIB_IF_OPER_STATUS_UNREACHABLE = 1;
MIB_IF_OPER_STATUS_DISCONNECTED = 2;
MIB_IF_OPER_STATUS_CONNECTING = 3;
MIB_IF_OPER_STATUS_CONNECTED = 4;
MIB_IF_OPER_STATUS_OPERATIONAL = 5;
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;
MIB_IF_ADMIN_STATUS_UP = 1;
MIB_IF_ADMIN_STATUS_DOWN = 2;
MIB_IF_ADMIN_STATUS_TESTING = 3;
type
MIB_IFROW = Record
wszName : Array[0 .. (MAX_INTERFACE_NAME_LEN*2-1)] of char;
dwIndex : LongInt;
dwType : LongInt;
dwMtu : LongInt;
dwSpeed : LongInt;
dwPhysAddrLen : LongInt;
bPhysAddr : Array[0 .. (MAXLEN_PHYSADDR-1)] of Byte;
dwAdminStatus : LongInt;
dwOperStatus : LongInt;
dwLastChange : LongInt;
dwInOctets : LongInt;
dwInUcastPkts : LongInt;
dwInNUcastPkts : LongInt;
dwInDiscards : LongInt;
dwInErrors : LongInt;
dwInUnknownProtos : LongInt;
dwOutOctets : LongInt;
dwOutUcastPkts : LongInt;
dwOutNUcastPkts : LongInt;
dwOutDiscards : LongInt;
dwOutErrors : LongInt;
dwOutQLen : LongInt;
dwDescrLen : LongInt;
bDescr : Array[0 .. (MAXLEN_IFDESCR - 1)] of Char;
end;
function Get_EthernetAddresses: TStringList;
Function GetIfTable( pIfTable : Pointer;
VAR pdwSize : LongInt;
bOrder : LongInt ): LongInt; stdcall;
implementation
// Never change the case of the characters of this external declaration!
// It has to exactly match the case of the name of the function in the dll.
Function GetIfTable; stdcall; external 'IPHLPAPI.DLL';
function Get_EthernetAddresses: TStringList;
const
_MAX_ROWS_ = 20;
type
_IfTable = Record
nRows : LongInt;
ifRow : Array[1.._MAX_ROWS_] of MIB_IFROW;
end;
VAR
pIfTable : ^_IfTable;
TableSize : LongInt;
tmp : String;
i,j : Integer;
ErrCode : LongInt;
begin
pIfTable := nil;
//------------------------------------------------------------
Result:=TStringList.Create;
if Assigned(Result) then
try
//-------------------------------------------------------
// First: just get the buffer size.
// TableSize returns the size needed.
TableSize:=0; // Set to zero so the GetIfTabel function
// won't try to fill the buffer yet,
// but only return the actual size it needs.
GetIfTable(pIfTable, TableSize, 1);
if (TableSize < SizeOf(MIB_IFROW)+Sizeof(LongInt)) then
begin
Exit; // less than 1 table entry?!
end; // if-end.
// Second:
// allocate memory for the buffer and retrieve the
// entire table.
GetMem(pIfTable, TableSize);
ErrCode := GetIfTable(pIfTable, TableSize, 1);
if ErrCode<>ERROR_SUCCESS then
begin
Exit; // OK, that did not work.
// Not enough memory i guess.
end; // if-end.
// Read the ETHERNET addresses.
for i := 1 to pIfTable^.nRows do
try
if pIfTable^.ifRow[i].dwType=MIB_IF_TYPE_ETHERNET then
begin
tmp:='';
for j:=0 to pIfTable^.ifRow[i].dwPhysAddrLen-1 do
begin
tmp := tmp + format('%.2x',
[ pIfTable^.ifRow[i].bPhysAddr[j] ] );
end; // for-end.
//-------------------------------------
if Length(tmp)>0 then Result.Add(tmp);
end; // if-end.
except
Exit;
end; // if-try-except-end.
finally
if Assigned(pIfTable) then FreeMem(pIfTable,TableSize);
end; // if-try-finally-end.
end;
end.
Bookmarks