!!!!!!关于寻找网卡物理地址的问题!!!!!!!!!

时间:2021-06-13 17:31:36
我们在做的一个软件,需要找到计算机里的网卡的物理地址,和他进行通信,现在已经可以做到了,但是有些时候windows98中存在虚拟的网卡,只在协议中存在,windows98也给他分配了地址,这样我就无法知道那个网卡是真是存在的,和他进行通信也就没有意义,请问用怎样的办法才能真正获得有效的网卡的物理地址呢???

5 个解决方案

#1


[转载]
在iphlpapi.dll里面有一个函数:GetAdaptersInfo() 
好像是干这个用的。说明如下: 
GetAdaptersInfo 
The GetAdaptersInfo function retrieves adapter information for the local computer. 

DWORD GetAdaptersInfo( 
  PIP_ADAPTER_INFO pAdapterInfo,    // buffer to receive data 
  PULONG pOutBufLen                 // size of data returned 
); 
Parameters 
pAdapterInfo  
[out] Pointer to a buffer that, , receives a linked list of IP_ADAPTER_INFO structures.  
pOutBufLen  
[in] Pointer to a ULONG variable that specifies the size of the buffer pointed to by the pAdapterInfo parameter. If this size is insufficient to hold the adapter information, GetAdaptersInfo fills in this variable with the required size, and returns an error code of ERROR_BUFFER_OVERFLOW.  
Return Values 
If the function succeeds, the return value is ERROR_SUCCESS. 

If the function fails, the return value is one of the following error codes. 

Value Meaning  
ERROR_BUFFER_OVERFLOW The buffer size indicated by the pOutBufLen parameter is too small to hold the adapter information. The pOutBufLen parameter points to the required size.  
ERROR_INVALID_PARAMETER The pOutBufLen parameter is NULL, or the calling process does not have read/write access to the memory pointed to by pOutBufLen, or the calling process does not have write access to the memory pointed to by the pAdapterInfo parameter.  
ERROR_NO_DATA No adapter information exists for the local computer.  
ERROR_NOT_SUPPORTED GetAdaptersInfo is not supported by the operating system running on the local computer.  
Other If the function fails, use FormatMessage to obtain the message string for the returned error.  


Requirements  
  Windows NT/2000: Requires Windows 2000. 
  Windows 95/98: Requires Windows 98. 
  Header: Declared in Iphlpapi.h.//没有 
  Library: Use Iphlpapi.lib.//没有 



IP_ADAPTER_INFO 
The IP_ADAPTER_INFO structure contains information about a particular network adapter on the local computer. 

typedef struct _IP_ADAPTER_INFO { 
  struct _IP_ADAPTER_INFO* Next; 
  DWORD ComboIndex; 
  char AdapterName[MAX_ADAPTER_NAME_LENGTH + 4]; 
  char Description[MAX_ADAPTER_DESCRIPTION_LENGTH + 4]; 
  UINT AddressLength; 
  BYTE Address[MAX_ADAPTER_ADDRESS_LENGTH]; 
  DWORD Index; 
  UINT Type; 
  UINT DhcpEnabled; 
  PIP_ADDR_STRING CurrentIpAddress; 
  IP_ADDR_STRING IpAddressList; 
  IP_ADDR_STRING GatewayList; 
  IP_ADDR_STRING DhcpServer; 
  BOOL HaveWins; 
  IP_ADDR_STRING PrimaryWinsServer; 
  IP_ADDR_STRING SecondaryWinsServer; 
  time_t LeaseObtained; 
  time_t LeaseExpires;  
} IP_ADAPTER_INFO, *PIP_ADAPTER_INFO; 
Members 
Next  
Pointer to the next adapter in the linked list of adapters.  
ComboIndex  
This member is unused.  
AdapterName[MAX_ADAPTER_NAME_LENGTH + 4]  
Specifies the name of the adapter.  
Description[MAX_ADAPTER_DESCRIPTION_LENGTH + 4]  
Specifies a description for the adapter.  
AddressLength  
Specifies the length of the hardware address for the adapter.  
Address[MAX_ADAPTER_ADDRESS_LENGTH]  
Specifies the hardware address for the adapter. //这个是不是你想要的? 
Index  
Specifies the adapter index.  
Type  
Specifies the adapter type.  
DhcpEnabled  
Specifies whether dynamic host configuration protocol (DHCP) is enabled for this adapter.  
CurrentIpAddress  
Specifies the current IP address for this adapter.  
IpAddressList  
Specifies the list of IP addresses associated with this adapter.  
GatewayList  
Specifies the IP address of the default gateway for this adapter.  
DhcpServer  
Specifies the IP address of the DHCP server for this adapter.  
HaveWins  
Specifies whether this adapter uses Windows Internet Name Service (WINS).  
PrimaryWinsServer  
Specifies the IP address of the primary WINS server.  
SecondaryWinsServer  
Specifies the IP address of the secondary WINS server.  
LeaseObtained  
Specifies the time when the current DHCP lease was obtained.  
LeaseExpires  
Specifies the time when the current DHCP lease will expire.  
Requirements  
  Windows NT/2000: Requires Windows 2000. 
  Windows 95/98: Requires Windows 98. 
  Header: Declared in Iptypes.h. 

#2


[转载]


implementation
uses SysUtils, Windows, NB30;


function GetNetBIOSAddress : string;
var  ncb  : TNCB;
  status  : TAdapterStatus;
  lanenum : TLanaEnum;

  procedure ResetAdapter (num : char);
  begin
    fillchar(ncb,sizeof(ncb),0);
    ncb.ncb_command:=char(NCBRESET);
    ncb.ncb_lana_num:=num;
    Netbios(@ncb);
  end;

var
  lanNum  : char;
  address : record
             part1 : Longint;
             part2 : Word;//Smallint;
            end absolute status;
begin
  Result:='';

  fillchar(ncb,sizeof(ncb),0);
    ncb.ncb_command:=char(NCBENUM);
    ncb.ncb_buffer:=@lanenum;
    ncb.ncb_length:=sizeof(lanenum);
  Netbios(@ncb);

  if lanenum.length=#0 then exit;
  lanNum:=lanenum.lana[0];

  ResetAdapter(lanNum);

  fillchar(ncb,sizeof(ncb),0);
    ncb.ncb_command:=char(NCBASTAT);
    ncb.ncb_lana_num:=lanNum;
    ncb.ncb_callname[0]:='*';
    ncb.ncb_buffer:=@status;
    ncb.ncb_length:=sizeof(status);
  Netbios(@ncb);
  ResetAdapter(lanNum);

  Result:=Format('%x%x',[address.part1,address.part2]);
end;

#3


unit Main;  

interface  

uses  
  SysUtils, WinTypes, WinProcs, Messages, Classes, Graphics, Controls, 
  

  Forms, Dialogs, StdCtrls,  
  Nb, ExtCtrls;  

type  
  TForm1 = class(TForm)  
    Panel1: TPanel;  
    Memo1: TMemo;  
    Panel2: TPanel;  
    Button1: TButton;  
    procedure Button1Click(Sender: TObject);  
    procedure FormCreate(Sender: TObject);  
  private  
    { Private declarations }  
  public  
    { Public declarations }  
  end;  

var  
  Form1: TForm1;  

implementation  

{$R *.DFM}  


{---------------------------------------------}  
{ enumerate the lana's  - works only on WIN32 }  
{---------------------------------------------}  
function NbLanaEnum: TLana_Enum;  
var  
  NCB: TNCB;  
  L_Enum: TLana_Enum;  
  RetCode: Word;  
begin  
{$IFDEF WIN32}  
  FillChar(NCB, SizeOf(NCB), 0);  
  FillChar(L_Enum, SizeOf(TLana_Enum), 0);  
  NCB.Command := NCB_ENUM;  
  NCB.Buf := @L_Enum;  
  NCB.Length := Sizeof(L_Enum);  
  RetCode := NetBiosCmd(NCB);  
  if RetCode <> NRC_GOODRET then begin  
    L_Enum.Length := 0;  
    L_Enum.Lana[0] := Byte(RetCode);  
  end;  
{$ELSE}                     { not supported for WIN16, fake LANA 0 }  

  L_Enum.Length := 1;  
  L_Enum.Lana[0] := 0;  
{$ENDIF}  
  Result := L_Enum;  
end;  

{----------------------------------------}  
{ Reset the lana - don't for WIN16 !     }  
{----------------------------------------}  
function NbReset(l: Byte): Word;  
var  
  NCB: TNCB;  
begin  
{$IFNDEF WIN32}             { will reset all your connections for WIN1 
  
6 }  
  Result := NRC_GOODRET;    { so just fake a reset for Win16           
  
  }  
{$ELSE}  
  FillChar(NCB, SizeOf(NCB), 0);  
  NCB.Command := NCB_RESET;  
  NCB.Lana_Num := l;  
  Result := NetBiosCmd(NCB);  
{$ENDIF}  
end;  
{----------------------------------------}  
{ return the MAC address of an interface }  
{ in the form of a string like :         }  
{ 'xx:xx:xx:xx:xx:xx'                    }  
{ using the definitions in nb.pas        }  
{----------------------------------------}  

function NbGetMacAddr(LanaNum: Integer): String;  
var  
  NCB: TNCB;  
  AdpStat: TAdpStat;  
  RetCode: Word;  
begin  
  FillChar(NCB, SizeOf(NCB), 0);  
  FillChar(AdpStat, SizeOf(AdpStat), 0);  
  NCB.Command := NCB_ADPSTAT;  
  NCB.Buf := @AdpStat;  
  NCB.Length := Sizeof(AdpStat);  
  FillChar(NCB.CallName, Sizeof(TNBName), $20);  
  NCB.CallName[0] := Byte('*');  
  NCB.Lana_Num := LanaNum;  
  RetCode := NetBiosCmd(NCB);  
  if RetCode = NRC_GOODRET then begin  
    Result := Format('%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x',  
                   [AdpStat.ID[0],  
                   AdpStat.ID[1],  
                   AdpStat.ID[2],  
                   AdpStat.ID[3],  
                   AdpStat.ID[4],  
                   AdpStat.ID[5]  
                   ]);  
  end else begin  
    Result := '??:??:??:??:??:??';  
  end;  
end;  


procedure TForm1.Button1Click(Sender: TObject);  
begin  
  Close;  
end;  

procedure TForm1.FormCreate(Sender: TObject);  
var  
  L_Enum : TLana_Enum;  
  RetCode: Word;  
  i: Integer;  
begin  
  L_Enum := NbLanaEnum;                       { enumerate lanas for WI 
  
N NT }  
  if L_Enum.Length = 0 then begin  
    Button1.Caption := Format('LanaEnum err=%2.2x', [L_Enum.Lana[0]]); 
  

    exit;  
  end;  

  for i := 0 to (L_Enum.Length - 1)do begin   { for every lana found   
  
     }  

    RetCode := NbReset(L_Enum.Lana[i]);       { Reset lana for WIN NT  
  
     }  
    if RetCode <> NRC_GOODRET then begin  
       Button1.Caption := Format('Reset Lana %d err=%2.2x',[i, RetCode 
  
]);  
       exit;  
    end;  
                                             { Get MAC Address         
  
     }  
    Memo1.Lines.Add(Format('Lana %x = %s', [L_Enum.Lana[i], NbGetMacAd 
  
dr(i)]));  

  end;  

  Button1.Caption := 'Stop';  
end;  

end.  
---------------------------------- -  


#4


unit Nb;  

{$F+}  

{  nb.pas  

   16/32 bit windows netbios access (follows IBM's Netbios 3.0 spec)  


   (C) CEVI VZW - 29 april 1998     -- DH (Danny.Heijl@cevi.be) --  

   You can (ab)use this code as you like, but please do not remove the 
  
 credits.  

   I used reference material from IBM, Microsoft, Syntax and Byte when 
  
 I wrote  
   the 16-bit (DOS) c-version ages ago (in Borland Turbo C 2.0 on a 38 
  
6SX PC)  
   with a Syntax SMB server running on Interactive Unix.  
   I now converted this to 16 and 32 bit Delphi code.  

}  

interface  


uses SysUtils, Winprocs, Wintypes;  

const  


{ size of a netbios name }  
  NBNAMESIZE    = 16;  

{ max number of network adapters }  
{ remeber it's BIG Blue, right ? }  
  MAXLANAS      = 254;  

{ NCB Command codes }  

  NCB_ASYNC     = $80;   { asynch command bit to be or-ed into command 
  
 }  

  NCB_CALL      = $10;   { open a session }  
  NCB_LISTEN    = $11;   { wait for a call }  
  NCB_HANGUP    = $12;   { end session }  
  NCB_SEND      = $14;   { send data }  
  NCB_RECV      = $15;   { receive data }  
  NCB_RECVANY   = $16;   { receive data on any session }  
  NCB_CHAINSEND = $17;   { chain send data }  
  NCB_DGSEND    = $20;   { send a datagram }  
  NCB_DGRECV    = $21;   { receive datagram }  
  NCB_DGSENDBC  = $22;   { send broadcast datagram }  
  NCB_DGREVCBC  = $23;   { receive broadcast datagram }  
  NCB_ADDNAME   = $30;   { add unique name to local table }  
  NCB_DELNAME   = $31;   { delete name from local table }  
  NCB_RESET     = $32;   { reset adapter }  
  NCB_ADPSTAT   = $33;   { adapter status }  
  NCB_SSTAT     = $34;   { session status }  
  NCB_CANCEL    = $35;   { cancel NCB request }  
  NCB_ADDGRPNAME= $36;   { add group name to local table }  
  NCB_ENUM      = $37;   { enum adapters }  
  NCB_UNLINK    = $70;   { unlink remote boot code }  
  NCB_SENDNA    = $71;   { send, don't wait for ACK }  
  NCB_CHAINSENDNA=$72;   { chain send, but don't wait for ACK }  
  NCB_LANSTALERT= $73;   { lan status alert }  
  NCB_ACTION    = $77;   { enable extensions }  
  NCB_FINDNAME  = $78;   { search for name on the network }  
  NCB_TRACE     = $79;   { activate / stop tracing }  

{ NCB return codes }  

  NRC_GOODRET     = $00;    { good return  
                              also returned when ASYNCH request accept 
  
ed }  
  NRC_BUFLEN      = $01;    { illegal buffer length                    
  
   }  
  NRC_ILLCMD      = $03;    { illegal command                          
  
   }  
  NRC_CMDTMO      = $05;    { command timed out                        
  
   }  
  NRC_INCOMP      = $06;    { message incomplete, issue another comman 
  
d  }  
  NRC_BADDR       = $07;    { illegal buffer address                   
  
   }  
  NRC_SNUMOUT     = $08;    { session number out of range              
  
   }  
  NRC_NORES       = $09;    { no resource available                    
  
   }  
  NRC_SCLOSED     = $0a;    { session closed                           
  
   }  
  NRC_CMDCAN      = $0b;    { command cancelled                        
  
   }  
  NRC_DUPNAME     = $0d;    { duplicate name                           
  
   }  
  NRC_NAMTFUL     = $0e;    { name table full                          
  
   }  
  NRC_ACTSES      = $0f;    { no deletions, name has active sessions   
  
   }  
  NRC_LOCTFUL     = $11;    { local session table full                 
  
   }  
  NRC_REMTFUL     = $12;    { remote session table full                
  
   }  
  NRC_ILLNN       = $13;    { illegal name number                      
  
   }  
  NRC_NOCALL      = $14;    { no callname                              
  
   }  
  NRC_NOWILD      = $15;    { cannot put * in NCB_NAME                 
  
   }  
  NRC_INUSE       = $16;    { name in use on remote adapter            
  
   }  
  NRC_NAMERR      = $17;    { name deleted                             
  
   }  
  NRC_SABORT      = $18;    { session ended abnormally                 
  
   }  
  NRC_NAMCONF     = $19;    { name conflict detected                   
  
   }  
  NRC_IFBUSY      = $21;    { interface busy, IRET before retrying     
  
   }  
  NRC_TOOMANY     = $22;    { too many commands outstanding, retry lat 
  
er }  
  NRC_BRIDGE      = $23;    { ncb_lana_num field invalid               
  
   }  
  NRC_CANOCCR     = $24;    { command completed while cancel occurring 
  
   }  
  NRC_CANCEL      = $26;    { command not valid to cancel              
  
   }  
  NRC_DUPENV      = $30;    { name defined by anther local process     
  
   }  
  NRC_ENVNOTDEF   = $34;    { environment undefined. RESET required    
  
   }  
  NRC_OSRESNOTAV  = $35;    { required OS resources exhausted          
  
   }  
  NRC_MAXAPPS     = $36;    { max number of applications exceeded      
  
   }  
  NRC_NOSAPS      = $37;    { no saps available for netbios            
  
   }  
  NRC_NORESOURCES = $38;    { requested resources are not available    
  
   }  
  NRC_INVADDRESS  = $39;    { invalid ncb address or length > segment  
  
   }  
  NRC_INVDDID     = $3B;    { invalid NCB DDID                         
  
   }  
  NRC_LOCKFAIL    = $3C;    { lock of user area failed                 
  
   }  
  NRC_OPENERR     = $3f;    { NETBIOS not loaded                       
  
   }  
  NRC_SYSTEM      = $40;    { system error                             
  
   }  

  NRC_PENDING     = $ff;    { asynchronous command is not yet finished 
  
   }  

{  Values for transport_id }  

 ALL_TRANSPORTS = 'M'#$00#$00#$00;  
 MS_NBF         = 'MNBF';  


{  values for name_flags bits. }  

 NAME_FLAGS_MASK = $87;  

 GROUP_NAME      = $80;  
 UNIQUE_NAME     = $00;  

 REGISTERING     = $00;  
 REGISTERED      = $04;  
 DEREGISTERED    = $05;  
 DUPLICATE       = $06;  
 DUPLICATE_DEREG = $07;  


{  Values for state }  

  LISTEN_OUTSTANDING      = $01;  
  CALL_PENDING            = $02;  
  SESSION_ESTABLISHED     = $03;  
  HANGUP_PENDING          = $04;  
  HANGUP_COMPLETE         = $05;  
  SESSION_ABORTED         = $06;  


#5


type  

{ Netbios Name }  
  TNBName = array[0..(NBNAMESIZE - 1)] of byte;  

{ MAC address }  
  TMacAddress = array[0..5] of byte;  

  PNCB = ^TNCB;  

 { Netbios Control Block }  

 {$IFDEF WIN32}  
  TNCBPostProc = procedure(P: PNCB);  
 {$ENDIF}  

  TNCB = packed record        { Netbios Control Block }  
    Command:  byte;      { command code                       }  
    RetCode:  byte;      { return code                        }  
    LSN:      byte;      { local session number               }  
    Num:      byte;      { name number                        }  
    Buf:      ^byte;     { data buffer                        }  
    Length:   word;      { data length                        }  
    CallName: TNBName;   { name to call                       }  
    Name:     TNBName;   { our own name                       }  
    RTO:      byte;      { receive time-out                   }  
    STO:      byte;      { send time-out                      }  
  {$IFNDEF WIN32}  
    Post_Offs:word;      { asynch notification routine offset }  
    Post_Seg: word;      { asynch notification routine segment}  
  {$ELSE}  
    PostPrc:  TNCBPostProc;{ asynch notification routine (nb30) }  
  {$ENDIF}  
    Lana_Num: byte;     { adapter number                     }  
    Cmd_Cplt: byte;     { command completion flag            }  
  {$IFDEF WIN32}  
    Reserved: array[0..9] of byte;  { Reserverd for Bios use }  
    Event:    THandle;  { WIN32 event handle to be signalled }  
                        { for asynch cmd completion          }  
  {$ELSE}  
    Reserved: array[0..13] of byte;  { Reserved }  
  {$ENDIF}  
  end;  


{ Netbios Name Info record }  
  PNameInfo = ^TNameInfo;  
  TNameInfo = packed record  { name info record }  
    Name:   TNBName;       { netbios name }  
    NameNum:byte;          { name number  }  
    NameSt: byte;          { name status  }  
  end;  

{ Netbios adapter status }  
  PAdpStat = ^TAdpStat;  
  TAdpStat = packed record    { adapter status record}  
    ID:       TMacAddress;   { adapter mac address           }  
    VMajor:   byte;          { software version major number }  
    Resvd0:   byte;  
    AdpType:  byte;          { adapter type                  }  
    VMinor:   byte;          { software version minor number }  
    RptTime:  word;          { reporting time period         }  
    RcvCRC:   word;          { receive crc errors            }  
    RcvOth:   word;          { receive other errors          }  
    TxmCol:   word;          { transmit collisions           }  
    TxmOth:   word;          { transmit other errors         }  
    TxmOK:    LongInt;       { successfull transmissions     }  
    RcvOK:    LongInt;       { successfull receives          }  
    TxmRetr:  word;          { transmit retries              }  
    NoRcvBuf: word;          { number of 'no receive buffer' }  
    T1_tmo:   word;          { t1 time-outs                  }  
    Ti_tmo:   word;          { ti time_outs                  }  
    Resvd1:   LongInt;  
    Free_Ncbs:word;          { number of free ncb's          }  
    Cfg_Ncbs: word;          { number of configured ncb's    }  
    max_Ncbs: word;          { max ncb's used                }  
    NoTxmBuf: word;          { number of 'no transmit buffer'}  
    MaxDGSize:word;          { max. datagram size            }  
    Pend_Ses: word;          { number of pending sessions    }  
    Cfg_Ses:  word;          { number of configured sessions }  
    Max_Ses:  word;          { max sessions used             }  
    Max_SPSz: word;          { max. session packet size      }  
    nNames:   word;          { number of names in local table}  
    Names:    array[0..15] of TnameInfo; { local name table  }  
  end;  

{  
   Structure returned to the NCB command NCBSSTAT is SESSION_HEADER fo 
  
llowed  
   by an array of SESSION_BUFFER structures. If the NCB_NAME starts wi 
  
th an  
   asterisk then an array of these structures is returned containing t 
  
he  
   status for all names.  
}  

{ session header }  
  PSession_Header = ^TSession_Header;  
  TSession_Header = packed record  
    sess_name:            byte;  
    num_sess:             byte;  
    rcv_dg_outstanding:   byte;  
    rcv_any_outstanding:  byte;  
  end;  

{ session buffer }  
  PSession_Buffer = ^TSession_Buffer;  
  TSession_Buffer = packed record  
    lsn:                  byte;  
    state:                byte;  
    local_name:           TNBName;  
    remote_name:          TNBName;  
    rcvs_outstanding:     byte;  
    sends_outstanding:    byte;  
  end;  

{  
   Structure returned to the NCB command NCBENUM.  

   On a system containing lana's 0, 2 and 3, a structure with  
   length =3, lana[0]=0, lana[1]=2 and lana[2]=3 will be returned.  
}  
  PLana_Enum = ^TLana_Enum;  
  TLANA_ENUM = packed record  
    length:   byte;         {  Number of valid entries in lana[] }  
    lana:     array[0..(MAXLANAS - 1)] of byte;  
  end;  

{  
   Structure returned to the NCB command NCBFINDNAME is FIND_NAME_HEAD 
  
ER followed  
   by an array of FIND_NAME_BUFFER structures.  
 }  

  PFind_Name_Header = ^TFind_Name_Header;  
  TFind_Name_Header = packed record  
    node_count:    word;  
    reserved:      byte;  
    unique_group:  byte;  
  end;  

  PFind_Name_Buffer = ^TFind_Name_Buffer;  
  TFind_Name_Buffer = packed record  
    length:          byte;  
    access_control:  byte;  
    frame_control:   byte;  
    destination_addr:TMacAddress;  
    source_addr:     TMacAddress;  
    routing_info:    array[0..17] of byte;  
  end;  

{  
   Structure provided with NCBACTION. The purpose of NCBACTION is to p 
  
rovide  
   transport specific extensions to netbios.  
 }  

  PAction_Header = ^TAction_Header;  
  TAction_Header = packed record  
    transport_id: LongInt;  
    action_code:  Word;  
    reserved:     Word;  
  end;  



{$IFDEF WIN32}  
  function Netbios(P: PNCB): Char; stdcall;  
{$ENDIF}  

{ Exposed functions }  


function NetbiosCmd(var NCB: TNCB): Word;  


implementation  

{$IFDEF WIN32}  
function Netbios; external 'netapi32.dll' name 'Netbios';  
{$ENDIF}  

{---------------------------------}  
{ execute a Windows Netbios Call  }  
{---------------------------------}  

function NetbiosCmd(var NCB: TNCB): Word;  
begin  
{$IFNDEF WIN32}  
  asm  
    push bp                   { save bp }  
    push ss                   { save ss }  
    push ds                   { save ds }  
    les  bx, NCB              { get segment/offset address of NCB }  
    call NetBiosCall;         { 16 bit Windows Netbios call }  
    xor  ah,ah  
    mov  @Result, ax          { store return code }  
    pop  ds                   { restore ds }  
    pop  ss                   { restore ss }  
    pop  bp                   { restore bp }  
  end;  
{$ELSE}  
  Result := Word(Netbios(PNCB(@NCB))); { 32 bit Windows Netbios call } 
  

{$ENDIF}  
end;  

end.  

#1


[转载]
在iphlpapi.dll里面有一个函数:GetAdaptersInfo() 
好像是干这个用的。说明如下: 
GetAdaptersInfo 
The GetAdaptersInfo function retrieves adapter information for the local computer. 

DWORD GetAdaptersInfo( 
  PIP_ADAPTER_INFO pAdapterInfo,    // buffer to receive data 
  PULONG pOutBufLen                 // size of data returned 
); 
Parameters 
pAdapterInfo  
[out] Pointer to a buffer that, , receives a linked list of IP_ADAPTER_INFO structures.  
pOutBufLen  
[in] Pointer to a ULONG variable that specifies the size of the buffer pointed to by the pAdapterInfo parameter. If this size is insufficient to hold the adapter information, GetAdaptersInfo fills in this variable with the required size, and returns an error code of ERROR_BUFFER_OVERFLOW.  
Return Values 
If the function succeeds, the return value is ERROR_SUCCESS. 

If the function fails, the return value is one of the following error codes. 

Value Meaning  
ERROR_BUFFER_OVERFLOW The buffer size indicated by the pOutBufLen parameter is too small to hold the adapter information. The pOutBufLen parameter points to the required size.  
ERROR_INVALID_PARAMETER The pOutBufLen parameter is NULL, or the calling process does not have read/write access to the memory pointed to by pOutBufLen, or the calling process does not have write access to the memory pointed to by the pAdapterInfo parameter.  
ERROR_NO_DATA No adapter information exists for the local computer.  
ERROR_NOT_SUPPORTED GetAdaptersInfo is not supported by the operating system running on the local computer.  
Other If the function fails, use FormatMessage to obtain the message string for the returned error.  


Requirements  
  Windows NT/2000: Requires Windows 2000. 
  Windows 95/98: Requires Windows 98. 
  Header: Declared in Iphlpapi.h.//没有 
  Library: Use Iphlpapi.lib.//没有 



IP_ADAPTER_INFO 
The IP_ADAPTER_INFO structure contains information about a particular network adapter on the local computer. 

typedef struct _IP_ADAPTER_INFO { 
  struct _IP_ADAPTER_INFO* Next; 
  DWORD ComboIndex; 
  char AdapterName[MAX_ADAPTER_NAME_LENGTH + 4]; 
  char Description[MAX_ADAPTER_DESCRIPTION_LENGTH + 4]; 
  UINT AddressLength; 
  BYTE Address[MAX_ADAPTER_ADDRESS_LENGTH]; 
  DWORD Index; 
  UINT Type; 
  UINT DhcpEnabled; 
  PIP_ADDR_STRING CurrentIpAddress; 
  IP_ADDR_STRING IpAddressList; 
  IP_ADDR_STRING GatewayList; 
  IP_ADDR_STRING DhcpServer; 
  BOOL HaveWins; 
  IP_ADDR_STRING PrimaryWinsServer; 
  IP_ADDR_STRING SecondaryWinsServer; 
  time_t LeaseObtained; 
  time_t LeaseExpires;  
} IP_ADAPTER_INFO, *PIP_ADAPTER_INFO; 
Members 
Next  
Pointer to the next adapter in the linked list of adapters.  
ComboIndex  
This member is unused.  
AdapterName[MAX_ADAPTER_NAME_LENGTH + 4]  
Specifies the name of the adapter.  
Description[MAX_ADAPTER_DESCRIPTION_LENGTH + 4]  
Specifies a description for the adapter.  
AddressLength  
Specifies the length of the hardware address for the adapter.  
Address[MAX_ADAPTER_ADDRESS_LENGTH]  
Specifies the hardware address for the adapter. //这个是不是你想要的? 
Index  
Specifies the adapter index.  
Type  
Specifies the adapter type.  
DhcpEnabled  
Specifies whether dynamic host configuration protocol (DHCP) is enabled for this adapter.  
CurrentIpAddress  
Specifies the current IP address for this adapter.  
IpAddressList  
Specifies the list of IP addresses associated with this adapter.  
GatewayList  
Specifies the IP address of the default gateway for this adapter.  
DhcpServer  
Specifies the IP address of the DHCP server for this adapter.  
HaveWins  
Specifies whether this adapter uses Windows Internet Name Service (WINS).  
PrimaryWinsServer  
Specifies the IP address of the primary WINS server.  
SecondaryWinsServer  
Specifies the IP address of the secondary WINS server.  
LeaseObtained  
Specifies the time when the current DHCP lease was obtained.  
LeaseExpires  
Specifies the time when the current DHCP lease will expire.  
Requirements  
  Windows NT/2000: Requires Windows 2000. 
  Windows 95/98: Requires Windows 98. 
  Header: Declared in Iptypes.h. 

#2


[转载]


implementation
uses SysUtils, Windows, NB30;


function GetNetBIOSAddress : string;
var  ncb  : TNCB;
  status  : TAdapterStatus;
  lanenum : TLanaEnum;

  procedure ResetAdapter (num : char);
  begin
    fillchar(ncb,sizeof(ncb),0);
    ncb.ncb_command:=char(NCBRESET);
    ncb.ncb_lana_num:=num;
    Netbios(@ncb);
  end;

var
  lanNum  : char;
  address : record
             part1 : Longint;
             part2 : Word;//Smallint;
            end absolute status;
begin
  Result:='';

  fillchar(ncb,sizeof(ncb),0);
    ncb.ncb_command:=char(NCBENUM);
    ncb.ncb_buffer:=@lanenum;
    ncb.ncb_length:=sizeof(lanenum);
  Netbios(@ncb);

  if lanenum.length=#0 then exit;
  lanNum:=lanenum.lana[0];

  ResetAdapter(lanNum);

  fillchar(ncb,sizeof(ncb),0);
    ncb.ncb_command:=char(NCBASTAT);
    ncb.ncb_lana_num:=lanNum;
    ncb.ncb_callname[0]:='*';
    ncb.ncb_buffer:=@status;
    ncb.ncb_length:=sizeof(status);
  Netbios(@ncb);
  ResetAdapter(lanNum);

  Result:=Format('%x%x',[address.part1,address.part2]);
end;

#3


unit Main;  

interface  

uses  
  SysUtils, WinTypes, WinProcs, Messages, Classes, Graphics, Controls, 
  

  Forms, Dialogs, StdCtrls,  
  Nb, ExtCtrls;  

type  
  TForm1 = class(TForm)  
    Panel1: TPanel;  
    Memo1: TMemo;  
    Panel2: TPanel;  
    Button1: TButton;  
    procedure Button1Click(Sender: TObject);  
    procedure FormCreate(Sender: TObject);  
  private  
    { Private declarations }  
  public  
    { Public declarations }  
  end;  

var  
  Form1: TForm1;  

implementation  

{$R *.DFM}  


{---------------------------------------------}  
{ enumerate the lana's  - works only on WIN32 }  
{---------------------------------------------}  
function NbLanaEnum: TLana_Enum;  
var  
  NCB: TNCB;  
  L_Enum: TLana_Enum;  
  RetCode: Word;  
begin  
{$IFDEF WIN32}  
  FillChar(NCB, SizeOf(NCB), 0);  
  FillChar(L_Enum, SizeOf(TLana_Enum), 0);  
  NCB.Command := NCB_ENUM;  
  NCB.Buf := @L_Enum;  
  NCB.Length := Sizeof(L_Enum);  
  RetCode := NetBiosCmd(NCB);  
  if RetCode <> NRC_GOODRET then begin  
    L_Enum.Length := 0;  
    L_Enum.Lana[0] := Byte(RetCode);  
  end;  
{$ELSE}                     { not supported for WIN16, fake LANA 0 }  

  L_Enum.Length := 1;  
  L_Enum.Lana[0] := 0;  
{$ENDIF}  
  Result := L_Enum;  
end;  

{----------------------------------------}  
{ Reset the lana - don't for WIN16 !     }  
{----------------------------------------}  
function NbReset(l: Byte): Word;  
var  
  NCB: TNCB;  
begin  
{$IFNDEF WIN32}             { will reset all your connections for WIN1 
  
6 }  
  Result := NRC_GOODRET;    { so just fake a reset for Win16           
  
  }  
{$ELSE}  
  FillChar(NCB, SizeOf(NCB), 0);  
  NCB.Command := NCB_RESET;  
  NCB.Lana_Num := l;  
  Result := NetBiosCmd(NCB);  
{$ENDIF}  
end;  
{----------------------------------------}  
{ return the MAC address of an interface }  
{ in the form of a string like :         }  
{ 'xx:xx:xx:xx:xx:xx'                    }  
{ using the definitions in nb.pas        }  
{----------------------------------------}  

function NbGetMacAddr(LanaNum: Integer): String;  
var  
  NCB: TNCB;  
  AdpStat: TAdpStat;  
  RetCode: Word;  
begin  
  FillChar(NCB, SizeOf(NCB), 0);  
  FillChar(AdpStat, SizeOf(AdpStat), 0);  
  NCB.Command := NCB_ADPSTAT;  
  NCB.Buf := @AdpStat;  
  NCB.Length := Sizeof(AdpStat);  
  FillChar(NCB.CallName, Sizeof(TNBName), $20);  
  NCB.CallName[0] := Byte('*');  
  NCB.Lana_Num := LanaNum;  
  RetCode := NetBiosCmd(NCB);  
  if RetCode = NRC_GOODRET then begin  
    Result := Format('%2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x',  
                   [AdpStat.ID[0],  
                   AdpStat.ID[1],  
                   AdpStat.ID[2],  
                   AdpStat.ID[3],  
                   AdpStat.ID[4],  
                   AdpStat.ID[5]  
                   ]);  
  end else begin  
    Result := '??:??:??:??:??:??';  
  end;  
end;  


procedure TForm1.Button1Click(Sender: TObject);  
begin  
  Close;  
end;  

procedure TForm1.FormCreate(Sender: TObject);  
var  
  L_Enum : TLana_Enum;  
  RetCode: Word;  
  i: Integer;  
begin  
  L_Enum := NbLanaEnum;                       { enumerate lanas for WI 
  
N NT }  
  if L_Enum.Length = 0 then begin  
    Button1.Caption := Format('LanaEnum err=%2.2x', [L_Enum.Lana[0]]); 
  

    exit;  
  end;  

  for i := 0 to (L_Enum.Length - 1)do begin   { for every lana found   
  
     }  

    RetCode := NbReset(L_Enum.Lana[i]);       { Reset lana for WIN NT  
  
     }  
    if RetCode <> NRC_GOODRET then begin  
       Button1.Caption := Format('Reset Lana %d err=%2.2x',[i, RetCode 
  
]);  
       exit;  
    end;  
                                             { Get MAC Address         
  
     }  
    Memo1.Lines.Add(Format('Lana %x = %s', [L_Enum.Lana[i], NbGetMacAd 
  
dr(i)]));  

  end;  

  Button1.Caption := 'Stop';  
end;  

end.  
---------------------------------- -  


#4


unit Nb;  

{$F+}  

{  nb.pas  

   16/32 bit windows netbios access (follows IBM's Netbios 3.0 spec)  


   (C) CEVI VZW - 29 april 1998     -- DH (Danny.Heijl@cevi.be) --  

   You can (ab)use this code as you like, but please do not remove the 
  
 credits.  

   I used reference material from IBM, Microsoft, Syntax and Byte when 
  
 I wrote  
   the 16-bit (DOS) c-version ages ago (in Borland Turbo C 2.0 on a 38 
  
6SX PC)  
   with a Syntax SMB server running on Interactive Unix.  
   I now converted this to 16 and 32 bit Delphi code.  

}  

interface  


uses SysUtils, Winprocs, Wintypes;  

const  


{ size of a netbios name }  
  NBNAMESIZE    = 16;  

{ max number of network adapters }  
{ remeber it's BIG Blue, right ? }  
  MAXLANAS      = 254;  

{ NCB Command codes }  

  NCB_ASYNC     = $80;   { asynch command bit to be or-ed into command 
  
 }  

  NCB_CALL      = $10;   { open a session }  
  NCB_LISTEN    = $11;   { wait for a call }  
  NCB_HANGUP    = $12;   { end session }  
  NCB_SEND      = $14;   { send data }  
  NCB_RECV      = $15;   { receive data }  
  NCB_RECVANY   = $16;   { receive data on any session }  
  NCB_CHAINSEND = $17;   { chain send data }  
  NCB_DGSEND    = $20;   { send a datagram }  
  NCB_DGRECV    = $21;   { receive datagram }  
  NCB_DGSENDBC  = $22;   { send broadcast datagram }  
  NCB_DGREVCBC  = $23;   { receive broadcast datagram }  
  NCB_ADDNAME   = $30;   { add unique name to local table }  
  NCB_DELNAME   = $31;   { delete name from local table }  
  NCB_RESET     = $32;   { reset adapter }  
  NCB_ADPSTAT   = $33;   { adapter status }  
  NCB_SSTAT     = $34;   { session status }  
  NCB_CANCEL    = $35;   { cancel NCB request }  
  NCB_ADDGRPNAME= $36;   { add group name to local table }  
  NCB_ENUM      = $37;   { enum adapters }  
  NCB_UNLINK    = $70;   { unlink remote boot code }  
  NCB_SENDNA    = $71;   { send, don't wait for ACK }  
  NCB_CHAINSENDNA=$72;   { chain send, but don't wait for ACK }  
  NCB_LANSTALERT= $73;   { lan status alert }  
  NCB_ACTION    = $77;   { enable extensions }  
  NCB_FINDNAME  = $78;   { search for name on the network }  
  NCB_TRACE     = $79;   { activate / stop tracing }  

{ NCB return codes }  

  NRC_GOODRET     = $00;    { good return  
                              also returned when ASYNCH request accept 
  
ed }  
  NRC_BUFLEN      = $01;    { illegal buffer length                    
  
   }  
  NRC_ILLCMD      = $03;    { illegal command                          
  
   }  
  NRC_CMDTMO      = $05;    { command timed out                        
  
   }  
  NRC_INCOMP      = $06;    { message incomplete, issue another comman 
  
d  }  
  NRC_BADDR       = $07;    { illegal buffer address                   
  
   }  
  NRC_SNUMOUT     = $08;    { session number out of range              
  
   }  
  NRC_NORES       = $09;    { no resource available                    
  
   }  
  NRC_SCLOSED     = $0a;    { session closed                           
  
   }  
  NRC_CMDCAN      = $0b;    { command cancelled                        
  
   }  
  NRC_DUPNAME     = $0d;    { duplicate name                           
  
   }  
  NRC_NAMTFUL     = $0e;    { name table full                          
  
   }  
  NRC_ACTSES      = $0f;    { no deletions, name has active sessions   
  
   }  
  NRC_LOCTFUL     = $11;    { local session table full                 
  
   }  
  NRC_REMTFUL     = $12;    { remote session table full                
  
   }  
  NRC_ILLNN       = $13;    { illegal name number                      
  
   }  
  NRC_NOCALL      = $14;    { no callname                              
  
   }  
  NRC_NOWILD      = $15;    { cannot put * in NCB_NAME                 
  
   }  
  NRC_INUSE       = $16;    { name in use on remote adapter            
  
   }  
  NRC_NAMERR      = $17;    { name deleted                             
  
   }  
  NRC_SABORT      = $18;    { session ended abnormally                 
  
   }  
  NRC_NAMCONF     = $19;    { name conflict detected                   
  
   }  
  NRC_IFBUSY      = $21;    { interface busy, IRET before retrying     
  
   }  
  NRC_TOOMANY     = $22;    { too many commands outstanding, retry lat 
  
er }  
  NRC_BRIDGE      = $23;    { ncb_lana_num field invalid               
  
   }  
  NRC_CANOCCR     = $24;    { command completed while cancel occurring 
  
   }  
  NRC_CANCEL      = $26;    { command not valid to cancel              
  
   }  
  NRC_DUPENV      = $30;    { name defined by anther local process     
  
   }  
  NRC_ENVNOTDEF   = $34;    { environment undefined. RESET required    
  
   }  
  NRC_OSRESNOTAV  = $35;    { required OS resources exhausted          
  
   }  
  NRC_MAXAPPS     = $36;    { max number of applications exceeded      
  
   }  
  NRC_NOSAPS      = $37;    { no saps available for netbios            
  
   }  
  NRC_NORESOURCES = $38;    { requested resources are not available    
  
   }  
  NRC_INVADDRESS  = $39;    { invalid ncb address or length > segment  
  
   }  
  NRC_INVDDID     = $3B;    { invalid NCB DDID                         
  
   }  
  NRC_LOCKFAIL    = $3C;    { lock of user area failed                 
  
   }  
  NRC_OPENERR     = $3f;    { NETBIOS not loaded                       
  
   }  
  NRC_SYSTEM      = $40;    { system error                             
  
   }  

  NRC_PENDING     = $ff;    { asynchronous command is not yet finished 
  
   }  

{  Values for transport_id }  

 ALL_TRANSPORTS = 'M'#$00#$00#$00;  
 MS_NBF         = 'MNBF';  


{  values for name_flags bits. }  

 NAME_FLAGS_MASK = $87;  

 GROUP_NAME      = $80;  
 UNIQUE_NAME     = $00;  

 REGISTERING     = $00;  
 REGISTERED      = $04;  
 DEREGISTERED    = $05;  
 DUPLICATE       = $06;  
 DUPLICATE_DEREG = $07;  


{  Values for state }  

  LISTEN_OUTSTANDING      = $01;  
  CALL_PENDING            = $02;  
  SESSION_ESTABLISHED     = $03;  
  HANGUP_PENDING          = $04;  
  HANGUP_COMPLETE         = $05;  
  SESSION_ABORTED         = $06;  


#5


type  

{ Netbios Name }  
  TNBName = array[0..(NBNAMESIZE - 1)] of byte;  

{ MAC address }  
  TMacAddress = array[0..5] of byte;  

  PNCB = ^TNCB;  

 { Netbios Control Block }  

 {$IFDEF WIN32}  
  TNCBPostProc = procedure(P: PNCB);  
 {$ENDIF}  

  TNCB = packed record        { Netbios Control Block }  
    Command:  byte;      { command code                       }  
    RetCode:  byte;      { return code                        }  
    LSN:      byte;      { local session number               }  
    Num:      byte;      { name number                        }  
    Buf:      ^byte;     { data buffer                        }  
    Length:   word;      { data length                        }  
    CallName: TNBName;   { name to call                       }  
    Name:     TNBName;   { our own name                       }  
    RTO:      byte;      { receive time-out                   }  
    STO:      byte;      { send time-out                      }  
  {$IFNDEF WIN32}  
    Post_Offs:word;      { asynch notification routine offset }  
    Post_Seg: word;      { asynch notification routine segment}  
  {$ELSE}  
    PostPrc:  TNCBPostProc;{ asynch notification routine (nb30) }  
  {$ENDIF}  
    Lana_Num: byte;     { adapter number                     }  
    Cmd_Cplt: byte;     { command completion flag            }  
  {$IFDEF WIN32}  
    Reserved: array[0..9] of byte;  { Reserverd for Bios use }  
    Event:    THandle;  { WIN32 event handle to be signalled }  
                        { for asynch cmd completion          }  
  {$ELSE}  
    Reserved: array[0..13] of byte;  { Reserved }  
  {$ENDIF}  
  end;  


{ Netbios Name Info record }  
  PNameInfo = ^TNameInfo;  
  TNameInfo = packed record  { name info record }  
    Name:   TNBName;       { netbios name }  
    NameNum:byte;          { name number  }  
    NameSt: byte;          { name status  }  
  end;  

{ Netbios adapter status }  
  PAdpStat = ^TAdpStat;  
  TAdpStat = packed record    { adapter status record}  
    ID:       TMacAddress;   { adapter mac address           }  
    VMajor:   byte;          { software version major number }  
    Resvd0:   byte;  
    AdpType:  byte;          { adapter type                  }  
    VMinor:   byte;          { software version minor number }  
    RptTime:  word;          { reporting time period         }  
    RcvCRC:   word;          { receive crc errors            }  
    RcvOth:   word;          { receive other errors          }  
    TxmCol:   word;          { transmit collisions           }  
    TxmOth:   word;          { transmit other errors         }  
    TxmOK:    LongInt;       { successfull transmissions     }  
    RcvOK:    LongInt;       { successfull receives          }  
    TxmRetr:  word;          { transmit retries              }  
    NoRcvBuf: word;          { number of 'no receive buffer' }  
    T1_tmo:   word;          { t1 time-outs                  }  
    Ti_tmo:   word;          { ti time_outs                  }  
    Resvd1:   LongInt;  
    Free_Ncbs:word;          { number of free ncb's          }  
    Cfg_Ncbs: word;          { number of configured ncb's    }  
    max_Ncbs: word;          { max ncb's used                }  
    NoTxmBuf: word;          { number of 'no transmit buffer'}  
    MaxDGSize:word;          { max. datagram size            }  
    Pend_Ses: word;          { number of pending sessions    }  
    Cfg_Ses:  word;          { number of configured sessions }  
    Max_Ses:  word;          { max sessions used             }  
    Max_SPSz: word;          { max. session packet size      }  
    nNames:   word;          { number of names in local table}  
    Names:    array[0..15] of TnameInfo; { local name table  }  
  end;  

{  
   Structure returned to the NCB command NCBSSTAT is SESSION_HEADER fo 
  
llowed  
   by an array of SESSION_BUFFER structures. If the NCB_NAME starts wi 
  
th an  
   asterisk then an array of these structures is returned containing t 
  
he  
   status for all names.  
}  

{ session header }  
  PSession_Header = ^TSession_Header;  
  TSession_Header = packed record  
    sess_name:            byte;  
    num_sess:             byte;  
    rcv_dg_outstanding:   byte;  
    rcv_any_outstanding:  byte;  
  end;  

{ session buffer }  
  PSession_Buffer = ^TSession_Buffer;  
  TSession_Buffer = packed record  
    lsn:                  byte;  
    state:                byte;  
    local_name:           TNBName;  
    remote_name:          TNBName;  
    rcvs_outstanding:     byte;  
    sends_outstanding:    byte;  
  end;  

{  
   Structure returned to the NCB command NCBENUM.  

   On a system containing lana's 0, 2 and 3, a structure with  
   length =3, lana[0]=0, lana[1]=2 and lana[2]=3 will be returned.  
}  
  PLana_Enum = ^TLana_Enum;  
  TLANA_ENUM = packed record  
    length:   byte;         {  Number of valid entries in lana[] }  
    lana:     array[0..(MAXLANAS - 1)] of byte;  
  end;  

{  
   Structure returned to the NCB command NCBFINDNAME is FIND_NAME_HEAD 
  
ER followed  
   by an array of FIND_NAME_BUFFER structures.  
 }  

  PFind_Name_Header = ^TFind_Name_Header;  
  TFind_Name_Header = packed record  
    node_count:    word;  
    reserved:      byte;  
    unique_group:  byte;  
  end;  

  PFind_Name_Buffer = ^TFind_Name_Buffer;  
  TFind_Name_Buffer = packed record  
    length:          byte;  
    access_control:  byte;  
    frame_control:   byte;  
    destination_addr:TMacAddress;  
    source_addr:     TMacAddress;  
    routing_info:    array[0..17] of byte;  
  end;  

{  
   Structure provided with NCBACTION. The purpose of NCBACTION is to p 
  
rovide  
   transport specific extensions to netbios.  
 }  

  PAction_Header = ^TAction_Header;  
  TAction_Header = packed record  
    transport_id: LongInt;  
    action_code:  Word;  
    reserved:     Word;  
  end;  



{$IFDEF WIN32}  
  function Netbios(P: PNCB): Char; stdcall;  
{$ENDIF}  

{ Exposed functions }  


function NetbiosCmd(var NCB: TNCB): Word;  


implementation  

{$IFDEF WIN32}  
function Netbios; external 'netapi32.dll' name 'Netbios';  
{$ENDIF}  

{---------------------------------}  
{ execute a Windows Netbios Call  }  
{---------------------------------}  

function NetbiosCmd(var NCB: TNCB): Word;  
begin  
{$IFNDEF WIN32}  
  asm  
    push bp                   { save bp }  
    push ss                   { save ss }  
    push ds                   { save ds }  
    les  bx, NCB              { get segment/offset address of NCB }  
    call NetBiosCall;         { 16 bit Windows Netbios call }  
    xor  ah,ah  
    mov  @Result, ax          { store return code }  
    pop  ds                   { restore ds }  
    pop  ss                   { restore ss }  
    pop  bp                   { restore bp }  
  end;  
{$ELSE}  
  Result := Word(Netbios(PNCB(@NCB))); { 32 bit Windows Netbios call } 
  

{$ENDIF}  
end;  

end.