NetBEUI.pas
上传用户:hbtcygglw
上传日期:2007-01-07
资源大小:281k
文件大小:10k
源码类别:

其他

开发平台:

Delphi

  1. unit NetBEUI;
  2. //{$define NCB_CHECK}
  3. interface
  4. uses SysUtils,windows,winsock,nb30,classes,dialogs;
  5. type
  6. TNetBEUI=class(TComponent)
  7.     protected
  8.     pNetBiosInfo:PNameBuffer;
  9.     FMacAddr:string;
  10.     FLocalName,FRemoteName:String;
  11.     FAdapterType:BYTE;
  12.     FNameList:TList;
  13.     procedure NBCheck(ncb:TNCB);
  14.     procedure MakeNetbiosName(var Dest:array of char;Src:string);
  15.     function  NBReset(nLana,nSessions,nNames:integer):Boolean;
  16.     function  NBListNames(nLana:Integer;strHostName:string):Boolean;
  17.     function  NBAdapterStatus(nLana:Integer;pBuf:PChar;bufLen:Integer;strHostName:String):Boolean;
  18.     procedure GetHostNames(strRemoteIp:String);
  19.     function  GetErrorMsg(rc:char):string;
  20.     public
  21.     constructor Create(AOwner:TComponent);override;
  22.     destructor  Destroy;override;
  23.     function  GetNetBiosStatus(IpAddr:String):Boolean;
  24.     function GetMACAddr:string;
  25.     function  GetNetBiosNameList:TList;
  26.     function  GetRemoteHostName:string;
  27.     function  GetAdapterType:BYTE;
  28.     class function GetLocalMAC:String;
  29.     end;
  30. const
  31. LANANUM=0;
  32. DIALUP=$FF;
  33. ETHERNET=$FE;
  34. implementation
  35. { TNetBEUI }
  36. constructor TNetBEUI.Create(AOwner:TComponent);
  37. begin
  38. Inherited;
  39. FNameList:=TList.Create;
  40. end;
  41. destructor TNetBEUI.Destroy;
  42. var
  43. i:Integer;
  44. begin
  45. for i:=0 to FNameList.Count-1 do
  46.     begin
  47.     FreeMem(FNameList.Items[i]);
  48.     end;
  49. Inherited;
  50. end;
  51. function TNetBEUI.GetAdapterType: BYTE;
  52. begin
  53. Result:=FAdapterType;
  54. end;
  55. function TNetBEUI.GetErrorMsg(rc: char): string;
  56. begin
  57. case rc of
  58.       Chr($00) : Result := 'good return' ;
  59.       Chr($01) : Result := 'illegal buffer length' ;
  60.       Chr($03) : Result := 'illegal command' ;
  61.       Chr($05) : Result := 'command timed out' ;
  62.       Chr($06) : Result := 'message incomplete, issue another command' ;
  63.       Chr($07) : Result := 'illegal buffer address' ;
  64.       Chr($08) : Result := 'session number out of range' ;
  65.       Chr($09) : Result := 'no resource available' ;
  66.       Chr($0a) : Result := 'session closed' ;
  67.       Chr($0b) : Result := 'command cancelled' ;
  68.       Chr($0d) : Result := 'duplicate name' ;
  69.       Chr($0e) : Result := 'name table full' ;
  70.       Chr($0f) : Result := 'no deletions, name has active sessions' ;
  71.       Chr($11) : Result := 'local session table full' ;
  72.       Chr($12) : Result := 'remote session table full' ;
  73.       Chr($13) : Result := 'illegal name number' ;
  74.       Chr($14) : Result := 'no callname' ;
  75.       Chr($15) : Result := 'cannot put * in NCB_NAME' ;
  76.       Chr($16) : Result := 'name in use on remote adapter' ;
  77.       Chr($17) : Result := 'name deleted' ;
  78.       Chr($18) : Result := 'session ended abnormally' ;
  79.       Chr($19) : Result := 'name conflict detected' ;
  80.       Chr($21) : Result := 'interface busy, IRET before retrying' ;
  81.       Chr($22) : Result := 'too many commands outstanding, retry later' ;
  82.       Chr($23) : Result := 'NCB_lana_num field invalid' ;
  83.       Chr($24) : Result := 'command completed while cancel occurring' ;
  84.       Chr($26) : Result := 'command not valid to cancel' ;
  85.       Chr($30) : Result := 'name defined by anther local process' ;
  86.       Chr($34) : Result := 'environment undefined. RESET required' ;
  87.       Chr($35) : Result := 'required OS resources exhausted' ;
  88.       Chr($36) : Result := 'max number of applications exceeded' ;
  89.       Chr($37) : Result := 'no saps available for netbios' ;
  90.       Chr($38) : Result := 'requested resources are not available' ;
  91.       Chr($39) : Result := 'invalid ncb address or length > segment' ;
  92.       Chr($3B) : Result := 'invalid NCB DDID' ;
  93.       Chr($3C) : Result := 'lock of user area failed' ;
  94.       Chr($3f) : Result := 'NETBIOS not loaded' ;
  95.       Chr($40) : Result := 'system error' ;
  96.       Chr($ff) : Result := 'asynchronous command is not yet finished' ;
  97.       else Result := 'unknown'
  98.     end ;
  99. end;
  100. procedure TNetBEUI.GetHostNames(strRemoteIp: String);
  101. var
  102. ent:PHostEnt;
  103. addr:DWORD;
  104. begin
  105. addr:=inet_addr(PChar(strRemoteIp));
  106. ent:=gethostbyaddr(@addr,4,AF_INET);
  107. if(ent<>nil)then FRemoteName:=ent.h_name
  108. else FRemoteName:='无法获得';
  109. //FreeMem(ent);
  110. end;
  111. function HexBL(vv: Byte): String;
  112. begin
  113. //  result:=D2H(vv , 2)+' '//十进制转十六进制;
  114. Result:=Format('%X',[vv]);
  115. end;
  116. class function TNetBEUI.GetLocalMAC: String;
  117. var
  118. NCB : TNCB ; // Netbios control block //NetBios控制块
  119. ADAPTER : TADAPTERSTATUS ; // Netbios adapter status//取网卡状态
  120. LANAENUM : TLANAENUM ; // Netbios lana
  121. intIdx : Integer ; // Temporary work value//临时变量
  122. cRC : Char ; // Netbios return code//NetBios返回值
  123. strTemp : String ; // Temporary string//临时变量
  124. begin
  125. // Initialize
  126. Result := '' ;
  127. try
  128.     // Zero control blocl
  129.     ZeroMemory(@NCB,SizeOf(NCB)) ;
  130.     // Issue enum command
  131.     NCB.ncb_command := Chr(NCBENUM) ;
  132.     //cRC := NetBios(@NCB) ;//Modify by Gale
  133.     NetBios(@NCB);
  134.     // Reissue enum command
  135.     NCB.ncb_buffer := @LANAENUM ;
  136.     NCB.ncb_length := SizeOf(LANAENUM) ;
  137.     cRC := NetBios(@NCB) ;
  138.     if Ord(cRC)<>0 then
  139.         exit ;
  140.     // Reset adapter
  141.     ZeroMemory(@NCB,SizeOf(NCB)) ;
  142.     NCB.ncb_command := Chr(NCBRESET) ;
  143.     NCB.ncb_lana_num := LANAENUM.lana[0] ;
  144.     cRC := NetBios(@NCB) ;
  145.     if Ord(cRC)<>0 then
  146.         exit ;
  147.     // Get adapter address
  148.     ZeroMemory(@NCB,SizeOf(NCB)) ;
  149.     NCB.ncb_command := Chr(NCBASTAT) ;
  150.     NCB.ncb_lana_num := LANAENUM.lana[0] ;
  151.     StrPCopy(NCB.ncb_callname,'*') ;
  152.     NCB.ncb_buffer := @ADAPTER ;
  153.     NCB.ncb_length := SizeOf(ADAPTER) ;
  154.     //cRC := NetBios(@NCB) ;//Modify by Gale remove Hint:'cRC' never used
  155.     NetBios(@NCB);
  156.     // Convert it to string
  157.     strTemp := HexBL(Byte(ADAPTER.Adapter_Address[0]));
  158.     for intIdx := 1 to 5 do
  159.         strTemp := strTemp+':'+HexBL(Byte(ADAPTER.adapter_address[intIdx]));
  160.     Result := strTemp ;
  161. finally
  162.     end ;
  163. end;
  164. function TNetBEUI.GetMACAddr: string;
  165. begin
  166. Result:=FMacAddr;
  167. end;
  168. function TNetBEUI.GetNetBiosNameList:TList;
  169. begin
  170. Result:=FNameList;
  171. end;
  172. function TNetBEUI.GetNetBiosStatus(IpAddr: String): Boolean;
  173. begin
  174. if (NBReset (LANANUM, 10, 10))then
  175.     begin
  176.     if (NBListNames (LANANUM,IpAddr))then
  177.         begin
  178.         Result:=True;
  179.         end
  180.     else Result:=False;
  181.     end
  182. else result:=False;
  183. end;
  184. function TNetBEUI.GetRemoteHostName: string;
  185. begin
  186. Result:=FRemoteName;
  187. end;
  188. procedure TNetBEUI.MakeNetbiosName(var Dest:array of char; Src: string);
  189. var
  190. l,i:Integer;
  191. begin
  192. l:=Length(Src);//cchSrc = lstrlen (szSrc);
  193. if(l>NCBNAMSZ)then l:=NCBNAMSZ;   //if (cchSrc > NCBNAMSZ) cchSrc = NCBNAMSZ;
  194. //for i:=0 to NCBNAMSZ-l do Dest[i]:=chr($20);
  195. FillMemory(@Dest,NCBNAMSZ,$20);
  196. for i:=1 to l do Dest[i-1]:=Src[i];
  197. end;
  198. function TNetBEUI.NBAdapterStatus(nLana: Integer; pBuf: PChar;
  199.   bufLen: Integer; strHostName: String): Boolean;
  200. var
  201. ncb:TNCB;
  202. begin
  203. ZeroMemory(@ncb,sizeof(ncb));
  204. ncb.ncb_command := chr(NCBASTAT);
  205. ncb.ncb_lana_num := chr(nLana);
  206. ncb.ncb_buffer :=pBuf;
  207. ncb.ncb_length := bufLen;
  208. ncb.ncb_rto:=chr(10);
  209. ncb.ncb_sto:=chr(2);
  210. MakeNetbiosName (ncb.ncb_callname, strHostName);
  211. Netbios (@ncb);
  212. NBCheck (ncb);
  213. Result:=(chr(NRC_GOODRET) = ncb.ncb_retcode);
  214. end;
  215. procedure TNetBEUI.NBCheck(ncb: TNCB);
  216. begin
  217. {$ifdef NCB_CHECK}
  218. if(ncb.ncb_retcode<>chr(NRC_GOODRET))then
  219.     ShowMessage(GetErrorMsg(ncb.ncb_retcode));
  220. {$endif}
  221. end;
  222. function TNetBEUI.NBListNames(nLana: Integer;
  223.   strHostName: string): Boolean;
  224. var
  225. i,bufLen:Integer;
  226. pStatus:PAdapterStatus;
  227. pNames:PNameBuffer;
  228. begin
  229. GetHostNames(PChar(strHostName));
  230.     // Allocate the largest buffer that might be needed.
  231. bufLen:= sizeof (TAdapterStatus) + 255 * sizeof (TNameBuffer);
  232. pStatus:= AllocMem(bufLen);  //(ADAPTER_STATUS *) HeapAlloc (hHeap, 0, cbBuffer);
  233. if(pStatus=nil)then
  234.     begin
  235.     Result:=False;
  236.     Exit;
  237.     end;
  238. if (not NBAdapterStatus (nLana,Pointer(pStatus),bufLen, strHostName))then
  239.     begin
  240.     FreeMem(pStatus);
  241.     Result:=False;
  242.     Exit;
  243.     end;
  244. // The list of names follows the adapter status structure.
  245. pNames :=PNameBuffer(
  246.     PChar(pStatus)
  247.     +sizeof(TAdapterStatus)
  248.     );
  249. {FMacAddr:=format('%02x_%02x_%02x_%02x_%02x_%02x',
  250.             [Ord(pStatus.adapter_address[0]),
  251.             Ord(pStatus.adapter_address[1]),
  252.             Ord(pStatus.adapter_address[2]),
  253.             Ord(pStatus.adapter_address[3]),
  254.             Ord(pStatus.adapter_address[4]),
  255.             Ord(pStatus.adapter_address[5])]);}
  256. FMacAddr:=
  257.     IntToHex(Ord(pStatus.adapter_address[0]),2)+'-'+
  258.     IntToHex(Ord(pStatus.adapter_address[1]),2)+'-'+
  259.     IntToHex(Ord(pStatus.adapter_address[2]),2)+'-'+
  260.     IntToHex(Ord(pStatus.adapter_address[3]),2)+'-'+
  261.     IntToHex(Ord(pStatus.adapter_address[4]),2)+'-'+
  262.     IntToHex(Ord(pStatus.adapter_address[5]),2);
  263. FAdapterType:=BYTE(pStatus.adapter_type);
  264. for i:= 0 to pStatus.name_count-1 do
  265.     begin
  266.     pNetBiosInfo:=AllocMem(sizeof(TNameBuffer));
  267. //    pNetBiosInfo^:=(pNames)[i];
  268.     pNetBiosInfo^:=PNameBuffer(PChar(pNames)+sizeof(TNameBuffer)*i)^;
  269.     FNameList.Add(pNetBiosInfo);
  270.     end;
  271.     
  272. FreeMem(pStatus);
  273. Result:=True;
  274. end;
  275. function TNetBEUI.NBReset(nLana, nSessions, nNames: integer): Boolean;
  276. var
  277. ncb:TNCB;
  278. begin
  279. {
  280.     NCB ncb;
  281.     memset (&ncb, 0, sizeof (ncb));
  282.     ncb.ncb_command = NCBRESET;
  283.     ncb.ncb_lsn = 0;                // Allocate new lana_num resources
  284.     ncb.ncb_lana_num = nLana;
  285.     ncb.ncb_callname[0] = nSessions;  // maximum sessions
  286.     ncb.ncb_callname[2] = nNames;   // maximum names
  287.     Netbios (&ncb);
  288.     NBCheck (ncb);
  289.     return (NRC_GOODRET == ncb.ncb_retcode);
  290. }
  291. ZeroMemory(@ncb,sizeof(ncb));
  292. ncb.ncb_command := chr(NCBRESET);
  293. ncb.ncb_lsn := chr(0);                // Allocate new lana_num resources
  294. ncb.ncb_lana_num := chr(nLana);
  295. ncb.ncb_callname[0] := chr(nSessions);  // maximum sessions
  296. ncb.ncb_callname[2] := chr(nNames);   // maximum names
  297. Netbios (@ncb);
  298. //NBCheck (ncb);
  299. //Result:=(chr(NRC_GOODRET) = ncb.ncb_retcode);
  300. Result:=true;
  301. end;
  302. end.