Link to home
Start Free TrialLog in
Avatar of rafaelri
rafaelri

asked on

Network Physical Address

How can I get a Network Card Physical Address??
ASKER CERTIFIED SOLUTION
Avatar of Mohammed Nasman
Mohammed Nasman
Flag of Palestine, State of image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of sundayboys
sundayboys

unit MainMAC;

interface

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

type
  TGetMACForm = class(TForm)
    Edit1: TEdit;
    ComboBox1: TComboBox;
    MACAddrButton: TButton;
    ResetButton: TButton;
    Label1: TLabel;
    Label2: TLabel;
    procedure MACAddrButtonClick(Sender: TObject);
    procedure ResetButtonClick(Sender: TObject);
    procedure FormCreate(Sender: TObject);
    procedure ComboBox1Change(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  GetMACForm: TGetMACForm;

implementation

{$R *.DFM}

type
 TNBLanaResources = (lrAlloc, lrFree);

type
 PMACAddress = ^TMACAddress;
 TMACAddress = array[0..5] of Byte;

{
The LanaEnum parameter specifies structure describing accessible numbers Lana.
The amounty Lana is defined by number of the installed network cards and network
protocols for each of them. Each accessible Lana identifies a unique combination
of one driver of the protocol and one network card. Each structure NCB contains
a field ncb_lana_num, in which necessary number Lana (i.e. identifier of pair
protocol/MAC) should be written.
In systems with one network card, Lana = 0, usually corresponds
"to the protocol by default".
}

// Get the list of adapters
function GetLanaEnum(LanaEnum: PLanaEnum): Byte;
var
  LanaEnumNCB: PNCB;
begin
  New(LanaEnumNCB);
  ZeroMemory(LanaEnumNCB, SizeOf(TNCB));
  try
    with LanaEnumNCB^ do
    begin
      ncb_buffer := PChar(LanaEnum);
      ncb_length := SizeOf(TLanaEnum);
      ncb_command  := Char(NCBENUM);
      NetBios(LanaEnumNCB);
      Result := Byte(ncb_cmd_cplt);
    end;
  finally
    Dispose(LanaEnumNCB);
  end;
end;

procedure TGetMACForm.FormCreate(Sender: TObject);
var
  LanaEnum: PLanaEnum;
  I: Integer;
begin
  Edit1.Text := '';
  New(LanaEnum);
  ZeroMemory(LanaEnum, SizeOf(TLanaEnum));
  try
    if GetLanaEnum(LanaEnum) = NRC_GOODRET then
    begin
      with ComboBox1, Items do
      begin
        Sorted := True;
        BeginUpdate;
        Clear;
        for I := 0 to Byte(LanaEnum.length) - 1 do
          Add(IntToStr(Byte(LanaEnum.lana[I])));
        ItemIndex := 0;
        EndUpdate;
      end;
    end;
  finally
    Dispose(LanaEnum);
  end;
  ResetButton.Enabled := (Win32Platform = VER_PLATFORM_WIN32_NT);
end;

function ResetLana(LanaNum, ReqSessions, ReqNames: Byte;
  LanaRes: TNBLanaResources): Byte;
var
  ResetNCB: PNCB;
begin
  New(ResetNCB);
  ZeroMemory(ResetNCB, SizeOf(TNCB));
  try
    with ResetNCB^ do
    begin
      ncb_lana_num := Char(LanaNum);        // Set Lana_Num
      ncb_lsn := Char(LanaRes);             // Allocation of new resources
      ncb_callname[0] := Char(ReqSessions); // Query of max sessions
      ncb_callname[1] := #0;                // Query of max NCBs (default)
      ncb_callname[2] := Char(ReqNames);    // Query of max names
      ncb_callname[3] := #0;                // Query of use NAME_NUMBER_1
      ncb_command  := Char(NCBRESET);
      NetBios(ResetNCB);
      Result := Byte(ncb_cmd_cplt);
    end;
  finally
    Dispose(ResetNCB);
  end;
end;

function GetMACAddress(LanaNum: Byte; MACAddress: PMACAddress): Byte;
var
  AdapterStatus: PAdapterStatus;
  StatNCB: PNCB;
begin
  New(StatNCB);
  ZeroMemory(StatNCB, SizeOf(TNCB));
  StatNCB.ncb_length := SizeOf(TAdapterStatus) +  255 * SizeOf(TNameBuffer);
  GetMem(AdapterStatus, StatNCB.ncb_length);
  try
    with StatNCB^ do
    begin
      ZeroMemory(MACAddress, SizeOf(TMACAddress));
      ncb_buffer := PChar(AdapterStatus);
      ncb_callname := '*              ' + #0;
      ncb_lana_num := Char(LanaNum);
      ncb_command  := Char(NCBASTAT);
      NetBios(StatNCB);
      Result := Byte(ncb_cmd_cplt);
      if Result = NRC_GOODRET then
        MoveMemory(MACAddress, AdapterStatus, SizeOf(TMACAddress));
    end;
  finally
    FreeMem(AdapterStatus);
    Dispose(StatNCB);
  end;
end;

procedure TGetMACForm.MACAddrButtonClick(Sender: TObject);
var
  LanaNum: Byte;
  MACAddress: PMACAddress;
  RetCode: Byte;
begin
  LanaNum := StrToInt(ComboBox1.Text);
  New(MACAddress);
  try
    RetCode := GetMACAddress(LanaNum, MACAddress);
    if RetCode = NRC_GOODRET then
    begin
      Edit1.Text := Format('%2.2x-%2.2x-%2.2x-%2.2x-%2.2x-%2.2x',
        [MACAddress[0], MACAddress[1], MACAddress[2],
         MACAddress[3], MACAddress[4], MACAddress[5]]);
    end else
    begin
      Beep;
      Edit1.Text := 'Error';
      ShowMessage('GetMACAddress Error! RetCode = $' + IntToHex(RetCode, 2));
    end;
  finally
    Dispose(MACAddress);
  end;
end;

procedure TGetMACForm.ResetButtonClick(Sender: TObject);
var
  RetCode: Byte;
  LanaNum: Byte;
begin
  LanaNum := StrToInt(ComboBox1.Text);
  RetCode := ResetLana(LanaNum, 0, 0, lrAlloc);
  if RetCode <> NRC_GOODRET then
  begin
    Beep;
    ShowMessage('Reset Error! RetCode = $' + IntToHex(RetCode, 2));
  end;
end;

procedure TGetMACForm.ComboBox1Change(Sender: TObject);
begin
  Edit1.Text := '';
end;

end.
sundayboys

  It's the same unit I posted in this link http://vladshar.ufanet.ru/

neatly removed the copyright notice by the author too.


one thing I discovered with windows2000 though

it's advisable to initiate a Reset on formshow or you'll get an error when probing for the mac address.  so I just stuck a formshow event then calls a reset if it's winnt


procedure TGetMACForm.FormShow(Sender: TObject);
begin
  if (Win32Platform = VER_PLATFORM_WIN32_NT) then
    resetbuttonclick(self);

end;

cheers!
Avatar of rafaelri

ASKER

I'm without time to check the answer but I'm sure it's working. And as you gave the answer first I'm gonna give you the points. tks!