📄 netbeui.pas
字号:
unit NetBEUI;
//{$define NCB_CHECK}
interface
uses SysUtils,windows,winsock,nb30,classes,dialogs;
type
TNetBEUI=class(TComponent)
protected
pNetBiosInfo:PNameBuffer;
FMacAddr:string;
FLocalName,FRemoteName:String;
FAdapterType:BYTE;
FNameList:TList;
procedure NBCheck(ncb:TNCB);
procedure MakeNetbiosName(var Dest:array of char;Src:string);
function NBReset(nLana,nSessions,nNames:integer):Boolean;
function NBListNames(nLana:Integer;strHostName:string):Boolean;
function NBAdapterStatus(nLana:Integer;pBuf:PChar;bufLen:Integer;strHostName:String):Boolean;
procedure GetHostNames(strRemoteIp:String);
function GetErrorMsg(rc:char):string;
public
constructor Create(AOwner:TComponent);override;
destructor Destroy;override;
function GetNetBiosStatus(IpAddr:String):Boolean;
function GetMACAddr:string;
function GetNetBiosNameList:TList;
function GetRemoteHostName:string;
function GetAdapterType:BYTE;
class function GetLocalMAC:String;
end;
const
LANANUM=0;
DIALUP=$FF;
ETHERNET=$FE;
implementation
{ TNetBEUI }
constructor TNetBEUI.Create(AOwner:TComponent);
begin
Inherited;
FNameList:=TList.Create;
end;
destructor TNetBEUI.Destroy;
var
i:Integer;
begin
for i:=0 to FNameList.Count-1 do
begin
FreeMem(FNameList.Items[i]);
end;
Inherited;
end;
function TNetBEUI.GetAdapterType: BYTE;
begin
Result:=FAdapterType;
end;
function TNetBEUI.GetErrorMsg(rc: char): string;
begin
case rc of
Chr($00) : Result := 'good return' ;
Chr($01) : Result := 'illegal buffer length' ;
Chr($03) : Result := 'illegal command' ;
Chr($05) : Result := 'command timed out' ;
Chr($06) : Result := 'message incomplete, issue another command' ;
Chr($07) : Result := 'illegal buffer address' ;
Chr($08) : Result := 'session number out of range' ;
Chr($09) : Result := 'no resource available' ;
Chr($0a) : Result := 'session closed' ;
Chr($0b) : Result := 'command cancelled' ;
Chr($0d) : Result := 'duplicate name' ;
Chr($0e) : Result := 'name table full' ;
Chr($0f) : Result := 'no deletions, name has active sessions' ;
Chr($11) : Result := 'local session table full' ;
Chr($12) : Result := 'remote session table full' ;
Chr($13) : Result := 'illegal name number' ;
Chr($14) : Result := 'no callname' ;
Chr($15) : Result := 'cannot put * in NCB_NAME' ;
Chr($16) : Result := 'name in use on remote adapter' ;
Chr($17) : Result := 'name deleted' ;
Chr($18) : Result := 'session ended abnormally' ;
Chr($19) : Result := 'name conflict detected' ;
Chr($21) : Result := 'interface busy, IRET before retrying' ;
Chr($22) : Result := 'too many commands outstanding, retry later' ;
Chr($23) : Result := 'NCB_lana_num field invalid' ;
Chr($24) : Result := 'command completed while cancel occurring' ;
Chr($26) : Result := 'command not valid to cancel' ;
Chr($30) : Result := 'name defined by anther local process' ;
Chr($34) : Result := 'environment undefined. RESET required' ;
Chr($35) : Result := 'required OS resources exhausted' ;
Chr($36) : Result := 'max number of applications exceeded' ;
Chr($37) : Result := 'no saps available for netbios' ;
Chr($38) : Result := 'requested resources are not available' ;
Chr($39) : Result := 'invalid ncb address or length > segment' ;
Chr($3B) : Result := 'invalid NCB DDID' ;
Chr($3C) : Result := 'lock of user area failed' ;
Chr($3f) : Result := 'NETBIOS not loaded' ;
Chr($40) : Result := 'system error' ;
Chr($ff) : Result := 'asynchronous command is not yet finished' ;
else Result := 'unknown'
end ;
end;
procedure TNetBEUI.GetHostNames(strRemoteIp: String);
var
ent:PHostEnt;
addr:DWORD;
begin
addr:=inet_addr(PChar(strRemoteIp));
ent:=gethostbyaddr(@addr,4,AF_INET);
if(ent<>nil)then FRemoteName:=ent.h_name
else FRemoteName:='无法获得';
//FreeMem(ent);
end;
function HexBL(vv: Byte): String;
begin
// result:=D2H(vv , 2)+' '//十进制转十六进制;
Result:=Format('%X',[vv]);
end;
class function TNetBEUI.GetLocalMAC: String;
var
NCB : TNCB ; // Netbios control block //NetBios控制块
ADAPTER : TADAPTERSTATUS ; // Netbios adapter status//取网卡状态
LANAENUM : TLANAENUM ; // Netbios lana
intIdx : Integer ; // Temporary work value//临时变量
cRC : Char ; // Netbios return code//NetBios返回值
strTemp : String ; // Temporary string//临时变量
begin
// Initialize
Result := '' ;
try
// Zero control blocl
ZeroMemory(@NCB,SizeOf(NCB)) ;
// Issue enum command
NCB.ncb_command := Chr(NCBENUM) ;
//cRC := NetBios(@NCB) ;//Modify by Gale
NetBios(@NCB);
// Reissue enum command
NCB.ncb_buffer := @LANAENUM ;
NCB.ncb_length := SizeOf(LANAENUM) ;
cRC := NetBios(@NCB) ;
if Ord(cRC)<>0 then
exit ;
// Reset adapter
ZeroMemory(@NCB,SizeOf(NCB)) ;
NCB.ncb_command := Chr(NCBRESET) ;
NCB.ncb_lana_num := LANAENUM.lana[0] ;
cRC := NetBios(@NCB) ;
if Ord(cRC)<>0 then
exit ;
// Get adapter address
ZeroMemory(@NCB,SizeOf(NCB)) ;
NCB.ncb_command := Chr(NCBASTAT) ;
NCB.ncb_lana_num := LANAENUM.lana[0] ;
StrPCopy(NCB.ncb_callname,'*') ;
NCB.ncb_buffer := @ADAPTER ;
NCB.ncb_length := SizeOf(ADAPTER) ;
//cRC := NetBios(@NCB) ;//Modify by Gale remove Hint:'cRC' never used
NetBios(@NCB);
// Convert it to string
strTemp := HexBL(Byte(ADAPTER.Adapter_Address[0]));
for intIdx := 1 to 5 do
strTemp := strTemp+':'+HexBL(Byte(ADAPTER.adapter_address[intIdx]));
Result := strTemp ;
finally
end ;
end;
function TNetBEUI.GetMACAddr: string;
begin
Result:=FMacAddr;
end;
function TNetBEUI.GetNetBiosNameList:TList;
begin
Result:=FNameList;
end;
function TNetBEUI.GetNetBiosStatus(IpAddr: String): Boolean;
begin
if (NBReset (LANANUM, 10, 10))then
begin
if (NBListNames (LANANUM,IpAddr))then
begin
Result:=True;
end
else Result:=False;
end
else result:=False;
end;
function TNetBEUI.GetRemoteHostName: string;
begin
Result:=FRemoteName;
end;
procedure TNetBEUI.MakeNetbiosName(var Dest:array of char; Src: string);
var
l,i:Integer;
begin
l:=Length(Src);//cchSrc = lstrlen (szSrc);
if(l>NCBNAMSZ)then l:=NCBNAMSZ; //if (cchSrc > NCBNAMSZ) cchSrc = NCBNAMSZ;
//for i:=0 to NCBNAMSZ-l do Dest[i]:=chr($20);
FillMemory(@Dest,NCBNAMSZ,$20);
for i:=1 to l do Dest[i-1]:=Src[i];
end;
function TNetBEUI.NBAdapterStatus(nLana: Integer; pBuf: PChar;
bufLen: Integer; strHostName: String): Boolean;
var
ncb:TNCB;
begin
ZeroMemory(@ncb,sizeof(ncb));
ncb.ncb_command := chr(NCBASTAT);
ncb.ncb_lana_num := chr(nLana);
ncb.ncb_buffer :=pBuf;
ncb.ncb_length := bufLen;
ncb.ncb_rto:=chr(10);
ncb.ncb_sto:=chr(2);
MakeNetbiosName (ncb.ncb_callname, strHostName);
Netbios (@ncb);
NBCheck (ncb);
Result:=(chr(NRC_GOODRET) = ncb.ncb_retcode);
end;
procedure TNetBEUI.NBCheck(ncb: TNCB);
begin
{$ifdef NCB_CHECK}
if(ncb.ncb_retcode<>chr(NRC_GOODRET))then
ShowMessage(GetErrorMsg(ncb.ncb_retcode));
{$endif}
end;
function TNetBEUI.NBListNames(nLana: Integer;
strHostName: string): Boolean;
var
i,bufLen:Integer;
pStatus:PAdapterStatus;
pNames:PNameBuffer;
begin
GetHostNames(PChar(strHostName));
// Allocate the largest buffer that might be needed.
bufLen:= sizeof (TAdapterStatus) + 255 * sizeof (TNameBuffer);
pStatus:= AllocMem(bufLen); //(ADAPTER_STATUS *) HeapAlloc (hHeap, 0, cbBuffer);
if(pStatus=nil)then
begin
Result:=False;
Exit;
end;
if (not NBAdapterStatus (nLana,Pointer(pStatus),bufLen, strHostName))then
begin
FreeMem(pStatus);
Result:=False;
Exit;
end;
// The list of names follows the adapter status structure.
pNames :=PNameBuffer(
PChar(pStatus)
+sizeof(TAdapterStatus)
);
{FMacAddr:=format('%02x_%02x_%02x_%02x_%02x_%02x',
[Ord(pStatus.adapter_address[0]),
Ord(pStatus.adapter_address[1]),
Ord(pStatus.adapter_address[2]),
Ord(pStatus.adapter_address[3]),
Ord(pStatus.adapter_address[4]),
Ord(pStatus.adapter_address[5])]);}
FMacAddr:=
IntToHex(Ord(pStatus.adapter_address[0]),2)+'-'+
IntToHex(Ord(pStatus.adapter_address[1]),2)+'-'+
IntToHex(Ord(pStatus.adapter_address[2]),2)+'-'+
IntToHex(Ord(pStatus.adapter_address[3]),2)+'-'+
IntToHex(Ord(pStatus.adapter_address[4]),2)+'-'+
IntToHex(Ord(pStatus.adapter_address[5]),2);
FAdapterType:=BYTE(pStatus.adapter_type);
for i:= 0 to pStatus.name_count-1 do
begin
pNetBiosInfo:=AllocMem(sizeof(TNameBuffer));
// pNetBiosInfo^:=(pNames)[i];
pNetBiosInfo^:=PNameBuffer(PChar(pNames)+sizeof(TNameBuffer)*i)^;
FNameList.Add(pNetBiosInfo);
end;
FreeMem(pStatus);
Result:=True;
end;
function TNetBEUI.NBReset(nLana, nSessions, nNames: integer): Boolean;
var
ncb:TNCB;
begin
{
NCB ncb;
memset (&ncb, 0, sizeof (ncb));
ncb.ncb_command = NCBRESET;
ncb.ncb_lsn = 0; // Allocate new lana_num resources
ncb.ncb_lana_num = nLana;
ncb.ncb_callname[0] = nSessions; // maximum sessions
ncb.ncb_callname[2] = nNames; // maximum names
Netbios (&ncb);
NBCheck (ncb);
return (NRC_GOODRET == ncb.ncb_retcode);
}
ZeroMemory(@ncb,sizeof(ncb));
ncb.ncb_command := chr(NCBRESET);
ncb.ncb_lsn := chr(0); // Allocate new lana_num resources
ncb.ncb_lana_num := chr(nLana);
ncb.ncb_callname[0] := chr(nSessions); // maximum sessions
ncb.ncb_callname[2] := chr(nNames); // maximum names
Netbios (@ncb);
//NBCheck (ncb);
//Result:=(chr(NRC_GOODRET) = ncb.ncb_retcode);
Result:=true;
end;
end.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -