190 lines
5.3 KiB
ObjectPascal
190 lines
5.3 KiB
ObjectPascal
{$X+,V-,B-}
|
|
program ShSAPs;
|
|
|
|
{ Testprogram for the nwSAP unit / NwTP 0.6 (c) 1993,1995 R.Spronk }
|
|
|
|
{ Dump all incoming SAP broadcasts on screen;
|
|
Sends -no- packets; receiving packets only }
|
|
|
|
{ Demonstrates
|
|
-The use of the Service Advertizing Protocol;
|
|
-Asynchronous handling of receiving and processing
|
|
(using 1 receive ESR and intermediate buffers }
|
|
|
|
uses crt,nwMisc,nwIPX,nwSAP;
|
|
|
|
CONST SAPsocket=$0452;
|
|
BUFSIZ=511;
|
|
{ May 'hang' your WS if more than 70 SAP broadcast were received
|
|
in a short interval (a few ticks). Increase the BUFSIZ value. }
|
|
|
|
Type TSAPserver=record
|
|
ObjType:word;
|
|
Name :array[1..48] of byte; { asciiz }
|
|
Address:TinternetworkAddress;
|
|
Hops :word;
|
|
end;
|
|
|
|
TSAPresponse=record
|
|
ResponseType:word; { 0002 General server; 0004 nearest server }
|
|
ServerEntry:array[1..7] of TSAPserver;
|
|
end;
|
|
|
|
Type String48=string[48];
|
|
Tservices=record
|
|
InUseFlag :Byte; { 0: not being accessed by other threads }
|
|
TimeStamp :Word; { Ticks / max 60. minutes }
|
|
ObjType:word;
|
|
Name :array[1..48] of byte; { asciiz }
|
|
Address:TinternetworkAddress;
|
|
Hops :word;
|
|
end;
|
|
|
|
Var ServBuf:array[0..BUFSIZ] of TServices;
|
|
ECBServBufInd:word; { 0..BUFSIZ }
|
|
ServBufInd :word; { 0..BUFSIZ }
|
|
|
|
StartTicks:Longint;
|
|
|
|
PktCount:word;
|
|
|
|
Var ReceiveEcb :Tecb;
|
|
IpxHdr :TipxHeader;
|
|
socket :word;
|
|
IPXreceiveBuffer: array[1..546] of byte;
|
|
SAPreceiveBuffer: TSAPresponse absolute IPXreceiveBuffer;
|
|
|
|
ReceivedBufLen:word;
|
|
PacketReceived:boolean;
|
|
|
|
RecString :string;
|
|
|
|
NewStack:array[1..1024] of word; { !! used by ESR }
|
|
StackBottom:word; { !! used by ESR }
|
|
ESRctr:byte; { !! used by SAP ESR }
|
|
|
|
|
|
{$F+}
|
|
Procedure SAPListenESRhandler(Var p:Tpecb);
|
|
begin
|
|
if SAPreceiveBuffer.Responsetype=$0200 { 0002 hi-lo: general server SAP reply }
|
|
then begin
|
|
ESRctr:=1;
|
|
while (ESRctr<=7) and (SAPreceiveBuffer.ServerEntry[ESRctr].ObjType>$0000)
|
|
do begin
|
|
while ServBuf[ECBservBufInd].inUseFlag>0
|
|
do begin
|
|
inc(ECBServBufInd);
|
|
ECBservBufInd:=ECBservBufInd and BUFSIZ;
|
|
end;
|
|
with SAPreceiveBuffer.ServerEntry[ESRctr]
|
|
do begin
|
|
Move(ObjType,ServBuf[ECBServBufInd].ObjType,SizeOf(TSAPserver));
|
|
ObjType:=$0000; { To mark that the entry has been dealt with;
|
|
to 'clear' receive buffer }
|
|
end;
|
|
with ServBuf[ECBServBufInd]
|
|
do begin
|
|
IPXgetIntervalMarker(TimeStamp);
|
|
InUseFlag:=$FF;
|
|
end;
|
|
inc(ESRctr);
|
|
end;
|
|
PacketReceived:=true;
|
|
inc(PktCount);
|
|
end;
|
|
IPXListenForPacket(ReceiveECB);
|
|
end;
|
|
{$F-}
|
|
|
|
{$F+}
|
|
Procedure SAPListenESR; assembler;
|
|
asm { ES:SI are the only valid registers when entering this procedure ! }
|
|
mov dx, seg stackbottom
|
|
mov ds, dx
|
|
|
|
mov dx,ss { setup of a new local stack }
|
|
mov bx,sp { ss:sp copied to dx:bx}
|
|
mov ax,ds
|
|
mov ss,ax
|
|
mov sp,offset stackbottom
|
|
push dx { push old ss:sp on new stack }
|
|
push bx
|
|
|
|
push es { push es:si on stack as local vars }
|
|
push si
|
|
mov di,sp
|
|
|
|
push ss { push address of local ptr on stack }
|
|
push di
|
|
CALL SAPListenEsrHandler
|
|
|
|
add sp,4 { skip stack ptr-copy }
|
|
pop bx { restore ss:sp from new stack }
|
|
pop dx
|
|
mov sp,bx
|
|
mov ss,dx
|
|
end;
|
|
{$F-}
|
|
|
|
|
|
Var ServerName:string;
|
|
|
|
begin
|
|
IF NOT IpxInitialize
|
|
then begin
|
|
writeln('Ipx needs to be installed.');
|
|
halt(1);
|
|
end;
|
|
socket:=SAPSocket;
|
|
IF NOT IPXopenSocket(Socket,SHORT_LIVED_SOCKET)
|
|
then begin
|
|
writeln('IPXopenSocket returned error# ',nwIPX.result);
|
|
halt(1);
|
|
end;
|
|
|
|
PktCount:=0;
|
|
ECBservBufInd:=0;
|
|
PacketReceived:=False;
|
|
{ Empty receive buffer (ReceiveEcb.fragment[2].address^) }
|
|
FillChar(IPXreceiveBuffer,546,#0);
|
|
|
|
{ Setup ECB and IPX header }
|
|
IPXsetupListenECB(Addr(SAPListenESR),SAPsocket,@IPXreceiveBuffer,546,
|
|
IpxHdr,ReceiveEcb);
|
|
|
|
IPXListenForPacket(ReceiveECB);
|
|
|
|
ServBufInd:=0;
|
|
REPEAT
|
|
|
|
WHILE (ServBufInd<512) and (NOT keypressed)
|
|
do begin
|
|
IPXrelinquishControl;
|
|
|
|
IF ServBuf[ServBufInd].InUseFlag>0
|
|
then begin
|
|
with ServBuf[ServBufInd]
|
|
do begin
|
|
writeln('---------');
|
|
writeln('BufIndex:',ServBufInd);
|
|
writeln('Timestamp: ',HexStr(TimeStamp,4));
|
|
writeln('ObjType : ',HexStr(swap(ObjType),4));
|
|
ZStrCopy(ServerName,name[1],48);
|
|
writeln('ServerNm : ',ServerName);
|
|
writeln('Address : ',HexDumpStr(Address,24));
|
|
writeln('Hops : ',HexStr(swap(Hops),4));
|
|
end;
|
|
ServBuf[ServBufInd].InUseFlag:=0;
|
|
end;
|
|
|
|
inc(ServBufInd);ServBufInd:=ServBufInd and BUFSIZ;
|
|
end;
|
|
|
|
UNTIL KeyPressed;
|
|
|
|
IF NOT IPXcloseSocket(SAPsocket)
|
|
then writeln('IPXcloseSocket returned error# ',nwIPX.result);
|
|
|
|
end.
|