home *** CD-ROM | disk | FTP | other *** search
/ Piper's Pit BBS/FTP: ibm 0040 - 0049 / ibm0040-0049 / ibm0040.tar / ibm0040 / BTF521-3.ZIP / NETTEST.LZH / NETTEST.PAS < prev   
Encoding:
Pascal/Delphi Source File  |  1989-02-23  |  15.0 KB  |  536 lines

  1. {$V-}
  2. program NetTester;
  3. {
  4.   Note how an ExitProc is set up to "undo" the changes to the envirornment
  5.   made by this program in the event of fatal runtime error or user abort.
  6.  
  7.   This program will check to see if Novell's NetWare and/or a NetBIOS
  8.   compatible operating system are present. The program will then use each of
  9.   the message services available.
  10.  
  11.   This program also contains an SPX Event Service Routine. Event Service
  12.   Routines are in essence hardware interrupt service routines that get control
  13.   immediately when an IPX/SPX event occurs. The SPX routines in the NetWare
  14.   unit allow a Pascal ESR to be specified for use by the Listen ECB Pool. The
  15.   procedure OurPascalESR is such a routine.
  16. }
  17.  
  18. uses Crt,
  19.      NetWare, {Services for Novell's NetWare}
  20.      NetBIOS; {Services for NetBIOS}
  21.  
  22. const
  23.   ActAsSender : Boolean = TRUE;
  24.  
  25.   {NetBIOS const}
  26.   ExampleRec       : NBNameStr = 'ExampleRec*****';
  27.   ExampleSend      : NBNameStr = 'ExampleSend****';
  28.  
  29.   {Use of Broadcast Datagrams is on by default.  However, Novell's NetBIOS}
  30.   {emulator does not implement these functions, so this program will}
  31.   {automatically set this to FALSE if NetWare is detected.}
  32.   BroadcastDatagrams : Boolean = TRUE;
  33.  
  34.   {NetWare const}
  35.   SPXSessionSocket = $7000;   {the socket for the SPX session}
  36.   IPXSessionSocket = $7001;   {the socket for the IPX exchange}
  37.  
  38. var
  39.   NetWareIsHere,Logged,
  40.   UsingIPXSPX,
  41.   NetBIOSIsHere    : Boolean;
  42.  
  43.   {NetWare vars}
  44.   TryConnect       : ConnectionList;
  45.   Connect          : ConnectionList;
  46.   Result           : ConnectionList;
  47.   Receiver,Sender  : IPXAddress;
  48.   SEvent           : SPXRec;
  49.   IEvent           : IPXRec;
  50.  
  51.   {NetBIOS vars}
  52.   SaveExitProc     : Pointer;
  53.   NameNum          : Byte;
  54.   SessionLSN       : Byte;
  55.   OurNCB           : NCB;
  56.  
  57. procedure GetConnections(Prompt : String;
  58.                          var Connect : ConnectionList;
  59.                          var TargetName : String);
  60. {Get all the connections which have TargetName Logged In}
  61. begin
  62.   Write(Prompt);
  63.   ReadLn(TargetName);
  64.   GetObjConnNumbers(TargetName,ObjUser,Connect);
  65. end;
  66.  
  67. function UserBreak : Boolean;
  68. {Abort if Keypressed}
  69. begin
  70.   IPXRelinquish;
  71.   if Keypressed then begin
  72.     if ReadKey = #0 then ;
  73.     WriteLn(^M^J,'User break');
  74.     Halt;
  75.   end
  76.   else
  77.     UserBreak := FALSE;
  78. end;
  79.  
  80. function ConnectedWithSomeOne(var TryConnect,Result,
  81.                               Connected : ConnectionList) : Boolean;
  82. {Return TRUE if a message pipe was successfully opened with any node}
  83.  
  84. var
  85.   I : Word;
  86.  
  87. begin
  88.   Connected.Count := 0;
  89.   with Result do
  90.     for I := 1 to Count do
  91.       {For each entry with 0 as a Result code, add it to Connected}
  92.       if List[I] = 0 then begin
  93.         Inc(Connected.Count);
  94.         Connected.List[Connected.Count] := TryConnect.List[I];
  95.       end;
  96.   ConnectedWithSomeone := Connected.Count <> 0; {return true if at least one}
  97.                                                 {pipe opened}
  98. end;
  99.  
  100. function WaitForIPX(var Rec : IPXRec) : Byte;
  101. {Wait for the completion of an IPX event, return CompletionCode as function
  102.  result.  Check for userbreak and abort if KeyPressed.}
  103. begin
  104.   while Rec.ECB.InUse <> 0 do begin
  105.     IPXRelinquish;
  106.     if UserBreak then ;
  107.   end;
  108.   WaitForIPX := Rec.ECB.CompletionCode;
  109. end;
  110.  
  111. function WaitForSPX(var Rec : SPXRec) : Byte;
  112. {Wait for the completion of an SPX event, return CompletionCode as function
  113.  result.  Check for userbreak and abort if KeyPressed.}
  114. begin
  115.   while Rec.ECB.InUse <> 0 do begin
  116.     IPXRelinquish;
  117.     if UserBreak then ;
  118.   end;
  119.   WaitForSPX := Rec.ECB.CompletionCode;
  120. end;
  121.  
  122. {These are declared as static}
  123. const
  124.   IPXMsg           : String[30] = 'IPX is good, clean fun!';
  125.   SPXMsg           : String[30] = 'SPX services are awesome!';
  126.  
  127. procedure IPXSPXSendDemo;
  128. {Demonstrate SPX and IPX services}
  129. var
  130.   Ret : Byte;
  131.  
  132. begin
  133.   {Ensure IPX services avail}
  134.   if IPXServicesAvail then
  135.     UsingIPXSPX := TRUE
  136.   else begin
  137.     UsingIPXSPX := FALSE;
  138.     Exit;
  139.   end;
  140.   GetInternetAddress(Connect.List[1],Receiver);
  141.  
  142.   Ret := SPXEstablishConn(SEvent,Receiver,SPXSessionSocket,FALSE,512,2,NIL);
  143.   if (Ret <> 0) or (WaitForSPX(SEvent) <> 0) then begin
  144.     WriteLn('Error establishing SPX connection');
  145.     Exit;
  146.   end;
  147.   SPXSend(SEvent,FALSE,1,Length(SPXMsg)+1,SPXMsg);
  148.   if WaitForSPX(SEvent) = 0 then
  149.     WriteLn('<',SPXMsg,'> send to receiver')
  150.   else
  151.     WriteLn('SPXSend error sending packet to receiver');
  152.  
  153.   Receiver.Socket := IPXSessionSocket;
  154.  
  155.   Ret := IPXSend(IEvent,Receiver,IPXSessionSocket,FALSE,
  156.                  Length(IPXMsg)+1,IPXMsg);
  157.  
  158.   if (Ret <> 0) or (WaitForIPX(IEvent) <> 0) then begin
  159.     WriteLn('Error sending IPX packet');
  160.     Exit;
  161.   end;
  162. end;
  163.  
  164. {$F+}
  165. {$S-,R-} {these MUST ALWAYS be off for an ESR}
  166. procedure OurPascalESR(var Event : SPXRec; RetCode : Byte;
  167.                        PoolIndex : Byte;
  168.                        DataType : Byte;
  169.                        DataP : Pointer);
  170. {This is a sample ESR. First it calls PoolQueueTheEvent to queue the incoming
  171.  event for processing. The rest of the ESR is for examplification only. In
  172.  general, an ESR should return very quickly. Since this one does not return
  173.  quickly, interrupts are enabled as soon as the event has been properly
  174.  queued.
  175. }
  176. var
  177.   I,II : Word;
  178.  
  179. begin
  180.   Inline($FB); {STI ; enable interrupts because we stay here too long...}
  181.  
  182.   {Make a silly sound}
  183.   for I := 1 to 1000 do begin
  184.     Sound(I);
  185.     for II := 1 to 20 do ; {NOTE: We can't call Delay here, so we use a loop}
  186.   end;
  187.   NoSound;
  188. end;
  189. {$F-}
  190. {$S+,R+}
  191.  
  192. procedure IPXSPXReceiveDemo;
  193. {Demonstrate SPX and IPX services}
  194.  
  195. var
  196.   PoolIndex : Byte;
  197.   SPXRetCode : Byte;
  198.   DT : Byte;
  199.   Ret : Byte;
  200.   DataP : Pointer;
  201.   Msg : String;
  202.  
  203. begin
  204.   {Ensure IPX services avail}
  205.   if IPXServicesAvail then
  206.     UsingIPXSPX := TRUE
  207.   else begin
  208.     UsingIPXSPX := FALSE;
  209.     Exit;
  210.   end;
  211.  
  212.   Delay(500);  {pause half a second to allow other side to issue Establish...}
  213.  
  214.   {Listen for the SPX connection}
  215.   Ret := SPXListenForConn(SEvent,SPXSessionSocket,FALSE,
  216.                           SizeOf(String),2,@OurPascalESR);
  217.   if (Ret <> 0) or (WaitForSPX(SEvent) <> 0) then begin
  218.     WriteLn('Error Listening for SPX connection');
  219.     Exit;
  220.   end;
  221.  
  222.   {Listen for an IPX packet}
  223.   Ret := IPXListen(IEvent,IPXSessionSocket,FALSE,SizeOf(String),Msg);
  224.  
  225.   {Check the Listen ECB Pool for an incoming event}
  226.   with SEvent do begin
  227.     repeat
  228.       if UserBreak then ;
  229.     until SPXListenPooled(SEvent,SPXRetCode,PoolIndex,DT,DataP);
  230.     {An event occurred, check the CompletionCode, if zero, print message}
  231.     if SPXRetCode = 0 then
  232.       WriteLn('<',String(DataP^),'> received via SPX services')
  233.     else
  234.       WriteLn('Error listening for SPX packet');
  235.   end;
  236.  
  237.   SPXReplenishPool(SEvent,PoolIndex); {place used ECB back in the listen pool}
  238.  
  239.   if (WaitForIPX(IEvent) <> 0) then begin
  240.     WriteLn('Error Listening for IPX packet');
  241.     Exit;
  242.   end
  243.   else
  244.     WriteLn('<',Msg,'> received via IPX services');
  245. end;
  246.  
  247. procedure NetWareMessageDemo;
  248. {Demonstrate assorted NetWare messaging services}
  249.  
  250. var
  251.   Name             : String;
  252.   RetCode          : Byte;
  253.  
  254. const
  255.   PipeMsg          = 'Message Pipes are fun!!!';
  256.  
  257. begin
  258.   {Get a connection list}
  259.   GetConnections('Enter user to send to: ',TryConnect,Name);
  260.   if TryConnect.Count = 0 then begin
  261.     WriteLn('User <',Name,'> is not logged on to this network');
  262.     Exit;
  263.   end;
  264.  
  265.   {Open a message pipe (or pipes)}
  266.   WriteLn('Waiting for open message pipe (press any key to give up)...');
  267.   repeat
  268.     {Attempt to open a message pipe with all nodes in connection list}
  269.     OpenMessagePipe(TryConnect,Result);
  270.   until ConnectedWithSomeone(TryConnect,Result,Connect) or UserBreak;
  271.  
  272.   {Send a message to all receptive nodes in conmnection list}
  273.   SendMessagePipe(PipeMsg,Connect,Result);
  274.   WriteLn('<',PipeMsg,'> sent via message pipe');
  275.  
  276.   {Now close the message pipe(s)}
  277.   RetCode := CloseMessagePipe(Connect,Result);
  278.   if RetCode <> 0 then
  279.     WriteLn('Error ',RetCode,' returned by CloseMessagePipe');
  280.  
  281.   IPXSPXSendDemo; {IPX/SPX demo}
  282.  
  283.   {Send a broadcast message to all nodes in Connection list}
  284.   SendBroadcastMsg('Hello '+Name,TryConnect,Result);
  285.   WriteLn('<Hello ',Name,'> broadcast to ',Name);
  286. end;
  287.  
  288. procedure NetWareReceiverDemo;
  289. {Demonstrate assorted NetWare messaging services}
  290.  
  291. var
  292.   Msg              : String;
  293.   SourceConn       : Byte;
  294.   RetCode          : Byte;
  295.   Name             : String;
  296. begin
  297.   {Get a connection List}
  298.   GetConnections('Enter user to receive from: ',TryConnect,Name);
  299.  
  300.   {Open a message pipe (or pipes)}
  301.   WriteLn('Waiting for open message pipe (press any key to give up)...');
  302.   repeat
  303.     {Attempt to open a message pipe with all nodes in connection list}
  304.     OpenMessagePipe(TryConnect,Result);
  305.   until ConnectedWithSomeone(TryConnect,Result,Connect) or UserBreak;
  306.  
  307.   Delay(1000);           {give the sender a second to send message}
  308.  
  309.   {Receive a message (if available) }
  310.   GetMessagePipe(SourceConn,Msg);
  311.   WriteLn('Message received from ',SourceConn,': <',Msg,'>');
  312.  
  313.   {Close the message pipe}
  314.   RetCode := CloseMessagePipe(Connect,Result);
  315.   if RetCode <> 0 then
  316.     WriteLn('Error ',RetCode,' returned by CloseMessagePipe');
  317.  
  318.   IPXSPXReceiveDemo; {IPX/SPX demo}
  319. end;
  320.  
  321. {$F+}
  322. procedure OurExitProc;
  323. {If Using SPX services - Aborts the SPX connection
  324.  If using NetBIOS - Deletes the name and hangs up the session
  325. }
  326. var
  327.   Ret : Byte;
  328.  
  329. begin
  330.   ExitProc := SaveExitProc;  {allow chaining to original ExitProc}
  331.  
  332.   {Abort the SPX Connection if SPX services are being used}
  333.   if NetWareIsHere and UsingIPXSPX then
  334.     SPXAbortConn(SEvent);
  335.  
  336.   {If NetBIOS, then Cancel any pending requests, delete the added names, and}
  337.   {hangup the session.}
  338.   if NetBIOSIsHere then begin
  339.     Ret := CancelRequest(OurNCB);
  340.     if ParamCount > 0 then
  341.       Ret := NetBIOSDeleteName(ExampleRec)
  342.     else
  343.       Ret := NetBIOSDeleteName(ExampleSend);
  344.     Ret := NetBiosHangUp(SessionLSN);
  345.   end;
  346. end;
  347. {$F-}
  348.  
  349. procedure NetBIOSReceiverDemo;
  350. {NetBIOS datagram and session demo}
  351. var
  352.   Msg : String;
  353.   Ret : Byte;
  354.  
  355. begin
  356.   Write('Please wait, adding NetBIOS name...');
  357.   if NetBiosAddName(ExampleRec,NameNum) <> 0 then begin
  358.     WriteLn(^M^J,'Unable to add NetBIOS name');
  359.     Exit;
  360.   end;
  361.   WriteLn(^M^J,'waiting for datagram from remote (press any key to abort)...');
  362.   ReceiveDatagram(OurNCB,NameNum,FALSE,SizeOf(Msg),Msg);
  363.   while OurNCB.CmdComplete <> 0 do
  364.     if UserBreak then ;
  365.   if OurNCB.RetCode = 0 then
  366.     WriteLn('Datagram <',Msg,'> received from ExampleSend')
  367.   else
  368.     WriteLn('ReceiveDatagram error = ',OurNCB.RetCode);
  369.  
  370.   if BroadcastDatagrams then begin
  371.     ReceiveBDatagram(OurNCB,NameNum,FALSE,SizeOf(Msg),Msg);
  372.     while OurNCB.CmdComplete <> 0 do
  373.       if UserBreak then ;
  374.     if OurNCB.RetCode = 0 then
  375.       WriteLn('Broadcast Datagram <',Msg,'> received from ExampleSend')
  376.     else
  377.       WriteLn('ReceiveBDatagram error = ',OurNCB.RetCode);
  378.   end;
  379.  
  380.   Write(^M^J,
  381.   'Attempting to establish a NetBIOS session (press any key to give up)...');
  382.  
  383.   repeat
  384.     Ret := NetBIOSListen(ExampleSend,ExampleRec,5,5,SessionLSN);
  385.   until (Ret = 0) or UserBreak;
  386.   WriteLn;
  387.  
  388.   Ret := NetBIOSReceive(SessionLSN,SizeOf(Msg),Msg);
  389.   if Ret = 0 then
  390.     WriteLn('Session Packet <',Msg,'> received')
  391.   else
  392.     WriteLn('NetBIOSReceive error ',Ret);
  393. end;
  394.  
  395. procedure NetBIOSMessageDemo;
  396. {NetBIOS datagram and session demo}
  397.  
  398. const
  399.   Datagram         : String[20] = 'Datagrams are fun!!!';
  400.   BDatagram        : String[40] = 'Broadcast Datagrams are fun!!!';
  401.   SessionPacket    : String[30] = 'Sessions are fun too!!!';
  402.  
  403. var
  404.   Ret : Byte;
  405.  
  406. begin
  407.   Write('Please wait, adding NetBIOS name...');
  408.   if NetBiosAddName(ExampleSend,NameNum) <> 0 then begin
  409.     WriteLn(^M^J,'Unable to add NetBIOS name');
  410.     Exit;
  411.   end;
  412.   WriteLn;
  413.   {Pause until user strikes a key}
  414.   Write('Press any key when ready for NetBIOS tests...');
  415.   if ReadKey = #0 then ;
  416.  
  417.   WriteLn;
  418.   {Send a datagram}
  419.   SendDatagram(OurNCB,NameNum,ExampleRec,FALSE,Length(Datagram)+1,Datagram);
  420.   {wait for the NetBIOS event to complete}
  421.   while OurNCB.CmdComplete <> 0 do
  422.     if UserBreak then ;
  423.   if OurNCB.RetCode = 0 then
  424.     WriteLn('Datagram <',Datagram,'> sent to ExampleRec')
  425.   else
  426.     WriteLn('SendDatagram error = ',OurNCB.RetCode);
  427.  
  428.   {If using Broadcast datagrams, then send one}
  429.   if BroadcastDatagrams then begin
  430.     Write('Pausing one second...');
  431.     Delay(1000);
  432.     WriteLn;
  433.     SendBDatagram(OurNCB,NameNum,FALSE,Length(BDatagram)+1,BDatagram);
  434.     while OurNCB.CmdComplete <> 0 do
  435.       if UserBreak then ;
  436.     if OurNCB.RetCode = 0 then
  437.       WriteLn('Broadcast Datagram <',BDatagram,'> sent to ExampleRec')
  438.     else
  439.       WriteLn('SendBDatagram error = ',OurNCB.RetCode);
  440.   end;
  441.   Write(^M^J,
  442.   'Attempting to establish a NetBIOS session (press any key to give up)...');
  443.  
  444.   {Establish a NetBIOS call}
  445.   repeat
  446.     Ret := NetBIOSCall(ExampleRec,ExampleSend,5,5,SessionLSN);
  447.   until (Ret = 0) or UserBreak;
  448.   WriteLn;
  449.  
  450.   {Send a Session Packet}
  451.   Ret := NetBIOSSend(SessionLSN,Length(SessionPacket)+1,SessionPacket);
  452.   if Ret = 0 then
  453.     WriteLn('<',SessionPacket,'> sent to remote')
  454.   else
  455.     WriteLn('NetBIOSReceive error ',Ret);
  456. end;
  457.  
  458. procedure InvalidOption(S : String);
  459.  
  460. begin
  461.   WriteLn(S,' is an invalid command line option');
  462. end;
  463.  
  464. procedure ShowHelp;
  465.  
  466. begin
  467.   WriteLn('NetTest [OPTIONS]'^M^J);
  468.   WriteLn('  /R    Act as receiving side');
  469.   WriteLn('  /B    Test NetBIOS only');
  470.   WriteLn('  /N    Test Advanced NetWare only');
  471.   WriteLn('  /?    This help message');
  472.   Halt;
  473. end;
  474.  
  475. procedure ParseCommandLine;
  476.  
  477. var
  478.   Opt : String;
  479.   I : Byte;
  480.  
  481. begin
  482.   for I := 1 to ParamCount do begin
  483.     Opt := ParamStr(I);
  484.     if (Length(Opt) = 2) and (Opt[1] in ['-','/']) then
  485.       case UpCase(Opt[2]) of
  486.         'B' : NetWareIsHere := FALSE;
  487.         'W','N' : NetBIOSIsHere := FALSE;
  488.         'R' : ActAsSender := FALSE;
  489.         '?','H' : ShowHelp;
  490.         else InvalidOption(Opt);
  491.       end
  492.     else
  493.       InvalidOption(Opt);
  494.   end;
  495. end;
  496.  
  497. var
  498.   Ret : Byte;
  499.  
  500. begin
  501.   WriteLn('NetTest version 1.0'^M^J);
  502.   {See what Operating system(s) we have here...}
  503.   NetWareIsHere := NetWareLoaded(Logged);
  504.   NetWareIsHere := NetWareIsHere and Logged;
  505.   NetBIOSIsHere := NetBIOSInstalled;
  506.  
  507.   ParseCommandLine;
  508.  
  509.   if not (NetBIOSIsHere or NetWareIsHere) then begin
  510.     WriteLn('No network operating system detected.');
  511.     Halt;
  512.   end;
  513.  
  514.   if NetWareIsHere then
  515.     BroadcastDatagrams := FALSE; {NetWare does not support these services}
  516.  
  517.   SaveExitProc := ExitProc;  {save original exitproc}
  518.   ExitProc := @OurExitProc;  {setup our exit procedure}
  519.  
  520.   if ActAsSender then begin
  521.     if NetWareIsHere then
  522.       NetWareMessageDemo;
  523.     if NetBIOSIsHere then
  524.       NetBIOSMessageDemo;
  525.   end
  526.   else begin
  527.     if NetWareIsHere then
  528.       NetWareReceiverDemo;
  529.     if NetBIOSIsHere then
  530.       NetBIOSReceiverDemo;
  531.   end;
  532.  
  533.   {NOTE: OurExitProc is called no matter how we terminate}
  534. end.
  535.  
  536.