home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Chip 2001 September
/
Chip_2001-09_cd1.bin
/
zkuste
/
delphi
/
kompon
/
d2345
/
MSYSINFO.ZIP
/
Source
/
MSI_Network.pas
< prev
next >
Wrap
Pascal/Delphi Source File
|
2001-05-21
|
19KB
|
553 lines
{*******************************************************}
{ }
{ MiTeC System Information Component }
{ Network Detection Part }
{ version 5.4 for Delphi 3,4,5 }
{ }
{ Copyright ⌐ 1997,2001 Michal Mutl }
{ }
{*******************************************************}
{$INCLUDE MITEC_DEF.INC}
unit MSI_Network;
interface
uses
SysUtils, Windows, Classes, WinSock;
type
TWinsock = class(TPersistent)
private
FDesc: string;
FStat: string;
FMajVer: word;
FMinVer: word;
public
procedure GetInfo;
published
property Description: string read FDesc write FDesc stored False;
property MajorVersion: word read FMajVer write FMajVer stored False;
property MinorVersion: word read FMinVer write FMinVer stored False;
property Status: string read FStat write FStat stored False;
end;
TNetwork = class(TPersistent)
private
FAdapter: TStrings;
FWinsock: TWinsock;
FIPAddress: TStrings;
FMACAddress: TStrings;
FCli: TStrings;
FServ: TStrings;
FProto: TStrings;
FNCAI: integer;
function GetLocalIP :string;
public
constructor Create;
destructor Destroy; override;
procedure GetInfo;
procedure Report(var sl :TStringList);
published
property IPAddresses: TStrings read FIPAddress write FIPAddress stored false;
property MACAddresses: TStrings read FMACAddress write FMACAddress stored False;
property Adapters :TStrings read FAdapter write FAdapter stored false;
property CardAdapterIndex: integer read FNCAI write FNCAI stored False;
property Protocols :TStrings read FProto write FProto stored False;
property Services :TStrings read FServ write FServ stored False;
property Clients :TStrings read FCli write FCli stored False;
property WinSock: TWinsock read FWinsock write FWinsock;
end;
implementation
uses Registry, MiTeC_Routines, MSI_Devices;
const
NBNAMESIZE = 16;
MAXLANAS = 254;
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 }
NRC_GOODRET = $00; { good return
NRC_BUFLEN = $01; { illegal buffer length }
NRC_ILLCMD = $03; { illegal command }
NRC_CMDTMO = $05; { command timed out }
NRC_INCOMP = $06; { message incomplete, issue another command }
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 later }
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 }
ALL_TRANSPORTS = 'M'#$00#$00#$00;
MS_NBF = 'MNBF';
NAME_FLAGS_MASK = $87;
GROUP_NAME = $80;
UNIQUE_NAME = $00;
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 followed
by an array of SESSION_BUFFER structures. If the NCB_NAME starts with an
asterisk then an array of these structures is returned containing the
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_HEADER 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 provide
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; external 'netapi32.dll' name 'Netbios';
{$ENDIF}
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)));
{$ENDIF}
end;
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}
L_Enum.Length:=1;
L_Enum.Lana[0]:=0;
{$ENDIF}
Result:=L_Enum;
end;
function NbReset(l: Byte): Word;
var
NCB: TNCB;
begin
{$IFNDEF WIN32}
Result:=NRC_GOODRET;
{$ELSE}
FillChar(NCB,SizeOf(NCB),0);
NCB.Command:=NCB_RESET;
NCB.Lana_Num:=l;
Result:=NetBiosCmd(NCB);
{$ENDIF}
end;
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
Result:='??:??:??:??:??:??';
end;
{ TWinsock }
procedure TWinsock.GetInfo;
var
GInitData :TWSADATA;
begin
try
if wsastartup($101,GInitData)=0 then begin
FDesc:=GInitData.szDescription;
FStat:=GInitData.szSystemStatus;
FMajVer:=Hi(GInitData.wHighVersion);
FMinVer:=Lo(GInitData.wHighVersion);
wsacleanup;
end else
FStat:='Winsock cannot be initialized.';
except
on e:Exception do begin
MessageBox(0,PChar(e.message),'TWinsock.GetInfo',MB_OK or MB_ICONERROR);
end;
end;
end;
{ TNetwork }
function TNetwork.GetLocalIP: string;
type
TaPInAddr = array [0..255] of PInAddr;
PaPInAddr = ^TaPInAddr;
var
phe :PHostEnt;
pptr :PaPInAddr;
Buffer :array [0..63] of char;
i :integer;
GInitData :TWSADATA;
begin
wsastartup($101,GInitData);
result:='';
GetHostName(Buffer,SizeOf(Buffer));
phe:=GetHostByName(buffer);
if not assigned(phe) then
exit;
pptr:=PaPInAddr(Phe^.h_addr_list);
i:=0;
while pptr^[I]<>nil do begin
result:=Result+StrPas(inet_ntoa(pptr^[I]^))+',';
inc(i);
end;
Delete(Result,Length(Result),1);
wsacleanup;
end;
procedure TNetwork.GetInfo;
var
L_Enum: TLana_Enum;
RetCode: Word;
i: integer;
ck,dv: string;
const
rkNetworkNT = {HKEY_LOCAL_MACHINE\}'SOFTWARE\Microsoft\Windows NT\CurrentVersion\NetworkCards';
rkNetwork2K = {HKEY_LOCAL_MACHINE\}'SYSTEM\CurrentControlSet\Control\Network';
rvNetworkNT = 'Description';
rvProtoClass = 'NetTrans';
rvServClass = 'NetService';
rvCliClass = 'NetClient';
begin
try
FWinSock.GetInfo;
FIPAddress.CommaText:=GetLocalIP;
FAdapter.Clear;
FNCAI:=-1;
with TDevices.Create do begin
GetInfo;
for i:=0 to DeviceCount-1 do
if Devices[i].DeviceClass=dcNet then begin
if Devices[i].FriendlyName='' then
ck:=Devices[i].Description
else
ck:=Devices[i].FriendlyName;
FAdapter.Add(ck);
if (Devices[i].Location<>'') and (FNCAI=-1) then
FNCAI:=FAdapter.Count-1;
end;
Free;
end;
if Is2K then begin
ck:=rkNetwork2K;
dv:=rvNetworkNT;
end else begin
ck:=ClassKey;
dv:=DescValue;
end;
GetClassDevices(ck,rvProtoClass,dv,FProto);
GetClassDevices(ck,rvServClass,dv,FServ);
GetClassDevices(ck,rvCliClass,dv,FCli);
FMACAddress.Clear;
L_Enum:=NbLanaEnum;
if L_Enum.Length<>0 then
for i:=0 to (L_Enum.Length-1) do begin
RetCode:=NbReset(L_Enum.Lana[i]);
if RetCode=NRC_GOODRET then begin
ck:=NbGetMacAddr(L_Enum.Lana[i]);
if FMacAddress.IndexOf(ck)=-1 then
FMacAddress.Add(ck);
end;
end;
except
on e:Exception do begin
MessageBox(0,PChar(e.message),'TNetwork.GetInfo',MB_OK or MB_ICONERROR);
end;
end;
end;
constructor TNetwork.Create;
begin
inherited;
FWinsock:=TWinsock.Create;
FAdapter:=TStringList.Create;
FIPAddress:=TStringList.Create;
FMACAddress:=TStringList.Create;
FProto:=TStringList.Create;
FServ:=TStringList.Create;
FCli:=TStringList.Create;
end;
destructor TNetwork.Destroy;
begin
FWinsock.Free;
FAdapter.Free;
FMACAddress.Free;
FIPAddress.Free;
FProto.Free;
FCli.Free;
FServ.Free;
inherited;
end;
procedure TNetwork.Report(var sl: TStringList);
begin
with sl do begin
Add('[Network]');
StringsToRep(Adapters,'Count','Adapter',sl);
StringsToRep(Protocols,'ProtoCount','Protocol',sl);
StringsToRep(Services,'ServiceCount','Service',sl);
StringsToRep(Clients,'ClientCount','Client',sl);
StringsToRep(IPAddresses,'IPCount','IPAddress',sl);
StringsToRep(MACAddresses,'MACCount','MACAddress',sl);
Add('[Winsock]');
Add(Format('Description=%s',[Winsock.Description]));
Add(Format('Version=%d.%d',[Hi(Winsock.MajorVersion),Lo(Winsock.MinorVersion)]));
Add(Format('Status=%s',[Winsock.Status]));
end;
end;
end.