home *** CD-ROM | disk | FTP | other *** search
/ PC World 2000 October / PCWorld_2000-10_cd2.bin / Borland / interbase / IBConsole_src.ZIP / ibconsole / zluCommDiag.pas < prev    next >
Pascal/Delphi Source File  |  2000-07-24  |  32KB  |  1,013 lines

  1. {
  2.  * The contents of this file are subject to the InterBase Public License
  3.  * Version 1.0 (the "License"); you may not use this file except in
  4.  * compliance with the License.
  5.  * 
  6.  * You may obtain a copy of the License at http://www.Inprise.com/IPL.html.
  7.  * 
  8.  * Software distributed under the License is distributed on an "AS IS"
  9.  * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
  10.  * the License for the specific language governing rights and limitations
  11.  * under the License.  The Original Code was created by Inprise
  12.  * Corporation and its predecessors.
  13.  * 
  14.  * Portions created by Inprise Corporation are Copyright (C) Inprise
  15.  * Corporation. All Rights Reserved.
  16.  * 
  17.  * Contributor(s): ______________________________________.
  18. }
  19.  
  20. {****************************************************************
  21. *
  22. *  f r m u C o m m D i a g
  23. *
  24. ****************************************************************
  25. *  Author: The Client Server Factory Inc.
  26. *  Date:   March 1, 1999
  27. *
  28. *  Description:  This unit provides all the necessary functions
  29. *                to ping a remote server, test specific services
  30. *                via TCP/IP and test a connection to a server
  31. *                using NetBEUI and SPX.
  32. *
  33. *****************************************************************
  34. * Revisions:
  35. *
  36. *****************************************************************}
  37. unit zluCommDiag;
  38.  
  39. interface
  40.  
  41. uses
  42.   Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
  43.   Winsock, PSock, Math;
  44.  
  45. type
  46.   TIPAddress = LongInt;                // IP address
  47.   TIPMask    = LongInt;                // IP mask
  48.   TIPStatus  = LongInt;                // IP status
  49.   HINSTANCE  = Longint;                // instance handle
  50.   HANDLE     = Cardinal;               // handle
  51.  
  52.   TIPOptions = packed record           // IP options structure
  53.     TTL         : Byte;
  54.     TOS         : Byte;
  55.     Flags       : Byte;
  56.     OptionsSize : Byte;
  57.     OptionsData : PChar;
  58.   end;
  59.   ptrIPOptions = ^TIPOptions;
  60.  
  61.   TICMPEchoReply = packed record       // ICMP reply structure
  62.     Address      : TIPAddress;
  63.     Status       : DWORD;
  64.     RTT          : DWORD;
  65.     DataSize     : WORD;
  66.     Reserved     : WORD;
  67.     Data         : Pointer;
  68.     Options      : TIPOptions;
  69.   end;
  70.   ptrICMPEchoReply = ^TICMPEchoReply;
  71.  
  72.   // SPX socket
  73.   TSockAddrIPX = packed record
  74.       sa_family: u_short;
  75.       sa_netnum: array[0..3] of Char;
  76.       sa_nodenum: array[0..5] of Char;
  77.       sa_socket: u_short;
  78.   end;
  79.     pSockAddrIPX = ^TSockAddrIPX;
  80.  
  81.   // ICMP dll function
  82.   TICMPCreateFile = function : THandle; stdcall;
  83.  
  84.   // ICMP dll function
  85.   TICMPCloseHandle = function(ICMPHandle : Thandle) : Boolean; stdcall;
  86.  
  87.   // ICMP dll function
  88.   TICMPSendEcho = function (ICMPHandle     : THandle;
  89.                             DestAddr       : TIPAddress;
  90.                             RequestData    : Pointer;
  91.                             RequestSize    : WORD;
  92.                             RequestOptions : ptrIPOptions;
  93.                             ReplyBuffer    : Pointer;
  94.                             ReplySize      : DWORD;
  95.                             Timeout        : DWORD) : DWORD; stdcall;
  96.  
  97.  
  98.   // socket exception
  99.   TSVCException = class(Exception);
  100.  
  101.   // Novell Netware function types
  102.   TNWCallsInit        = function(Reserved1, Reserved2 : Pointer) : Cardinal;  StdCall;
  103.   TNWCLXInit          = function(Reserved1, Reserved2 : Pointer) : Cardinal;  StdCall;
  104.   TNWCCOpenConnByName = function(StartConnHandle : Cardinal; Name : PChar; NameFormat, OpenState, TranType : Cardinal; var pConnHandle : Cardinal) : Cardinal;  StdCall;
  105.   TNWCCCloseConn      = function(ConnHandle : Cardinal) : Cardinal;  StdCall;
  106.  
  107.   {****************************************************************
  108.   *
  109.   *  T i b c P i n g
  110.   *
  111.   ****************************************************************
  112.   *  Author: The Client Server Factory Inc.
  113.   *  Date:   March 1, 1999
  114.   *
  115.   *  Description:  This class implements the interface to
  116.   *                perform packet internet groping on a remote
  117.   *                server using TCP/IP using a 32 byte packet.
  118.   *
  119.   *****************************************************************
  120.   * Revisions:
  121.   *
  122.   *****************************************************************}
  123.   TibcPing = class
  124.   private
  125.     { private declarations }
  126.     FAddress                : String;
  127.     FAddrResolved           : Boolean;
  128.     FHostIP                 : String;
  129.     FHostName               : String;
  130.     FIPAddress              : LongInt;
  131.     FLastError              : DWORD;
  132. //    FPackets                : Integer;
  133.     FReply                  : TICMPEchoReply;
  134.     FSize                   : Integer;
  135.     FTimeout                : Integer;
  136.     FTTL                    : Integer;
  137.     hICMP                   : THandle;
  138.     hICMPdll                : HModule;
  139.     function GetAddr        : String;
  140.     function GetHostIP      : String;
  141.     function GetHostName    : String;
  142.     function GetLastErr     : Integer;
  143.     function GetResult      : String;
  144.     function GetRTTReply    : Integer;
  145.     function GetSize        : Integer;
  146.     function GetTimeOut     : Integer;
  147.     function GetTTL         : Integer;
  148.     function GetTTLReply    : Integer;
  149.     procedure SetAddr(Host : String);
  150.     procedure SetHostName(Host : String);
  151.     procedure SetSize(PacketSize : Integer);
  152.     procedure SetTimeOut(TOut : Integer);
  153.     procedure SetTTL(LiveTime : Integer);
  154.   public
  155.     { public declarations }
  156.     function ResolveHost   : Boolean;
  157.     function Ping          : Boolean;
  158.     property HostIP        : String read GetHostIP;
  159.     property LastError     : Integer read GetLastErr;
  160.     property RTTReply      : Integer read GetRTTReply;
  161.     property TTLReply      : Integer read GetTTLReply;
  162.     property VerboseResult : String read GetResult;
  163.   published
  164.     { published declarations }
  165.     property Host      : String read GetAddr write SetAddr;
  166.     property HostName  : String read GetHostName write SetHostName;
  167.     property Size      : Integer read GetSize write SetSize;
  168.     property TimeOut   : Integer read GetTimeout write SetTimeout;
  169.     property TTL       : Integer read GetTTL write SetTTL;
  170.   end;
  171.  
  172.   {****************************************************************
  173.   *
  174.   *  T i b c S o c k e t
  175.   *
  176.   ****************************************************************
  177.   *  Author: The Client Server Factory Inc.
  178.   *  Date:   March 1, 1999
  179.   *
  180.   *  Description:  This class implements the interface to test
  181.   *                a port/service on a specified remote
  182.   *                server using TCP/IP.
  183.   *
  184.   *****************************************************************
  185.   * Revisions:
  186.   *
  187.   *****************************************************************}
  188.   TibcSocket = class(TPowerSock)
  189.   private
  190.     { private declarations }
  191.     FPortName               : String;
  192.     function GetPortName    : String;
  193.     function GetSockDesc    : String;
  194.     function GetSockVersion : String;
  195.   public
  196.     { public declarations }
  197.     property PortName       : String read GetPortName;
  198.     property WSDescription  : String read GetSockDesc;
  199.     property WSVersion      : String read GetSockVersion;
  200.   published
  201.     { published declarations }
  202.   end;
  203.  
  204.   {****************************************************************
  205.   *
  206.   *  T i b c S P X
  207.   *
  208.   ****************************************************************
  209.   *  Author: The Client Server Factory Inc.
  210.   *  Date:   March 1, 1999
  211.   *
  212.   *  Description:  This class implements the interface to
  213.   *                test an unlicensed connection to a Netware
  214.   *                server using IPX/SPX.  The client machine
  215.   *                must have the proper Netware client installed.
  216.   *
  217.   *****************************************************************
  218.   * Revisions:
  219.   *
  220.   *****************************************************************}
  221.   TibcSPX = class
  222.   private
  223.     { private declarations }
  224.     FServer : String;
  225.     function GetServer : String;
  226.     procedure SetServer(Server : String);
  227.   public
  228.     { public declarations }
  229.     procedure TestSPX(var sResult : String);
  230.   published
  231.     { published declarations }
  232.     property ServerName : String read GetServer write SetServer;
  233.  
  234.   end;
  235.  
  236.   {****************************************************************
  237.   *
  238.   *  T i b c P i p e s
  239.   *
  240.   ****************************************************************
  241.   *  Author: The Client Server Factory Inc.
  242.   *  Date:   March 1, 1999
  243.   *
  244.   *  Description:  This class implements the interface to
  245.   *                test a connection to an NT server using a named
  246.   *                pipe.
  247.   *
  248.   *****************************************************************
  249.   * Revisions:
  250.   *
  251.   *****************************************************************}
  252.   TibcPipes = class
  253.   private
  254.     FDefault : String;  // CSDiagDefault
  255. //    FItem    : String;
  256. //    FName    : String;
  257.     FPath    : String;
  258.     FPipe    : String;
  259.     FSA      : SECURITY_ATTRIBUTES;
  260.     FServer  : String;
  261.     FTotal   : Integer;
  262.     hPipe    : HANDLE;
  263.     function GetPath : String;
  264.     function GetServer : String;
  265.     function GetTries : Integer;
  266.     procedure SetPath(Path : String);
  267.     procedure SetServer(Server : String);
  268.     procedure SetTries(Tries : Integer);
  269.   public
  270.     function TestPipe(var sResult : String; SilentTest : Boolean) : Boolean;
  271.   published
  272.     property Path   : String read GetPath write SetPath;
  273.     property Server : String read GetServer write SetServer;
  274.     property Tries  : Integer read GetTries write SetTries;
  275.   end;
  276.  
  277. const
  278.   CRLF          = #13#10;              // carriage return linefeed pair
  279.   ICMPdll       = 'icmp.dll';          // name of ICMP dll
  280.   CALWIN32      = 'calwin32.dll';
  281.   CLXWIN32      = 'clxwin32.dll';
  282.     NSPROTO_IPX   = 1000;
  283.     NSPROTO_SPX   = 1256;
  284.     NSPROTO_SPXII = 1257;
  285.   SOCK_DIAG_SPX = $0456;
  286.   NWCC_NAME_FORMAT_BIND = $0002;
  287.   NWCC_OPEN_LICENSED    = $0001;
  288.   NWCC_TRAN_TYPE_WILD  = $00008000;
  289.  
  290.   // IP status codes returned to transports and
  291.   // user IO controls.
  292.   IP_SUCCESS                = 0;
  293.   IP_BASE                   = 11000;
  294.   IP_BUFFER_TOO_SMALL       = IP_BASE + $1;
  295.   IP_DEST_NET_UNREACHABLE   = IP_BASE + $2;
  296.   IP_DEST_HOST_UNREACHABLE  = IP_BASE + $3;
  297.   IP_DEST_PROT_UNREACHABLE  = IP_BASE + $4;
  298.   IP_DEST_PORT_UNREACHABLE  = IP_BASE + $5;
  299.   IP_NO_RESOURCES           = IP_BASE + $6;
  300.   IP_BAD_OPTION             = IP_BASE + $7;
  301.   IP_ERR_HARDWARE           = IP_BASE + $8;
  302.   IP_PACKET_TOO_LARGE       = IP_BASE + $9;
  303.   IP_REQ_TIMEOUT            = IP_BASE + $A;
  304.   IP_BAD_REQ                = IP_BASE + $B;
  305.   IP_BAD_ROUTE              = IP_BASE + $C;
  306.   IP_TTL_EXPIRED_TRANSIT    = IP_BASE + $D;
  307.   IP_TTL_EXPIRED_REASSEM    = IP_BASE + $E;
  308.   IP_PARAM_PROBLEM          = IP_BASE + $F;
  309.   IP_SOURCE_QUENCH          = IP_BASE + $10;
  310.   IP_OPTION_TOO_LARGE       = IP_BASE + $11;
  311.   IP_BAD_DESTINATION        = IP_BASE + $12;
  312.  
  313.   // IP Ports
  314.   IP_PORT_ECHO              = 7;
  315.   IP_PORT_DISCARD           = 9;
  316.   IP_PORT_SYSTAT            = 11;
  317.   IP_PORT_DAYTIME           = 13;
  318.   IP_PORT_NETSTAT           = 15;
  319.   IP_PORT_FTP               = 21;
  320.   IP_PORT_TELNET            = 23;
  321.   IP_PORT_SMTP              = 25;
  322.   IP_PORT_TIMESERVER        = 37;
  323.   IP_PORT_NAMESERVER        = 42;
  324.   IP_PORT_WHOIS             = 43;
  325.   IP_PORT_MTP               = 57;
  326.   IP_PORT_GDS_DB            = 3050;
  327.  
  328.   // status codes passed up on status indications.
  329.   IP_ADDR_DELETED           = IP_BASE + $13;
  330.   IP_SPEC_MTU_CHANGE        = IP_BASE + $14;
  331.   IP_MTU_CHANGE             = IP_BASE + $15;
  332.   GENERAL_FAILURE           = IP_BASE + $16;
  333.   IP_PENDING                = IP_BASE + $FF;
  334.  
  335.   // IP header flags
  336.   IP_FLAG_DF                = $2;
  337.  
  338.   // IP option types
  339.   IP_OPT_EOL                = $0;           // end of list option
  340.   IP_OPT_NOP                = $1;           // no-op
  341.   IP_OPT_SECURITY           = $82;          // security option
  342.   IP_OPT_LSRR               = $83;          // loose source route
  343.   IP_OPT_SSRR               = $89;          // strict source route
  344.   IP_OPT_RR                 = $07;          // record route
  345.   IP_OPT_TS                 = $44;          // timestamp
  346.   IP_OPT_SID                = $88;          // stread id
  347.   MAX_OPT_SIZE              = $40;
  348.  
  349. implementation
  350.  
  351. {****************************************************************
  352. *
  353. *  G e t R e s u l t
  354. *
  355. ****************************************************************
  356. *  Author: The Client Server Factory Inc.
  357. *  Date:   March 1, 1999
  358. *
  359. *  Input:  None
  360. *
  361. *  Return: String - contains a verbose error message
  362. *
  363. *  Description:  converts a numeric error code to a
  364. *                verbose error message
  365. *
  366. *****************************************************************
  367. * Revisions:
  368. *
  369. *****************************************************************}
  370. function TibcPing.GetResult : String;
  371. var
  372.   lErr : String;
  373. begin
  374.   // determine which error code
  375.   case FLastError of
  376.     IP_SUCCESS               : lErr:='Success';
  377.     IP_BUFFER_TOO_SMALL      : lErr:='Buffer too small';
  378.     IP_DEST_NET_UNREACHABLE  : lErr:='Destination network unreachable';
  379.     IP_DEST_HOST_UNREACHABLE : lErr:='Destination host unreachable';
  380.     IP_DEST_PROT_UNREACHABLE : lErr:='Destination protocol unreachable';
  381.     IP_DEST_PORT_UNREACHABLE : lErr:='Destination port unreachable';
  382.     IP_NO_RESOURCES          : lErr:='No resources';
  383.     IP_BAD_OPTION            : lErr:='Bad Option';
  384.     IP_ERR_HARDWARE          : lErr:='Hardware error';
  385.     IP_PACKET_TOO_LARGE      : lErr:='Packet too large';
  386.     IP_REQ_TIMEOUT           : lErr:='Request timed out';
  387.     IP_BAD_REQ               : lErr:='Bad request';
  388.     IP_BAD_ROUTE             : lErr:='Bad route';
  389.     IP_TTL_EXPIRED_TRANSIT   : lErr:='TTL expired in transit';
  390.     IP_TTL_EXPIRED_REASSEM   : lErr:='TTL expired in reassembly';
  391.     IP_PARAM_PROBLEM         : lErr:='Parameter problems';
  392.     IP_SOURCE_QUENCH         : lErr:='Source quench';
  393.     IP_OPTION_TOO_LARGE      : lErr:='Option too large';
  394.     IP_BAD_DESTINATION       : lErr:='Bad destination';
  395.  
  396.     IP_ADDR_DELETED          : lErr:='Address deleted';
  397.     IP_SPEC_MTU_CHANGE       : lErr:='Spec MTU change';
  398.     IP_MTU_CHANGE            : lErr:='MTU change';
  399.     GENERAL_FAILURE          : lErr:='General failure';
  400.     IP_PENDING               : lErr:='Pending...';
  401.   else
  402.     lErr:='ICMP Error #' + IntToStr(FLastError);  // just in case
  403.   end;
  404.  
  405.   // return error message
  406.   Result:=lErr;
  407. end;
  408.  
  409. // accessor to return hostname
  410. function TibcPing.GetHostName : String;
  411. var
  412.   Host : String;
  413. begin
  414.   if FHostName <> '' then
  415.     Host:=FHostName
  416.   else
  417.     Host:='';
  418.  
  419.   Result:=Host;
  420. end;
  421.  
  422. // accessor to specify hostname
  423. procedure TibcPing.SetHostName(Host : String);
  424. begin
  425.   FHostName:=Host;
  426. end;
  427.  
  428. // accessor to get packet size
  429. function TibcPing.GetSize : Integer;
  430. begin
  431.   Result:=FSize;
  432. end;
  433.  
  434. // accessor to specify packet size
  435. procedure TibcPing.SetSize(PacketSize : Integer);
  436. begin
  437.   FSize:=PacketSize;
  438. end;
  439.  
  440. // accessor to get time to live
  441. function TibcPing.GetTTL : Integer;
  442. begin
  443.   Result:=FTTL;
  444. end;
  445.  
  446. // accessor to specify time to live
  447. procedure TibcPing.SetTTL(LiveTime : Integer);
  448. begin
  449.   FTTL:=LiveTime;
  450. end;
  451.  
  452. // accessor to get time out
  453. function TibcPing.GetTimeOut : Integer;
  454. begin
  455.   Result:=FTimeOut;
  456. end;
  457.  
  458. // accessor to specify time out
  459. procedure TibcPing.SetTimeOut(TOut : Integer);
  460. begin
  461.   FTimeout:=TOut;
  462. end;
  463.  
  464. // accessor to get host
  465. function TibcPing.GetAddr : String;
  466. begin
  467.   Result:=FAddress;
  468. end;
  469.  
  470. // accessor to specify host
  471. procedure TibcPing.SetAddr(Host : String);
  472. begin
  473.   FAddress:=Host;
  474. end;
  475.  
  476. // accessor to get time to live of reply
  477. function TibcPing.GetTTLReply : Integer;
  478. begin
  479.   Result:=Integer(FReply.Options.TTL);
  480. end;
  481.  
  482. // accessor to get round trip time of reply
  483. function TibcPing.GetRTTReply : Integer;
  484. begin
  485.   Result:=LongInt(FReply.RTT);
  486. end;
  487.  
  488. // accessor to get host IP
  489. function TibcPing.GetHostIP : String;
  490. begin
  491.   Result:=FHostIP;
  492. end;
  493.  
  494. // accessor to get last error code
  495. function TibcPing.GetLastErr : Integer;
  496. begin
  497.   Result:=FLastError;
  498. end;
  499.  
  500. {****************************************************************
  501. *
  502. *  R e s o l v e H o s t
  503. *
  504. ****************************************************************
  505. *  Author: The Client Server Factory Inc.
  506. *  Date:   March 1, 1999
  507. *
  508. *  Input:  None
  509. *
  510. *  Return: Boolean - inidicates whether the name resolution of
  511. *                    the host was successful.
  512. *
  513. *  Description:  Converts a hostname to an IP address.
  514. *
  515. *****************************************************************
  516. * Revisions:
  517. *
  518. *****************************************************************}
  519. function TibcPing.ResolveHost : Boolean;
  520. var
  521.   WSAData : TWSAData;                  // Winsock data
  522.   ptrHE   : PHostEnt;                  // pointer to HostEnt structure
  523.  
  524. begin
  525.   result := false;
  526.   // initialize winsock
  527.   if WSAStartup($101, WSAData) <> 0 then
  528.     raise TSVCException.Create('Can not initialize winsock.');
  529.  
  530.   // set hostname
  531.   FIPAddress:=inet_addr(PChar(FAddress));
  532.  
  533.   // try to resolve hostname to ip address
  534.   if FIPAddress <> LongInt(INADDR_NONE) then
  535.     FHostName:=FAddress                // if no resolution is required
  536.   else
  537.   begin                                // otherwise, get host by name
  538.     ptrHE:=GetHostByName(PChar(FAddress));
  539.     if ptrHE = Nil then                // if the structure isn't filled
  540.     begin
  541.       FLastError:=GetLastError;        // get error code
  542.       FAddrResolved:=False;            // set resolution flag to false
  543.       Result:=FAddrResolved;
  544.       Exit;
  545.     end;
  546.  
  547.     // set IP address, hostname and resolution flag True
  548.     FIPAddress:=LongInt(PLongInt(ptrHE^.h_addr_list^)^);
  549.     FHostName:=ptrHE.h_name;
  550.     FAddrResolved:=True;
  551.     Result:=FAddrResolved;
  552.   end;
  553.  
  554.   // set host IP
  555.   FHostIP:=StrPas(inet_ntoa(TInAddr(FIPAddress)));
  556. end;
  557.  
  558. {****************************************************************
  559. *
  560. *  P i n g
  561. *
  562. ****************************************************************
  563. *  Author: The Client Server Factory Inc.
  564. *  Date:   March 1, 1999
  565. *
  566. *  Input:  None
  567. *
  568. *  Return: Boolean - inidicates whether the ping operation
  569. *                    was successful.
  570. *
  571. *  Description:
  572. *
  573. *****************************************************************
  574. * Revisions:
  575. *
  576. *****************************************************************}
  577. function TibcPing.Ping : Boolean;
  578. var
  579.   WSAData         : TWSAData;          // winsock data
  580. //  ptrHE           : PHostEnt;          // pointer to HostEnt structure
  581.   BufferSize      : Integer;           // size of buffer
  582.   pReqData        : Pointer;           // pointer to request data
  583.   PData           : Pointer;           // pointer to data
  584.   pIPE            : ptrICMPEchoReply;  // pointer to ICMP reply
  585.   IPOpt           : TIPOptions;        // IP options
  586.   Msg             : String;            // dummy date
  587. //  iResult         : Integer;           // result
  588.   ICMPCreateFile  : TICMPCreateFile;   //
  589.   ICMPCloseHandle : TICMPCloseHandle;
  590.   ICMPSendEcho    : TICMPSendEcho;
  591.  
  592. begin
  593.   Result:=False;
  594.  
  595.   // initialize winsock
  596.   if WSAStartup($101, WSAData) <> 0 then
  597.     raise TSVCException.Create('Can not initialize winsock.');
  598.  
  599.   // load ICMO dll
  600.   hICMPdll:=LoadLibrary(ICMPdll);
  601.   if hICMPdll = 0 then
  602.     raise TSVCException.Create('Unable to register ' + ICMPdll);
  603.  
  604.   // ICMP library functions
  605.   @ICMPCreateFile:=GetProcAddress(hICMPdll, 'IcmpCreateFile');
  606.   @ICMPCloseHandle:=GetProcAddress(hICMPdll, 'IcmpCloseHandle');
  607.   @ICMPSendEcho:=GetProcAddress(hICMPdll, 'IcmpSendEcho');
  608.  
  609.   // ensure addresses where returned
  610.   if (@ICMPCreateFile = Nil) or
  611.      (@ICMPCloseHandle = Nil) or
  612.      (@ICMPSendEcho = Nil) then
  613.        raise TSVCException.Create('Error loading dll functions.');
  614.  
  615.   // create ICMP file
  616.   hICMP:=IcmpCreateFile;
  617.   if hICMP = INVALID_HANDLE_VALUE then
  618.     raise TSVCException.Create('Unable to get ping handle.');
  619.  
  620.   // get buffer size
  621.   BufferSize:=SizeOf(TICMPEchoReply) + FSize;
  622.   GetMem(pReqData, FSize);
  623.   GetMem(pData, FSize);
  624.   GetMem(pIPE, BufferSize);
  625.  
  626.   try
  627.     // Initialize request data buffer
  628.     FillChar(pReqData^, FSize, $20);
  629.     Msg:=('SevenOfNine');
  630.     Move(Msg[1], pReqData^, Min(FSize, Length(Msg)));
  631.  
  632.     // initialize ICMP reply data
  633.     pIPE^.Data:=pData;
  634.     FillChar(pIPE^, SizeOf(pIPE^), 0);
  635.  
  636.     // set IP options
  637.     FillChar(IPOpt, SizeOf(IPOpt), 0);
  638.     IPOpt.TTL:=FTTL;
  639.  
  640.     // get result of ICMP echo
  641.     IcmpSendEcho(hICMP, FIPAddress, pReqData, FSize,
  642.                  @IPOpt, pIPE, BufferSize, FTimeOut);
  643.  
  644.     // get last error
  645.     FLastError:=GetLastError;
  646.  
  647.     // get ICMP reply structure
  648.     FReply:=pIPE^;
  649.   finally
  650.     // deallocate memory
  651.     FreeMem(pIPE);
  652.     FreeMem(pData);
  653.     FreeMem(pReqData);
  654.     FreeLibrary(hICMPdll);
  655.   end;
  656. end;
  657.  
  658. {****************************************************************
  659. *
  660. *  G e t P o r t N a  m e
  661. *
  662. ****************************************************************
  663. *  Author: The Client Server Factory Inc.
  664. *  Date:   March 1, 1999
  665. *
  666. *  Input:  None
  667. *
  668. *  Return: String - name of well-known port
  669. *
  670. *  Description: Returns the name of a well-known port
  671. *               based on the port service number
  672. *
  673. *****************************************************************
  674. * Revisions:
  675. *
  676. *****************************************************************}
  677. function TibcSocket.GetPortName : String;
  678. var
  679.   Service : String;
  680. begin
  681.   // list of well known ports
  682.  
  683.   // determine service name based on port number
  684.   // these are well-known ports
  685.   case Port of
  686.     IP_PORT_ECHO       : Service:='ECHO';
  687.     IP_PORT_DISCARD    : Service:='DISCARD';
  688.     IP_PORT_SYSTAT     : Service:='SYSTAT';
  689.     IP_PORT_DAYTIME    : Service:='DAYTIME';
  690.     IP_PORT_NETSTAT    : Service:='NETSTAT';
  691.     IP_PORT_FTP        : Service:='FTP';
  692.     IP_PORT_TELNET     : Service:='TELNET';
  693.     IP_PORT_SMTP       : Service:='SMTP';
  694.     IP_PORT_TIMESERVER : Service:='TIMESERVER';
  695.     IP_PORT_NAMESERVER : Service:='NAMESERVER';
  696.     IP_PORT_WHOIS      : Service:='WHOIS';
  697.     IP_PORT_MTP        : Service:='MTP';
  698.     IP_PORT_GDS_DB     : Service:='GDS_DB';
  699.   else
  700.     Service:='';
  701.   end;
  702.  
  703.   FPortName:=Service;
  704.   Result:=FPortName;                   // return service name
  705. end;
  706.  
  707. // accessor to get socket desciption
  708. function TibcSocket.GetSockDesc : String;
  709. var
  710.   Desc : String;
  711. begin
  712.   if assigned(WSAInfo) then
  713.   begin
  714.     Desc:=WSAInfo.Strings[2];
  715.   end
  716.   else
  717.     Desc:='N/A';
  718.  
  719.   Result:=Desc;
  720. end;
  721.  
  722. // accessor to get socket version
  723. function TibcSocket.GetSockVersion : String;
  724. var
  725.   Version : String;
  726. begin
  727.   if assigned(WSAInfo) then
  728.   begin
  729.     Version:=WSAInfo.Strings[1];
  730.   end
  731.   else
  732.     Version:='N/A';
  733.  
  734.   Result:=Version;
  735. end;
  736.  
  737. // accessor to get server name
  738. function TibcPipes.GetServer : String;
  739. begin
  740.   Result := FServer;
  741. end;
  742.  
  743. // accessor to get path name
  744. function TibcPipes.GetPath : String;
  745. begin
  746.   Result := FPath;
  747. end;
  748.  
  749. // accessor to get max number of attempts
  750. function TibcPipes.GetTries : Integer;
  751. begin
  752.   Result := FTotal;
  753. end;
  754.  
  755. // accessor to set the server name
  756. procedure TibcPipes.SetServer(Server : String);
  757. begin
  758.   FServer := Server;
  759. end;
  760.  
  761. // accessor to set path
  762. procedure TibcPipes.SetPath(Path : String);
  763. begin
  764.   FPath := Path;
  765. end;
  766.  
  767. // accessor to set max number of attempts
  768. procedure TibcPipes.SetTries(Tries : Integer);
  769. begin
  770.   FTotal := Tries;
  771. end;
  772.  
  773. {****************************************************************
  774. *
  775. *  T e s t P i p e
  776. *
  777. ****************************************************************
  778. *  Author: The Client Server Factory Inc.
  779. *  Date:   March 1, 1999
  780. *
  781. *  Input:  sResult - a string containing the result buffer
  782. *
  783. *  Return: Boolean - indicates whether test was successful
  784. *
  785. *  Description: Creates client end of a named pipe and attempts
  786. *               to connect to the specified pipe.
  787. *
  788. *****************************************************************
  789. * Revisions:
  790. *
  791. *****************************************************************}
  792. function TibcPipes.TestPipe(var sResult : String; SilentTest : Boolean) : Boolean;
  793. var
  794.   pPipe    : PChar;                    // pipe name
  795.   iSuccess : Boolean;                  // success flag
  796.   iNum     : Integer;                  // number of tries so far
  797. //  iResult  : Integer;                  // error code
  798. begin
  799.   iSuccess := False;                 // initialize variables
  800.   iNum := 0;
  801.   try
  802. //    iResult := 0;
  803.  
  804.     if Server = '' then
  805.     begin                               // if no server name is supplied
  806.       result := false;
  807.       Exit;                            // then exit function
  808.     end;
  809.  
  810.     // set pipe name
  811.     FPipe := Format('\\%s%s', [FServer, FPath]);
  812.  
  813.     // set security attributes
  814.     FDefault:='CSDiagDefault';
  815.     FSA.nLength := SizeOf(FSA);
  816.     FSA.lpSecurityDescriptor := Nil;
  817.     FSA.bInheritHandle := FALSE;
  818.  
  819.     pPipe:=PChar(FPipe);
  820.  
  821.     if not SilentTest then
  822.       sResult:=Format('Attempting to attach to %s using NetBEUI.%s%s', [Server, CRLF, CRLF]);
  823.  
  824.     // poll until a connection is established or the max number of tries have exceeded
  825.     while (not iSuccess) and (iNum < FTotal) do
  826.     begin
  827.       hPipe := CreateFile(pPipe, GENERIC_READ or GENERIC_WRITE,
  828.               FILE_SHARE_READ or FILE_SHARE_WRITE, @FSA,
  829.               OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
  830.  
  831.       if hPipe <> INVALID_HANDLE_VALUE then
  832.       begin
  833.         // if a connection is established then set success flag
  834.         iSuccess:=True;
  835.       end
  836.       else
  837.         // if no connection yet then increment the number of tries so far
  838.         Inc(iNum);
  839.     end;
  840.  
  841. //    iResult := GetLastError;
  842.  
  843.     // build result message in buffer
  844.     if not SilentTest then
  845.     begin
  846.       if hPipe <> INVALID_HANDLE_VALUE then
  847.       begin
  848.         sResult:=Format('%sAttached successfully to %s using %s', [sResult, Server, CRLF]);
  849.         sResult:=Format('%sthe following named pipe: %s', [sResult, CRLF]);
  850.         sResult:=Format('%s   %s.%S%S', [sResult, FPipe, CRLF, CRLF]);
  851.         sResult:=Format('%sNetBEUI Communication Test Passed!', [sResult]);
  852.       end
  853.       else
  854.       begin
  855.         sResult:=Format('%sAn error occurred attempting to connect to %s%s', [sResult, Server, CRLF]);
  856.         sResult:=Format('%s   using the following named pipe:%s', [sResult, CRLF]);
  857.         sResult:=Format('%s   %s%s%s', [SResult, FPipe, CRLF, CRLF]);
  858.         sResult:=Format('%sNetBEUI Communication Test Failed!', [sResult]);
  859.       end;
  860.     end;
  861.   finally
  862.     if iSuccess then
  863.       CloseHandle(hPipe);
  864.  
  865.     Result := iSuccess;
  866.   end;
  867. end;
  868.  
  869. {****************************************************************
  870. *
  871. *  T e s t S P X
  872. *
  873. ****************************************************************
  874. *  Author: The Client Server Factory Inc.
  875. *  Date:   March 1, 1999
  876. *
  877. *  Input:  sResult - a string containing the result buffer
  878. *
  879. *  Return: Boolean - indicates whether test was successful
  880. *
  881. *  Description: Tests a SPX connection to the specified server.
  882. *
  883. *****************************************************************
  884. * Revisions:
  885. *
  886. *****************************************************************}
  887. procedure TibcSPX.TestSPX(var sResult : String);
  888. var
  889.   ccode         : Cardinal;            // return code
  890.   ConnHandle    : Cardinal;            // connection handle
  891.   lServer       : array [0..7] of char;// servername
  892.   hInstCalWin   : THandle;
  893.   hInstCLXWin   : THandle;
  894.   lError        : Boolean;
  895.   NWCallsInit   : TNWCallsInit;
  896.   NWCLXInit     : TNWCLXInit;
  897.   NWCCCloseConn : TNWCCCloseConn;
  898.   NWCCOpenConnByName : TNWCCOpenConnByName;
  899. begin
  900.   lError := False;
  901.   ccode := 0;
  902.   hInstCalWin := 0;
  903. //  hInstCLXWin := 0;
  904.   try
  905.     // load libraries
  906.     hInstCalWin := LoadLibrary(CALWIN32);
  907.     hInstCLXWin := LoadLibrary(CLXWIN32);
  908.  
  909.     // determine if libraries where successfully loaded
  910.     if (hInstCalWin > 0) and (hInstCLXWIN > 0) then
  911.     begin
  912.       // get function pointer
  913.       @NWCallsInit := GetProcAddress(hInstCalWin, PChar('NWCallsInit'));
  914.  
  915.       // if a valid function pointer is returned then call function
  916.       if @NWCallsInit <> Nil then
  917.         ccode := NWCallsInit(Nil, Nil)   // initialize
  918.       else
  919.         lError := True;                  // if no valid pointer then set error flag
  920.  
  921.       // if function call successful and no error
  922.       if (ccode = 0) and (not lError) then
  923.       begin                              // check return code
  924.         // get function pointer
  925.         @NWCLXInit := GetProcAddress(hInstCLXWin, PChar('NWCLXInit'));
  926.  
  927.         // if a valid function pointer is returned then call function
  928.         if @NWCLXInit <> Nil then
  929.           ccode := NWCLXInit(Nil, Nil)   // initialize
  930.         else
  931.           lError := True;                // if no valid pointer then set error flag
  932.  
  933.       end;
  934.  
  935.       // if either of the calls failed
  936.       if (ccode <> 0) or (lError) then
  937.       begin                              // show error message
  938.         sResult:=Format('Could not initialize Netware client library.%s%s', [CRLF, CRLF]);
  939.         sResult:=Format('%sSPX Communication Test Failed!', [sResult]);
  940.       end
  941.       else
  942.       begin
  943.         // get function pointer
  944.         @NWCCOpenConnByName := GetProcAddress(hInstCLXWin, PChar('NWCCOpenConnByName'));
  945.  
  946.         StrCopy(lServer, PChar(FServer));
  947.  
  948.         sResult:=Format('Attempting to attach to %s using SPX.%s%s', [FServer, CRLF, CRLF]);
  949.  
  950.         // if a valid function pointer is returned then call function
  951.         if @NWCCOpenConnByName <> Nil then
  952.         begin
  953.           // attempt to connect to the Netware server
  954.           ccode := NWCCOpenConnByName(0, @lServer, NWCC_NAME_FORMAT_BIND,
  955.             NWCC_OPEN_LICENSED, NWCC_TRAN_TYPE_WILD, ConnHandle);
  956.         end
  957.         else
  958.           lError := True;              // if no valid pointer then set error flag
  959.  
  960.         // check return code
  961.         if (ccode <> 0) or (lError) then
  962.         begin                            // show error message if return code not 0
  963.           sResult:=Format('%sAn error occurred attempting to connect to %s%s', [sResult, FServer, CRLF]);
  964.           sResult:=Format('%s   using the SPX protocol.%s%s', [sResult, CRLF, CRLF]);
  965.           sResult:=Format('%sSPX Communication Test Failed!', [sResult]);
  966.         end
  967.         else
  968.         begin                            // show success message if return node is 0
  969.           sResult:=Format('%sAttached successfully to %s%s', [sResult, FServer, CRLF]);
  970.           sResult:=Format('%s   using the SPX protocol.%s%s', [sResult, CRLF, CRLF]);
  971.           sResult:=Format('%sSPX Communication Test Passed!', [sResult]);
  972.         end;
  973.       end;
  974.     end
  975.     else
  976.     begin
  977.       // show error message is one of the dlls failed to load
  978.       sResult:=Format('%sAn error occurred attempting to connect to %s%s', [sResult, FServer, CRLF]);
  979.       sResult:=Format('%s   using the SPX protocol.%s%s', [sResult, CRLF, CRLF]);
  980.       sResult:=Format('%sYou do not seem to have the proper NetWare client installed.%s%s', [sResult, CRLF, CRLF]);
  981.       sResult:=Format('%sSPX Communication Test Failed!', [sResult]);
  982.     end;
  983.   finally
  984.     // close connection if active
  985.     hInstCLXWin := LoadLibrary(CLXWIN32);
  986.     if hInstCLXWin > 0 then
  987.     begin
  988.       @NWCCCloseConn := GetProcAddress(hInstCLXWin, PChar('NWCCCloseConn'));
  989.       if (@NWCCCloseConn <> Nil) and (ccode = 0) then
  990.       begin                              // if a connection is open
  991.         NWCCCloseConn(ConnHandle);       // then close the connection
  992.       end;
  993.     end;
  994.  
  995.     // free libraries
  996.     FreeLibrary(hInstCalWin);
  997.     FreeLibrary(hInstCLXWin);
  998.   end;
  999. end;
  1000.  
  1001. function TibcSPX.GetServer : String;
  1002. begin
  1003.   Result := FServer;
  1004. end;
  1005.  
  1006. procedure TibcSPX.SetServer(Server : String);
  1007. begin
  1008.   FServer:=Server;
  1009. end;
  1010.  
  1011. end.
  1012.  
  1013.