| 1 | { **************************************************************
 | 
|---|
| 2 |         Package: XWB - Kernel RPCBroker
 | 
|---|
| 3 |         Date Created: Sept 18, 1997 (Version 1.1)
 | 
|---|
| 4 |         Site Name: Oakland, OI Field Office, Dept of Veteran Affairs
 | 
|---|
| 5 |         Developers: Danila Manapsal, Don Craven, Joel Ivey
 | 
|---|
| 6 |         Description: manages Winsock connections and creates/parses
 | 
|---|
| 7 |                      messages
 | 
|---|
| 8 |         Current Release: Version 1.1 Patch 40 (Sept. 22, 2004)
 | 
|---|
| 9 | *************************************************************** }
 | 
|---|
| 10 | 
 | 
|---|
| 11 | unit Wsockc;
 | 
|---|
| 12 | {
 | 
|---|
| 13 |   Changes in v1.1.13 (JLI -- 8/23/00) -- XWB*1.1*13
 | 
|---|
| 14 |     Made changes to cursor dependent on current cursor being crDefault so
 | 
|---|
| 15 |        that the application can set it to a different cursor for long or
 | 
|---|
| 16 |        repeated processes without the cursor 'flashing' repeatedly.
 | 
|---|
| 17 | 
 | 
|---|
| 18 |   Changes in v1.1.8 (REM -- 6/18/99) -- XWB*1.1*8
 | 
|---|
| 19 |     Update version 'BrokerVer'.
 | 
|---|
| 20 | 
 | 
|---|
| 21 |   Changes in v1.1.6 (DPC -- 6/7/99) -- XWB*1.1*6
 | 
|---|
| 22 |     In tCall function, made changing cursor to hourglass conditional:
 | 
|---|
| 23 |     don't do it if XWB IM HERE  RPC is being invoked.
 | 
|---|
| 24 | 
 | 
|---|
| 25 |   Changes in V1.1.4 (DCM - 9/18/98)-XWB*1.1*4
 | 
|---|
| 26 |   1.  Changed the ff line in NetStart from:
 | 
|---|
| 27 |       if inet_addr(PChar(Server)) <> INADDR_NONE then
 | 
|---|
| 28 |       to
 | 
|---|
| 29 |       if inet_addr(PChar(Server)) <> longint(INADDR_NONE) then
 | 
|---|
| 30 |   Reason:  true 64 bit types in Delphi 4
 | 
|---|
| 31 |   2.  Changed the ff line in NetStart from:
 | 
|---|
| 32 |       $else
 | 
|---|
| 33 |       hSocket := accept(hSocketListen, DHCPHost, AddrLen);{ -- returns new socket
 | 
|---|
| 34 |       to
 | 
|---|
| 35 |       $else
 | 
|---|
| 36 |       hSocket := accept(hSocketListen, @DHCPHost, @AddrLen);{ -- returns new socket
 | 
|---|
| 37 |   Reason:  Incompatible types when recompiling
 | 
|---|
| 38 |   3. In NetStop, if socket <= 0, restore the default cursor.
 | 
|---|
| 39 |   Reason:  Gave the impression of a busy process after the Kernel login
 | 
|---|
| 40 |       process timesout.
 | 
|---|
| 41 | 
 | 
|---|
| 42 |   Changes in V1.1T3  [Feb 5, 1997]
 | 
|---|
| 43 |   1. Connect string now includes workstation name. This is used by kernel
 | 
|---|
| 44 |      security.
 | 
|---|
| 45 |   2. Code is 32bit compliant for Delphi 2.0
 | 
|---|
| 46 |   3. A great majority of PChars changed to default string (ansi-string)
 | 
|---|
| 47 |   4. Reading is done in 32k chunks during a loop.  Intermediate data is
 | 
|---|
| 48 |      buffered into a string.  At the end, a PChar is allocated and
 | 
|---|
| 49 |      returned to maintain compatibility with the original broker interface.
 | 
|---|
| 50 |      It is expected that shortly this will change once the broker component
 | 
|---|
| 51 |      changes its usage of tcall to expect a string return.  Total read
 | 
|---|
| 52 |      can now exceed 32K up to workstation OS limits.
 | 
|---|
| 53 |   5. Creation of Hostent and Address structures has been streamlined.
 | 
|---|
| 54 | 
 | 
|---|
| 55 |   Changes in V1.0T12
 | 
|---|
| 56 |   1. Inclusion of hSocket as a parameter on most API calls
 | 
|---|
| 57 | 
 | 
|---|
| 58 | 
 | 
|---|
| 59 |   Changes in V1.0T11
 | 
|---|
| 60 |   1. Reference parameter type is included. i.e. $J will be evaluated rather
 | 
|---|
| 61 |   than sending "$J".
 | 
|---|
| 62 |   2. Fully integrated with the TRPCB component interface.
 | 
|---|
| 63 |   3. This low level module is now called from an intermediate DLL.
 | 
|---|
| 64 | 
 | 
|---|
| 65 |   Changes in V1.0T10
 | 
|---|
| 66 |   1. Fixed various memory leaks.
 | 
|---|
| 67 | 
 | 
|---|
| 68 |   Changes in V1.0T9
 | 
|---|
| 69 |   1. Supports word processing fields.
 | 
|---|
| 70 |   2. Added a new exception type EBrokerError.  This is raised when errors occur
 | 
|---|
| 71 |   in NetCall, NetworkConnect, and NetworkDisconnect
 | 
|---|
| 72 | 
 | 
|---|
| 73 |   Changes in V1.0T8
 | 
|---|
| 74 |   1. Fix a problem in BuildPar in the case of a single list parameter with many
 | 
|---|
| 75 |      entries.
 | 
|---|
| 76 |   2. List parameters (arrays) can be large up to 65520 bytes
 | 
|---|
| 77 |   3. Introduction of sCallV and tCallV which use the Delphi Pascal open array
 | 
|---|
| 78 |      syntax (sCallFV and tCallV developed by Kevin Meldrum)
 | 
|---|
| 79 |   4. A new brokerDataRec type, null has been introduced to represent M calls
 | 
|---|
| 80 |      with no parameters, i.e. D FUN^LIB().
 | 
|---|
| 81 |   5. If you want to send a null parameter "", i.e. D FUN^LIB(""), Value
 | 
|---|
| 82 |   should be set to ''.
 | 
|---|
| 83 |   6. Fixed bug where a single ^ passed to sCall would generate error (confused
 | 
|---|
| 84 |   as a global reference.
 | 
|---|
| 85 |   7. Fixed a bug where a first position dot (.) in a literal parameter would
 | 
|---|
| 86 |   cause an error at the server end.
 | 
|---|
| 87 |   8. Fixed a bug where null strings (as white space in a memo box for example)
 | 
|---|
| 88 |   would not be correctly received at the server.
 | 
|---|
| 89 | 
 | 
|---|
| 90 |   Changes in V1.0T7
 | 
|---|
| 91 |   1. Procedure NetworkConnect has been changed to Function NetworkConnect
 | 
|---|
| 92 |      returning BOOL
 | 
|---|
| 93 |   2. global variable IsConnected (BOOL) can be used to determine connection
 | 
|---|
| 94 |      state
 | 
|---|
| 95 |   3. Function cRight has been fixed to preserve head pointer to input PChar
 | 
|---|
| 96 |      string
 | 
|---|
| 97 |   4. New message format which includes length calculations for input parameters
 | 
|---|
| 98 | 
 | 
|---|
| 99 |    *******************************************************************
 | 
|---|
| 100 |   A 32-bit high level interface to the Winsock API in Delphi Pascal.
 | 
|---|
| 101 | 
 | 
|---|
| 102 |   This implementation allows communications between Delphi forms and
 | 
|---|
| 103 |   DHCP back end servers through the use of the DHCP Request Broker.
 | 
|---|
| 104 | 
 | 
|---|
| 105 |   Usage: Put wsock in your Uses clause of your Delphi form.  See additional
 | 
|---|
| 106 |   specs for Request Broker message formats, etc.
 | 
|---|
| 107 |   Programmer: Enrique Gomez - VA San Francisco ISC - April 1995
 | 
|---|
| 108 | }
 | 
|---|
| 109 | 
 | 
|---|
| 110 | 
 | 
|---|
| 111 | interface
 | 
|---|
| 112 | 
 | 
|---|
| 113 | Uses
 | 
|---|
| 114 | SysUtils, winsock, xwbut1, WinProcs, Wintypes,
 | 
|---|
| 115 | classes, dialogs, forms, controls,
 | 
|---|
| 116 | stdctrls, ClipBrd, Trpcb, RpcbErr;
 | 
|---|
| 117 | 
 | 
|---|
| 118 | type
 | 
|---|
| 119 |   TXWBWinsock = class(TObject)
 | 
|---|
| 120 |   private
 | 
|---|
| 121 |     FCountWidth: Integer;
 | 
|---|
| 122 |     FIsBackwardsCompatible: Boolean;
 | 
|---|
| 123 |     FOldConnectionOnly: Boolean;
 | 
|---|
| 124 |   public
 | 
|---|
| 125 |     XNetCallPending, xFlush: boolean;
 | 
|---|
| 126 |     SocketError, XHookTimeOut: integer;
 | 
|---|
| 127 |     XNetTimerStart: TDateTime;
 | 
|---|
| 128 |     BROKERSERVER: string;
 | 
|---|
| 129 |     SecuritySegment, ApplicationSegment: string;
 | 
|---|
| 130 |     IsConnected: Boolean;
 | 
|---|
| 131 | //    NetBlockingHookVar: Function(): Bool; export;
 | 
|---|
| 132 |     function NetCall(hSocket: integer; imsg: string): PChar;
 | 
|---|
| 133 |     function tCall(hSocket: integer; api, apVer: String; Parameters: TParams;
 | 
|---|
| 134 |              var Sec, App: PChar; TimeOut: integer): PChar;
 | 
|---|
| 135 |     function cRight( z: PChar;  n: longint): PChar;
 | 
|---|
| 136 |     function cLeft( z: PChar; n: longint): PChar;
 | 
|---|
| 137 |     function BuildApi ( n,p: string; f: longint): string;
 | 
|---|
| 138 |     function BuildHdr ( wkid: string; winh: string; prch: string;
 | 
|---|
| 139 |              wish: string): string;
 | 
|---|
| 140 |     function BuildPar(hSocket: integer; api, RPCVer: string;
 | 
|---|
| 141 |              const Parameters: TParams): string;
 | 
|---|
| 142 |     function StrPack ( n: string; p: integer): string;
 | 
|---|
| 143 |     function VarPack(n: string): string;
 | 
|---|
| 144 |     function NetStart(ForegroundM: boolean; Server: string; ListenerPort: integer;
 | 
|---|
| 145 |                   var hSocket: integer): integer;
 | 
|---|
| 146 |     function NetworkConnect(ForegroundM: boolean; Server: string; ListenerPort, 
 | 
|---|
| 147 |         TimeOut: integer): Integer;
 | 
|---|
| 148 |     function libSynGetHostIP(s: string): string;
 | 
|---|
| 149 |     function libNetCreate (lpWSData : TWSAData) : integer;
 | 
|---|
| 150 |     function libNetDestroy: integer;
 | 
|---|
| 151 |     function GetServerPacket(hSocket: integer): string;
 | 
|---|
| 152 | //    function NetBlockingHook: BOOL; export;
 | 
|---|
| 153 | 
 | 
|---|
| 154 |     procedure NetworkDisconnect(hSocket: integer);
 | 
|---|
| 155 |     procedure NetStop(hSocket: integer);
 | 
|---|
| 156 |     procedure CloseSockSystem(hSocket: integer; s: string);
 | 
|---|
| 157 |     constructor Create;
 | 
|---|
| 158 | 
 | 
|---|
| 159 |     procedure NetError(Action: string; ErrType: integer);
 | 
|---|
| 160 | function NetStart1(ForegroundM: boolean; Server: string; ListenerPort: integer; 
 | 
|---|
| 161 |     var hSocket: integer): Integer; virtual;
 | 
|---|
| 162 |     function BuildPar1(hSocket: integer; api, RPCVer: string; const Parameters: 
 | 
|---|
| 163 |         TParams): String; virtual;
 | 
|---|
| 164 |     property CountWidth: Integer read FCountWidth write FCountWidth;
 | 
|---|
| 165 |     property IsBackwardsCompatible: Boolean read FIsBackwardsCompatible write 
 | 
|---|
| 166 |         FIsBackwardsCompatible;
 | 
|---|
| 167 |     property OldConnectionOnly: Boolean read FOldConnectionOnly write
 | 
|---|
| 168 |         FOldConnectionOnly;
 | 
|---|
| 169 |   end;
 | 
|---|
| 170 | 
 | 
|---|
| 171 | function LPack(Str: String; NDigits: Integer): String;
 | 
|---|
| 172 | 
 | 
|---|
| 173 | function SPack(Str: String): String;
 | 
|---|
| 174 | 
 | 
|---|
| 175 | function NetBlockingHook: BOOL; export;
 | 
|---|
| 176 | 
 | 
|---|
| 177 | var
 | 
|---|
| 178 |   HookTimeOut: Integer;
 | 
|---|
| 179 |   NetCallPending: Boolean;
 | 
|---|
| 180 |   NetTimerStart: TDateTime;
 | 
|---|
| 181 | 
 | 
|---|
| 182 | Const
 | 
|---|
| 183 |  WINSOCK1_1 = $0101;
 | 
|---|
| 184 |  DHCP_NAME = 'BROKERSERVER';
 | 
|---|
| 185 |  M_DEBUG = True;
 | 
|---|
| 186 |  M_NORMAL = False;
 | 
|---|
| 187 |  BrokerVer = '1.108';
 | 
|---|
| 188 |  Buffer64K = 65520;
 | 
|---|
| 189 |  Buffer32K = 32767;
 | 
|---|
| 190 |  Buffer24K = 24576;
 | 
|---|
| 191 |  Buffer16K = 16384;
 | 
|---|
| 192 |  Buffer8K = 8192;
 | 
|---|
| 193 |  Buffer4K = 4096;
 | 
|---|
| 194 |  DefBuffer = 256;
 | 
|---|
| 195 |  DebugOn: boolean = False;
 | 
|---|
| 196 |  XWBBASEERR = {WSABASEERR + 1} 20000;
 | 
|---|
| 197 | 
 | 
|---|
| 198 | {Broker Application Error Constants}
 | 
|---|
| 199 |  XWB_NO_HEAP    = XWBBASEERR + 1;
 | 
|---|
| 200 |  XWB_M_REJECT   = XWBBASEERR + 2;
 | 
|---|
| 201 |  XWB_BadSignOn  = XWBBASEERR + 4;
 | 
|---|
| 202 |  XWB_BadReads   = XWBBASEERR + 8;
 | 
|---|
| 203 |  XWB_ExeNoMem   = XWBBASEERR + 100;
 | 
|---|
| 204 |  XWB_ExeNoFile  = XWB_ExeNoMem +  2;
 | 
|---|
| 205 |  XWB_ExeNoPath  = XWB_ExeNoMem +  3;
 | 
|---|
| 206 |  XWB_ExeShare   = XWB_ExeNoMem +  5;
 | 
|---|
| 207 |  XWB_ExeSepSeg  = XWB_ExeNoMem +  6;
 | 
|---|
| 208 |  XWB_ExeLoMem   = XWB_ExeNoMem +  8;
 | 
|---|
| 209 |  XWB_ExeWinVer  = XWB_ExeNoMem + 10;
 | 
|---|
| 210 |  XWB_ExeBadExe  = XWB_ExeNoMem + 11;
 | 
|---|
| 211 |  XWB_ExeDifOS   = XWB_ExeNoMem + 12;
 | 
|---|
| 212 |  XWB_RpcNotReg  = XWBBASEERR + 201;
 | 
|---|
| 213 | 
 | 
|---|
| 214 | implementation
 | 
|---|
| 215 | 
 | 
|---|
| 216 |  uses fDebugInfo; {P36} //, TRPCB;
 | 
|---|
| 217 | 
 | 
|---|
| 218 | var
 | 
|---|
| 219 |   Prefix: String;
 | 
|---|
| 220 | 
 | 
|---|
| 221 | {
 | 
|---|
| 222 |   function LPack
 | 
|---|
| 223 |   Prepends the length of the string in NDigits characters to the value of Str
 | 
|---|
| 224 | 
 | 
|---|
| 225 |   e.g., LPack('DataValue',4)
 | 
|---|
| 226 |   returns   '0009DataValue'
 | 
|---|
| 227 | }
 | 
|---|
| 228 | function LPack(Str: String; NDigits: Integer): String;
 | 
|---|
| 229 | Var
 | 
|---|
| 230 |   r: Integer;
 | 
|---|
| 231 |   t: String;
 | 
|---|
| 232 |   Width: Integer;
 | 
|---|
| 233 |   Ex1: Exception;
 | 
|---|
| 234 | begin
 | 
|---|
| 235 |   r := Length(Str);
 | 
|---|
| 236 |   // check for enough space in NDigits characters
 | 
|---|
| 237 |   t := IntToStr(r);
 | 
|---|
| 238 |   Width := Length(t);
 | 
|---|
| 239 |   if NDigits < Width then
 | 
|---|
| 240 |   begin
 | 
|---|
| 241 |     Ex1 := Exception.Create('In generation of message to server, call to LPack where Length of string of '+IntToStr(Width)+' chars exceeds number of chars for output length ('+IntToStr(NDigits)+')');
 | 
|---|
| 242 |     Raise Ex1;
 | 
|---|
| 243 |   end;
 | 
|---|
| 244 |   t := '000000000' + IntToStr(r);               {eg 11-1-96}
 | 
|---|
| 245 |   Result := Copy(t, length(t)-(NDigits-1),length(t)) + Str;
 | 
|---|
| 246 | end;
 | 
|---|
| 247 | 
 | 
|---|
| 248 | {
 | 
|---|
| 249 |   function SPack
 | 
|---|
| 250 |   Prepends the length of the string in one byte to the value of Str, thus Str must be less than 256 characters.
 | 
|---|
| 251 | 
 | 
|---|
| 252 |   e.g., SPack('DataValue')
 | 
|---|
| 253 |   returns   #9 + 'DataValue'
 | 
|---|
| 254 | }
 | 
|---|
| 255 | function SPack(Str: String): String;
 | 
|---|
| 256 | Var
 | 
|---|
| 257 |   r: Integer;
 | 
|---|
| 258 |   Ex1: Exception;
 | 
|---|
| 259 | begin
 | 
|---|
| 260 |   r := Length(Str);
 | 
|---|
| 261 |   // check for enough space in one byte
 | 
|---|
| 262 |   if r > 255 then
 | 
|---|
| 263 |   begin
 | 
|---|
| 264 |     Ex1 := Exception.Create('In generation of message to server, call to SPack with Length of string of '+IntToStr(r)+' chars which exceeds max of 255 chars');
 | 
|---|
| 265 |     Raise Ex1;
 | 
|---|
| 266 |   end;
 | 
|---|
| 267 | //  t := Byte(r);               
 | 
|---|
| 268 |   Result := Char(r) + Str;
 | 
|---|
| 269 | end;
 | 
|---|
| 270 | 
 | 
|---|
| 271 | 
 | 
|---|
| 272 | function TXWBWinsock.libNetCreate (lpWSData : TWSAData) : integer;
 | 
|---|
| 273 | begin
 | 
|---|
| 274 |     Result := WSAStartup(WINSOCK1_1, lpWSData); {hard coded for Winsock
 | 
|---|
| 275 |            version 1.1}
 | 
|---|
| 276 | end;
 | 
|---|
| 277 | 
 | 
|---|
| 278 | function TXWBWinsock.libNetDestroy :integer;
 | 
|---|
| 279 | begin
 | 
|---|
| 280 |   WSAUnhookBlockingHook;      { -- restore the default mechanism};
 | 
|---|
| 281 |   WSACleanup;                 { -- shutdown TCP API};
 | 
|---|
| 282 |   Result := 1;
 | 
|---|
| 283 | end;
 | 
|---|
| 284 | 
 | 
|---|
| 285 | function TXWBWinsock.libSynGetHostIP(s: string): string;
 | 
|---|
| 286 | var
 | 
|---|
| 287 |    HostName: PChar;
 | 
|---|
| 288 |    HostAddr: TSockAddr;
 | 
|---|
| 289 |    TCPResult: PHostEnt;
 | 
|---|
| 290 |    test: longint;
 | 
|---|
| 291 |    ChangeCursor: Boolean;
 | 
|---|
| 292 | begin
 | 
|---|
| 293 |     { -- set up a hook for blocking calls so there is no automatic DoEvents
 | 
|---|
| 294 |       in the background }
 | 
|---|
| 295 |    xFlush := False;
 | 
|---|
| 296 |    NetTimerStart := Now;
 | 
|---|
| 297 |    NetCallPending := True;
 | 
|---|
| 298 |    HookTimeOut := XHookTimeOut;
 | 
|---|
| 299 |    WSASetBlockingHook(@NetBlockingHook);
 | 
|---|
| 300 | 
 | 
|---|
| 301 |    if Screen.Cursor = crDefault then
 | 
|---|
| 302 |      ChangeCursor := True
 | 
|---|
| 303 |    else
 | 
|---|
| 304 |      ChangeCursor := False;
 | 
|---|
| 305 |    if ChangeCursor then
 | 
|---|
| 306 |      Screen.Cursor := crHourGlass;
 | 
|---|
| 307 |    HostName := StrNew(PChar(s));
 | 
|---|
| 308 |    test := inet_addr(HostName);
 | 
|---|
| 309 |    if test > INADDR_ANY then
 | 
|---|
| 310 |       begin
 | 
|---|
| 311 |            Result := s;
 | 
|---|
| 312 |            StrDispose(Hostname);
 | 
|---|
| 313 |            if ChangeCursor then
 | 
|---|
| 314 |              Screen.Cursor := crDefault;
 | 
|---|
| 315 |            exit;
 | 
|---|
| 316 |       end;
 | 
|---|
| 317 | 
 | 
|---|
| 318 |    try
 | 
|---|
| 319 |    begin
 | 
|---|
| 320 |       TCPResult := gethostbyname(HostName);
 | 
|---|
| 321 |       if TCPResult = nil then
 | 
|---|
| 322 |          begin
 | 
|---|
| 323 |               if ChangeCursor then
 | 
|---|
| 324 |                 Screen.Cursor := crDefault;
 | 
|---|
| 325 |               WSAUnhookBlockingHook;
 | 
|---|
| 326 |               Result := '';
 | 
|---|
| 327 |               StrDispose(HostName);
 | 
|---|
| 328 |               exit;
 | 
|---|
| 329 |          end;
 | 
|---|
| 330 | 
 | 
|---|
| 331 |       HostAddr.sin_addr.S_addr := longint(plongint(TCPResult^.h_addr_list^)^);
 | 
|---|
| 332 | 
 | 
|---|
| 333 |    end;
 | 
|---|
| 334 |    except on EInvalidPointer do
 | 
|---|
| 335 |           begin
 | 
|---|
| 336 |                Result := '';
 | 
|---|
| 337 |                Screen.Cursor := crDefault;
 | 
|---|
| 338 |                StrDispose(HostName);
 | 
|---|
| 339 |                exit;
 | 
|---|
| 340 |           end;
 | 
|---|
| 341 |    end;
 | 
|---|
| 342 |    if ChangeCursor then
 | 
|---|
| 343 |      Screen.Cursor := crDefault;
 | 
|---|
| 344 |    WSAUnhookBlockingHook;
 | 
|---|
| 345 |    Result := StrPas(inet_ntoa(HostAddr.sin_addr));
 | 
|---|
| 346 |    StrDispose(HostName);
 | 
|---|
| 347 | end;
 | 
|---|
| 348 | 
 | 
|---|
| 349 | function TXWBWinsock.cRight;
 | 
|---|
| 350 | var
 | 
|---|
| 351 |    i,t: longint;
 | 
|---|
| 352 | begin
 | 
|---|
| 353 |      t := strlen(z);
 | 
|---|
| 354 |      if n < t then
 | 
|---|
| 355 |         begin
 | 
|---|
| 356 |              for i := 0 to n do
 | 
|---|
| 357 |                  z[i] := z[t-n+i];
 | 
|---|
| 358 |              z[n] := chr(0);
 | 
|---|
| 359 |         end;
 | 
|---|
| 360 |      cRight := z;
 | 
|---|
| 361 | end;
 | 
|---|
| 362 | 
 | 
|---|
| 363 | function TXWBWinsock.cLeft;
 | 
|---|
| 364 | var
 | 
|---|
| 365 |    t: longint;
 | 
|---|
| 366 | begin
 | 
|---|
| 367 |      t := strlen(z);
 | 
|---|
| 368 |      if n > t then n := t;
 | 
|---|
| 369 |      z[n] := chr(0);
 | 
|---|
| 370 |      cLeft := z;
 | 
|---|
| 371 | end;
 | 
|---|
| 372 | 
 | 
|---|
| 373 | function TXWBWinsock.BuildApi ( n,p: string; f: longint): string;
 | 
|---|
| 374 | Var
 | 
|---|
| 375 |   x,s: string;
 | 
|---|
| 376 | begin
 | 
|---|
| 377 |      str(f,x);
 | 
|---|
| 378 |      s := StrPack(p,5);
 | 
|---|
| 379 |      result := StrPack(x + n + '^' + s,5);
 | 
|---|
| 380 | end;
 | 
|---|
| 381 | 
 | 
|---|
| 382 | function TXWBWinsock.NetworkConnect(ForegroundM: boolean; Server: string; 
 | 
|---|
| 383 |     ListenerPort, TimeOut: integer): Integer;
 | 
|---|
| 384 | var
 | 
|---|
| 385 |    status: integer;
 | 
|---|
| 386 |    hSocket: integer;
 | 
|---|
| 387 |    BrokerError: EBrokerError;
 | 
|---|
| 388 | begin
 | 
|---|
| 389 |   Prefix := '[XWB]';
 | 
|---|
| 390 |      xFlush := False;
 | 
|---|
| 391 |      IsConnected := False;
 | 
|---|
| 392 |      XHookTimeOut := TimeOut;
 | 
|---|
| 393 |      if not OldConnectionOnly then
 | 
|---|
| 394 |      try
 | 
|---|
| 395 |        status := NetStart(ForeGroundM, server, ListenerPort, hSocket);
 | 
|---|
| 396 |      except
 | 
|---|
| 397 |        on E: EBrokerError do
 | 
|---|
| 398 |        begin
 | 
|---|
| 399 |          if IsBackwardsCompatible then  // remove DSM specific error message, and just go with any error
 | 
|---|
| 400 |          begin
 | 
|---|
| 401 |            status := NetStart1(ForeGroundM, server, ListenerPort, hSocket);
 | 
|---|
| 402 |          end
 | 
|---|
| 403 |          else if ((Pos('connection lost',E.Message) > 0) //  DSM
 | 
|---|
| 404 |               or ((Pos('recv',E.Message) > 0) and (Pos('WSAECONNRESET',E.Message) > 0))) then  // Cache
 | 
|---|
| 405 |          begin
 | 
|---|
| 406 |            BrokerError := EBrokerError.Create('Broker requires a UCX or single connection protocol and this port uses the callback protocol.'+'  The application is specified to be non-backwards compatible.  Installing patch XWB*1.1*35 and activating this port number for UCX connections will correct the problem.');
 | 
|---|
| 407 |            raise BrokerError;
 | 
|---|
| 408 |          end
 | 
|---|
| 409 |          else
 | 
|---|
| 410 |            raise;
 | 
|---|
| 411 |        end;
 | 
|---|
| 412 |      end
 | 
|---|
| 413 |      else  // OldConnectionOnly
 | 
|---|
| 414 |        status := NetStart1(ForeGroundM, server, ListenerPort, hSocket);
 | 
|---|
| 415 | 
 | 
|---|
| 416 |      if status = 0 then IsConnected := True;
 | 
|---|
| 417 |      Result := hSocket;                  {return the newly established socket}
 | 
|---|
| 418 | end;
 | 
|---|
| 419 | 
 | 
|---|
| 420 | procedure TXWBWinsock.NetworkDisconnect(hSocket: integer);
 | 
|---|
| 421 | begin
 | 
|---|
| 422 |      xFlush := False;
 | 
|---|
| 423 |      if IsConnected then
 | 
|---|
| 424 |      try
 | 
|---|
| 425 |         NetStop(hSocket);
 | 
|---|
| 426 |      except on EBrokerError do
 | 
|---|
| 427 |      begin
 | 
|---|
| 428 |           SocketError := WSAUnhookBlockingHook;     { -- rest deflt mechanism}
 | 
|---|
| 429 |           SocketError := WSACleanup;                { -- shutdown TCP API}
 | 
|---|
| 430 |      end;
 | 
|---|
| 431 |      end;
 | 
|---|
| 432 | 
 | 
|---|
| 433 | end;
 | 
|---|
| 434 | 
 | 
|---|
| 435 | function TXWBWinsock.BuildHdr ( wkid: string; winh: string; prch: string;
 | 
|---|
| 436 |          wish: string): string;
 | 
|---|
| 437 | Var
 | 
|---|
| 438 |   t: string;
 | 
|---|
| 439 | begin
 | 
|---|
| 440 |    t := wkid + ';' + winh + ';' + prch + ';' + wish + ';';
 | 
|---|
| 441 |    Result := StrPack(t,3);
 | 
|---|
| 442 | end;
 | 
|---|
| 443 | 
 | 
|---|
| 444 | function TXWBWinsock.BuildPar(hSocket: integer; api, RPCVer: string;
 | 
|---|
| 445 |          const Parameters: TParams): string;
 | 
|---|
| 446 | var
 | 
|---|
| 447 |   i,ParamCount: integer;
 | 
|---|
| 448 |   param: string;
 | 
|---|
| 449 |   tResult: string;
 | 
|---|
| 450 |   subscript: string;
 | 
|---|
| 451 |   IsSeen: Boolean;
 | 
|---|
| 452 |   BrokerError: EBrokerError;
 | 
|---|
| 453 |   Str: String;
 | 
|---|
| 454 | begin
 | 
|---|
| 455 |   param := '5';
 | 
|---|
| 456 |   if Parameters = nil then ParamCount := 0
 | 
|---|
| 457 |   else ParamCount := Parameters.Count;
 | 
|---|
| 458 |   for i := 0 to ParamCount - 1 do
 | 
|---|
| 459 |   begin
 | 
|---|
| 460 |     if Parameters[i].PType <> undefined then
 | 
|---|
| 461 |     begin
 | 
|---|
| 462 |        // Make sure that new parameter types are only used with non-callback server.
 | 
|---|
| 463 |       if IsBackwardsCompatible and ((Parameters[i].PType = global) or (Parameters[i].PType = empty) or (Parameters[i].PType = stream)) then
 | 
|---|
| 464 |       begin
 | 
|---|
| 465 |         if Parameters[i].PType = global then
 | 
|---|
| 466 |           Str := 'global'
 | 
|---|
| 467 |         else if Parameters[i].PType = empty then
 | 
|---|
| 468 |           Str := 'empty'
 | 
|---|
| 469 |         else
 | 
|---|
| 470 |           Str := 'stream';
 | 
|---|
| 471 |         BrokerError := EBrokerError.Create('Use of ' + Str + ' parameter type requires setting the TRPCBroker IsBackwardsCompatible property to FALSE');
 | 
|---|
| 472 |         raise BrokerError;
 | 
|---|
| 473 |       end;
 | 
|---|
| 474 |       with Parameters[i] do
 | 
|---|
| 475 |       begin
 | 
|---|
| 476 | //        if PType= null then
 | 
|---|
| 477 | //          param:='';
 | 
|---|
| 478 | 
 | 
|---|
| 479 |         if PType = literal then
 | 
|---|
| 480 |           param := param + '0'+LPack(Value,CountWidth)+'f';      // 030107 new message protocol
 | 
|---|
| 481 | 
 | 
|---|
| 482 |         if PType = reference then
 | 
|---|
| 483 |           param := param + '1'+LPack(Value,CountWidth)+'f';     // 030107 new message protocol
 | 
|---|
| 484 | 
 | 
|---|
| 485 |         if PType = empty then
 | 
|---|
| 486 |           param := param + '4f';
 | 
|---|
| 487 | 
 | 
|---|
| 488 |         if (PType = list) or (PType = global) then
 | 
|---|
| 489 |         begin
 | 
|---|
| 490 |           if PType = list then      // 030107 new message protocol
 | 
|---|
| 491 |             param := param + '2'
 | 
|---|
| 492 |           else
 | 
|---|
| 493 |             param := param + '3';
 | 
|---|
| 494 |           IsSeen := False;
 | 
|---|
| 495 |           subscript := Mult.First;
 | 
|---|
| 496 |           while subscript <> '' do
 | 
|---|
| 497 |           begin
 | 
|---|
| 498 |             if IsSeen then
 | 
|---|
| 499 |               param := param + 't';
 | 
|---|
| 500 |             if Mult[subscript] = '' then
 | 
|---|
| 501 |               Mult[subscript] := #1;
 | 
|---|
| 502 |             param := param + LPack(subscript,CountWidth)+LPack(Mult[subscript],CountWidth);
 | 
|---|
| 503 |             IsSeen := True;
 | 
|---|
| 504 |             subscript := Mult.Order(subscript,1);
 | 
|---|
| 505 |           end;  // while subscript <> ''
 | 
|---|
| 506 |           if not IsSeen then         // 040922 added to take care of list/global parameters with no values
 | 
|---|
| 507 |             param := param + LPack('',CountWidth);
 | 
|---|
| 508 |           param := param + 'f';
 | 
|---|
| 509 |         end;
 | 
|---|
| 510 |         if PType = stream then
 | 
|---|
| 511 |         begin
 | 
|---|
| 512 |           param := param + '5' + LPack(Value,CountWidth) + 'f';
 | 
|---|
| 513 |         end;
 | 
|---|
| 514 |       end;  // with Parameters[i] do
 | 
|---|
| 515 |     end;  // if Parameters[i].PType <> undefined
 | 
|---|
| 516 |   end; // for i := 0
 | 
|---|
| 517 |   if param = '5' then
 | 
|---|
| 518 |     param := param + '4f';
 | 
|---|
| 519 | 
 | 
|---|
| 520 |   tresult := Prefix + '11' + IntToStr(CountWidth) + '0' + '2' + SPack(RPCVer) + SPack(api) + param + #4;
 | 
|---|
| 521 | 
 | 
|---|
| 522 | //  Application.ProcessMessages;  // removed 040716 jli not needed and may impact some programs
 | 
|---|
| 523 | 
 | 
|---|
| 524 |   Result := tresult;
 | 
|---|
| 525 | end;
 | 
|---|
| 526 | {                   // previous message protocol
 | 
|---|
| 527 |   sin := TStringList.Create;
 | 
|---|
| 528 |   sin.clear;
 | 
|---|
| 529 |   x := '';
 | 
|---|
| 530 |   param := '';
 | 
|---|
| 531 |   arr := 0;
 | 
|---|
| 532 |   if Parameters = nil then ParamCount := 0
 | 
|---|
| 533 |   else ParamCount := Parameters.Count;
 | 
|---|
| 534 |   for i := 0 to ParamCount - 1 do
 | 
|---|
| 535 |     if Parameters[i].PType <> undefined then begin
 | 
|---|
| 536 |       with Parameters[i] do begin
 | 
|---|
| 537 | 
 | 
|---|
| 538 | //        if PType= null then
 | 
|---|
| 539 | //          param:='';
 | 
|---|
| 540 | 
 | 
|---|
| 541 |         if PType = literal then
 | 
|---|
| 542 |           param := param + strpack('0' + Value,3);
 | 
|---|
| 543 |         if PType = reference then
 | 
|---|
| 544 |           param := param + strpack('1' + Value,3);
 | 
|---|
| 545 |         if (PType = list) or (PType = global) then begin
 | 
|---|
| 546 |           Value := '.x';
 | 
|---|
| 547 |           param := param + strpack('2' + Value,3);
 | 
|---|
| 548 |           if Pos('.',Value) >0 then
 | 
|---|
| 549 |             x := Copy(Value,2,length(Value));
 | 
|---|
| 550 | //            if PType = wordproc then dec(last);
 | 
|---|
| 551 |             subscript := Mult.First;
 | 
|---|
| 552 |             while subscript <> '' do begin
 | 
|---|
| 553 |               if Mult[subscript] = '' then Mult[subscript] := #1;
 | 
|---|
| 554 |               sin.Add(StrPack(subscript,3) + StrPack(Mult[subscript],3));
 | 
|---|
| 555 |               subscript := Mult.Order(subscript,1);
 | 
|---|
| 556 |             end;  // while
 | 
|---|
| 557 |             sin.Add('000');
 | 
|---|
| 558 |             arr := 1;
 | 
|---|
| 559 |         end;  // if
 | 
|---|
| 560 |       end;  // with
 | 
|---|
| 561 |     end;  // if
 | 
|---|
| 562 | 
 | 
|---|
| 563 | param := Copy(param,1,Length(param));
 | 
|---|
| 564 | tsize := 0;
 | 
|---|
| 565 | 
 | 
|---|
| 566 | tResult := '';
 | 
|---|
| 567 | tout := '';
 | 
|---|
| 568 | 
 | 
|---|
| 569 | hdr := BuildHdr('XWB','','','');
 | 
|---|
| 570 | strout := strpack(hdr + BuildApi(api,param,arr),5);
 | 
|---|
| 571 | num :=0;
 | 
|---|
| 572 | 
 | 
|---|
| 573 | RPCVersion := '';
 | 
|---|
| 574 | RPCVersion := VarPack(RPCVer);
 | 
|---|
| 575 | 
 | 
|---|
| 576 | if sin.Count-1 > 0 then num := sin.Count-1;
 | 
|---|
| 577 | 
 | 
|---|
| 578 | if num > 0 then
 | 
|---|
| 579 |    begin
 | 
|---|
| 580 |         for i := 0 to num do
 | 
|---|
| 581 |           tsize := tsize + length(sin.strings[i]);
 | 
|---|
| 582 |         x := '00000' + IntToStr(tsize + length(strout)+ length(RPCVersion));
 | 
|---|
| 583 |    end;
 | 
|---|
| 584 | if num = 0 then
 | 
|---|
| 585 |    begin
 | 
|---|
| 586 |         x := '00000' + IntToStr(length(strout)+ length(RPCVersion));
 | 
|---|
| 587 |    end;
 | 
|---|
| 588 | 
 | 
|---|
| 589 | psize := x;
 | 
|---|
| 590 | psize := Copy(psize,length(psize)-5,5);
 | 
|---|
| 591 | tResult := psize;
 | 
|---|
| 592 | tResult := ConCat(tResult, RPCVersion);
 | 
|---|
| 593 | tout := strout;
 | 
|---|
| 594 | tResult := ConCat(tResult, tout);
 | 
|---|
| 595 | 
 | 
|---|
| 596 | if num > 0 then
 | 
|---|
| 597 |    begin
 | 
|---|
| 598 |         for i := 0 to num do
 | 
|---|
| 599 |             tResult := ConCat(tResult, sin.strings[i]);
 | 
|---|
| 600 |    end;
 | 
|---|
| 601 | 
 | 
|---|
| 602 | sin.free;
 | 
|---|
| 603 | 
 | 
|---|
| 604 | frmBrokerExample.Edit1.Text := tResult;
 | 
|---|
| 605 | 
 | 
|---|
| 606 | Result := tResult;  // return result
 | 
|---|
| 607 | end;
 | 
|---|
| 608 | }
 | 
|---|
| 609 | 
 | 
|---|
| 610 | function TXWBWinsock.StrPack(n: string; p: integer): String;
 | 
|---|
| 611 | Var
 | 
|---|
| 612 |   s,l: integer;
 | 
|---|
| 613 |   t,x,zero: shortstring;
 | 
|---|
| 614 |   y: string;
 | 
|---|
| 615 | begin
 | 
|---|
| 616 | 
 | 
|---|
| 617 |     s := Length(n);
 | 
|---|
| 618 |     fillchar(zero,p+1, '0');
 | 
|---|
| 619 |     SetLength(zero, p);
 | 
|---|
| 620 |     str(s,x);
 | 
|---|
| 621 |     t := zero + x;
 | 
|---|
| 622 |     l := length(x)+1;
 | 
|---|
| 623 |     y := Copy(t, l , p);
 | 
|---|
| 624 |     y := y + n;
 | 
|---|
| 625 |     Result := y;
 | 
|---|
| 626 | end;
 | 
|---|
| 627 | 
 | 
|---|
| 628 | function TXWBWinsock.VarPack(n: string): string;
 | 
|---|
| 629 | var
 | 
|---|
| 630 |    s: integer;
 | 
|---|
| 631 | begin
 | 
|---|
| 632 |      if n = '' then
 | 
|---|
| 633 |         n := '0';
 | 
|---|
| 634 |      s := Length(n);
 | 
|---|
| 635 |      SetLength(Result, s+2);
 | 
|---|
| 636 |      Result := '|' + chr(s) + n;
 | 
|---|
| 637 | end;
 | 
|---|
| 638 | 
 | 
|---|
| 639 | const
 | 
|---|
| 640 |      OneSecond = 0.000011574;
 | 
|---|
| 641 | 
 | 
|---|
| 642 | function NetBlockingHook: BOOL;
 | 
|---|
| 643 | var
 | 
|---|
| 644 |    TimeOut: double;
 | 
|---|
| 645 |      //TimeOut = 30 * OneSecond;
 | 
|---|
| 646 | 
 | 
|---|
| 647 | begin
 | 
|---|
| 648 |   if HookTimeOut > 0 then
 | 
|---|
| 649 |      TimeOut := HookTimeOut * OneSecond
 | 
|---|
| 650 |   else
 | 
|---|
| 651 |       TimeOut := OneSecond / 20;
 | 
|---|
| 652 |   Result := False;
 | 
|---|
| 653 |   if NetCallPending then
 | 
|---|
| 654 |      if Now > (NetTimerStart + TimeOut) then WSACancelBlockingCall;
 | 
|---|
| 655 | end;
 | 
|---|
| 656 | 
 | 
|---|
| 657 | function TXWBWinsock.NetCall(hSocket: integer; imsg: string): PChar;
 | 
|---|
| 658 | var
 | 
|---|
| 659 |   BufSend, BufRecv, BufPtr: PChar;
 | 
|---|
| 660 |   sBuf: string;
 | 
|---|
| 661 |   OldTimeOut: integer;
 | 
|---|
| 662 |   BytesRead, BytesLeft, BytesTotal: longint;
 | 
|---|
| 663 |   TryNumber: Integer;
 | 
|---|
| 664 |   BadXfer: Boolean;
 | 
|---|
| 665 |   xString: String;
 | 
|---|
| 666 | begin
 | 
|---|
| 667 | 
 | 
|---|
| 668 |   { -- clear receive buffer prior to sending rpc }
 | 
|---|
| 669 |   if xFlush = True then begin
 | 
|---|
| 670 |      OldTimeOut := HookTimeOut;
 | 
|---|
| 671 |      HookTimeOut := 0;
 | 
|---|
| 672 |      WSASetBlockingHook(@NetBlockingHook);
 | 
|---|
| 673 |      NetCallPending := True;
 | 
|---|
| 674 |      BufRecv := StrAlloc(Buffer32k);
 | 
|---|
| 675 |      NetTimerStart := Now;
 | 
|---|
| 676 |      BytesRead := recv(hSocket, BufRecv^, Buffer32k, 0);
 | 
|---|
| 677 |      if BytesRead > 0 then
 | 
|---|
| 678 |        while BufRecv[BytesRead-1] <> #4 do begin
 | 
|---|
| 679 |          BytesRead := recv(hSocket, BufRecv^, Buffer32k, 0);
 | 
|---|
| 680 |        end;
 | 
|---|
| 681 |      StrDispose(BufRecv);
 | 
|---|
| 682 |      xFlush := False;
 | 
|---|
| 683 |      //Buf := nil;    //P14
 | 
|---|
| 684 |      HookTimeOut := OldTimeOut;
 | 
|---|
| 685 |   end;
 | 
|---|
| 686 |   { -- provide variables for blocking hook }
 | 
|---|
| 687 | 
 | 
|---|
| 688 |   TryNumber := 0;
 | 
|---|
| 689 |   BadXfer := True;
 | 
|---|
| 690 | 
 | 
|---|
| 691 | 
 | 
|---|
| 692 |   { -- send message length + message to server }
 | 
|---|
| 693 | 
 | 
|---|
| 694 |   //BytesTotal := length(Prefix) + length(imsg) + 1 // p14
 | 
|---|
| 695 |   //Buf := StrAlloc(BytesTotal);
 | 
|---|
| 696 |   //Buf[0] := #0;
 | 
|---|
| 697 | 
 | 
|---|
| 698 |    if Prefix = '[XWB]' then
 | 
|---|
| 699 |      BufSend := StrNew(PChar({Prefix +} imsg))  //;     //moved in P14
 | 
|---|
| 700 |    else
 | 
|---|
| 701 |      BufSend := StrNew(PChar({Prefix +} imsg));
 | 
|---|
| 702 |   BufRecv := StrAlloc(Buffer32k);
 | 
|---|
| 703 |   Result := PChar('');
 | 
|---|
| 704 | //  try
 | 
|---|
| 705 |   while BadXfer and (TryNumber < 4) do
 | 
|---|
| 706 |   begin
 | 
|---|
| 707 |     NetCallPending := True;
 | 
|---|
| 708 |     NetTimerStart := Now;
 | 
|---|
| 709 |     TryNumber := TryNumber + 1;
 | 
|---|
| 710 |     BadXfer := False;
 | 
|---|
| 711 |    {Clipboard.SetTextBuf(buf);
 | 
|---|
| 712 |     ShowMessage('In Clipboard');}
 | 
|---|
| 713 |     SocketError := send(hSocket, BufSend^, StrLen(BufSend), 0);
 | 
|---|
| 714 |     if SocketError = SOCKET_ERROR then
 | 
|---|
| 715 |       NetError('send', 0);
 | 
|---|
| 716 | {
 | 
|---|
| 717 |   finally
 | 
|---|
| 718 |     StrDispose(Buf);
 | 
|---|
| 719 |     //Buf := nil;     //P14
 | 
|---|
| 720 |   end;
 | 
|---|
| 721 | }
 | 
|---|
| 722 |     BufRecv[0] := #0;
 | 
|---|
| 723 |     try
 | 
|---|
| 724 |       BufPtr := BufRecv;
 | 
|---|
| 725 |       BytesLeft := Buffer32k;
 | 
|---|
| 726 |       BytesTotal := 0;
 | 
|---|
| 727 | 
 | 
|---|
| 728 |       {Get Security and Application packets}
 | 
|---|
| 729 |       SecuritySegment := GetServerPacket(hSocket);
 | 
|---|
| 730 |       ApplicationSegment := GetServerPacket(hSocket);
 | 
|---|
| 731 |       sBuf := '';
 | 
|---|
| 732 |       { -- loop reading TCP buffer until server is finished sending reply }
 | 
|---|
| 733 | 
 | 
|---|
| 734 |       repeat
 | 
|---|
| 735 |         BytesRead := recv(hSocket, BufPtr^, BytesLeft, 0);
 | 
|---|
| 736 | 
 | 
|---|
| 737 |         if BytesRead > 0 then begin
 | 
|---|
| 738 |           if BufPtr[BytesRead-1] = #4 then
 | 
|---|
| 739 |           begin
 | 
|---|
| 740 |             sBuf := ConCat(sBuf, BufPtr);
 | 
|---|
| 741 |           end
 | 
|---|
| 742 |           else
 | 
|---|
| 743 |           begin
 | 
|---|
| 744 |             BufPtr[BytesRead] := #0;
 | 
|---|
| 745 |             sBuf := ConCat(sBuf, BufPtr);
 | 
|---|
| 746 |           end;
 | 
|---|
| 747 |           Inc(BytesTotal, BytesRead);
 | 
|---|
| 748 |         end;
 | 
|---|
| 749 | 
 | 
|---|
| 750 |         if BytesRead <= 0 then
 | 
|---|
| 751 |         begin
 | 
|---|
| 752 |           if BytesRead = SOCKET_ERROR then
 | 
|---|
| 753 |             NetError('recv', 0)
 | 
|---|
| 754 |           else
 | 
|---|
| 755 |             NetError('connection lost', 0);
 | 
|---|
| 756 |           break;
 | 
|---|
| 757 |         end;
 | 
|---|
| 758 |       until BufPtr[BytesRead-1] = #4;
 | 
|---|
| 759 |       sBuf := Copy(sBuf, 1, BytesTotal - 1);
 | 
|---|
| 760 |       StrDispose(BufRecv);
 | 
|---|
| 761 |       BufRecv := StrAlloc(BytesTotal+1);   // cause of many memory leaks
 | 
|---|
| 762 |       StrCopy(BufRecv, PChar(sBuf));
 | 
|---|
| 763 |       Result := BufRecv;
 | 
|---|
| 764 |       if ApplicationSegment = 'U411' then
 | 
|---|
| 765 |         BadXfer := True;
 | 
|---|
| 766 |       NetCallPending := False;
 | 
|---|
| 767 |     finally
 | 
|---|
| 768 |       sBuf := '';
 | 
|---|
| 769 |     end;
 | 
|---|
| 770 |   end;
 | 
|---|
| 771 | 
 | 
|---|
| 772 |   if BadXfer then
 | 
|---|
| 773 |   begin
 | 
|---|
| 774 |     StrDispose(BufRecv);
 | 
|---|
| 775 |     NetError(StrPas('Repeated Incomplete Reads on the server'), XWB_BadReads);
 | 
|---|
| 776 |     Result := StrNew('');
 | 
|---|
| 777 |   end;
 | 
|---|
| 778 | 
 | 
|---|
| 779 |   { -- if there was on error on the server, display the error code }
 | 
|---|
| 780 | 
 | 
|---|
| 781 |   if Result[0] = #24 then
 | 
|---|
| 782 |   begin
 | 
|---|
| 783 |     xString := StrPas(@Result[1]);
 | 
|---|
| 784 |     StrDispose(BufRecv);
 | 
|---|
| 785 |     NetError(xString, XWB_M_REJECT);
 | 
|---|
| 786 | //    NetCall := #0;
 | 
|---|
| 787 |     Result := StrNew('');
 | 
|---|
| 788 |   end;
 | 
|---|
| 789 | end;
 | 
|---|
| 790 | 
 | 
|---|
| 791 | function TXWBWinsock.tCall(hSocket: integer; api, apVer: String; Parameters: TParams;
 | 
|---|
| 792 |          var Sec , App: PChar; TimeOut: integer ): PChar;
 | 
|---|
| 793 | var
 | 
|---|
| 794 |  tmp: string;
 | 
|---|
| 795 |  ChangeCursor: Boolean;
 | 
|---|
| 796 | begin
 | 
|---|
| 797 |      HookTimeOut := TimeOut;
 | 
|---|
| 798 |      if (string(Api) <> 'XWB IM HERE') and (Screen.Cursor = crDefault) then
 | 
|---|
| 799 |        ChangeCursor  := True
 | 
|---|
| 800 |      else
 | 
|---|
| 801 |        ChangeCursor := False;
 | 
|---|
| 802 |      if ChangeCursor then
 | 
|---|
| 803 |        Screen.Cursor := crHourGlass;  //P6
 | 
|---|
| 804 | 
 | 
|---|
| 805 |      if Prefix = '[XWB]' then
 | 
|---|
| 806 |        tmp := BuildPar(hSocket, api, apVer, Parameters)
 | 
|---|
| 807 |      else
 | 
|---|
| 808 |        tmp := BuildPar1(hSocket, api, apVer, Parameters);
 | 
|---|
| 809 | 
 | 
|---|
| 810 | //     xFlush := True;     // Have it clear input buffers prior to call
 | 
|---|
| 811 |      Result := NetCall(hSocket, tmp);
 | 
|---|
| 812 |      StrPCopy(Sec, SecuritySegment);
 | 
|---|
| 813 |      StrPCopy(App, ApplicationSegment);
 | 
|---|
| 814 |      if ChangeCursor then
 | 
|---|
| 815 |        Screen.Cursor := crDefault;
 | 
|---|
| 816 | end;
 | 
|---|
| 817 | 
 | 
|---|
| 818 | 
 | 
|---|
| 819 | function TXWBWinsock.NetStart (ForegroundM: boolean; Server: string;
 | 
|---|
| 820 |                    ListenerPort: integer; var hSocket: integer): integer;
 | 
|---|
| 821 | Var
 | 
|---|
| 822 |   WinSockData: TWSADATA;
 | 
|---|
| 823 |   LocalHost, DHCPHost: TSockAddr;
 | 
|---|
| 824 |   LocalName, workstation, pDHCPName: string;
 | 
|---|
| 825 |   y, tmp, upArrow, rAccept, rLost: string;
 | 
|---|
| 826 |   tmpPchar: PChar;
 | 
|---|
| 827 |   pLocalname: array [0..255] of char;
 | 
|---|
| 828 |   r: integer;
 | 
|---|
| 829 |   HostBuf,DHCPBuf: PHostEnt;
 | 
|---|
| 830 |   lin: TLinger;
 | 
|---|
| 831 |   s_lin: array [0..3] of char absolute lin;
 | 
|---|
| 832 |   ChangeCursor: Boolean;
 | 
|---|
| 833 | begin
 | 
|---|
| 834 | { ForegroundM is a boolean value, TRUE means the M handling process is
 | 
|---|
| 835 |   running interactively a pointer rather than passing address length
 | 
|---|
| 836 |   by value) }
 | 
|---|
| 837 | 
 | 
|---|
| 838 |     { -- initialize Windows Sockets API for this task }
 | 
|---|
| 839 |     if Screen.Cursor = crDefault then
 | 
|---|
| 840 |       ChangeCursor := True
 | 
|---|
| 841 |     else
 | 
|---|
| 842 |       ChangeCursor := False;
 | 
|---|
| 843 |     if ChangeCursor then
 | 
|---|
| 844 |       Screen.Cursor := crHourGlass;
 | 
|---|
| 845 |     upArrow := string('^');
 | 
|---|
| 846 |     rAccept := string('accept');
 | 
|---|
| 847 |     rLost := string('(connection lost)');
 | 
|---|
| 848 | 
 | 
|---|
| 849 |     SocketError := WSAStartup(WINSOCK1_1, WinSockData);
 | 
|---|
| 850 |     If SocketError >0 Then
 | 
|---|
| 851 |             NetError( 'WSAStartup',0);
 | 
|---|
| 852 | 
 | 
|---|
| 853 |     { -- set up a hook for blocking calls so there is no automatic DoEvents
 | 
|---|
| 854 |      in the background }
 | 
|---|
| 855 |     NetCallPending := False;
 | 
|---|
| 856 |     if ForeGroundM = False then if WSASetBlockingHook(@NetBlockingHook) = nil
 | 
|---|
| 857 |        then NetError('WSASetBlockingHook',0);
 | 
|---|
| 858 | 
 | 
|---|
| 859 |     { -- establish HostEnt and Address structure for local machine}
 | 
|---|
| 860 |     SocketError := gethostname(pLocalName, 255); { -- name of local system}
 | 
|---|
| 861 |     If SocketError >0 Then
 | 
|---|
| 862 |        NetError ('gethostname (local)',0);
 | 
|---|
| 863 |     HostBuf := gethostbyname(pLocalName); { -- info for local name}
 | 
|---|
| 864 |     If HostBuf = nil Then
 | 
|---|
| 865 |        NetError( 'gethostbyname',0);
 | 
|---|
| 866 |     LocalHost.sin_addr.S_addr := longint(plongint(HostBuf^.h_addr_list^)^);
 | 
|---|
| 867 |     LocalName := inet_ntoa(LocalHost.sin_addr);
 | 
|---|
| 868 |     workstation := string(HostBuf.h_name);
 | 
|---|
| 869 | 
 | 
|---|
| 870 |     { -- establish HostEnt and Address structure for remote machine }
 | 
|---|
| 871 |     if inet_addr(PChar(Server)) <> longint(INADDR_NONE) then
 | 
|---|
| 872 |     begin
 | 
|---|
| 873 |       DHCPHost.sin_addr.S_addr := inet_addr(PChar(Server));
 | 
|---|
| 874 |       DHCPBuf := gethostbyaddr(@DHCPHost.sin_addr.S_addr,sizeof(DHCPHost),PF_INET);
 | 
|---|
| 875 |     end
 | 
|---|
| 876 |     else
 | 
|---|
| 877 |         DHCPBuf := gethostbyname(PChar(Server)); { --  info for DHCP system}
 | 
|---|
| 878 | 
 | 
|---|
| 879 |     If DHCPBuf = nil Then
 | 
|---|
| 880 |     begin
 | 
|---|
| 881 |         { modification to take care of problems with 10-dot addresses that weren't registered - solution found by Shawn Hardenbrook }
 | 
|---|
| 882 | //            NetError ('Error Identifying Remote Host ' + Server,0);
 | 
|---|
| 883 | //            NetStart := 10001;
 | 
|---|
| 884 | //            exit;
 | 
|---|
| 885 |       DHCPHost.sin_addr.S_addr := inet_addr(PChar(Server));
 | 
|---|
| 886 |       pDHCPName := 'UNKNOWN';
 | 
|---|
| 887 |     end
 | 
|---|
| 888 |     else
 | 
|---|
| 889 |     begin;
 | 
|---|
| 890 |       DHCPHost.sin_addr.S_addr := longint(plongint(DHCPBuf^.h_addr_list^)^);
 | 
|---|
| 891 |       pDHCPName := inet_ntoa(DHCPHost.sin_addr);
 | 
|---|
| 892 |     end;
 | 
|---|
| 893 |     DHCPHost.sin_family := PF_INET;                 { -- internet address type}
 | 
|---|
| 894 |     DHCPHost.sin_port := htons(ListenerPort);        { -- port to connect to}
 | 
|---|
| 895 | 
 | 
|---|
| 896 |     { -- make connection to DHCP }
 | 
|---|
| 897 |     hSocket := socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
 | 
|---|
| 898 |     If hSocket = INVALID_SOCKET Then
 | 
|---|
| 899 |             NetError( 'socket',0);
 | 
|---|
| 900 | 
 | 
|---|
| 901 |     SocketError := connect(hSocket, DHCPHost, SizeOf(DHCPHost));
 | 
|---|
| 902 |     If SocketError = SOCKET_ERROR Then
 | 
|---|
| 903 |        NetError( 'connect',0);
 | 
|---|
| 904 |     HookTimeOut := 30;
 | 
|---|
| 905 | 
 | 
|---|
| 906 |        { -- remove setup of hSocketListen
 | 
|---|
| 907 | 
 | 
|---|
| 908 | //    establish local IP now that connection is done
 | 
|---|
| 909 |     AddrLen := SizeOf(LocalHost);
 | 
|---|
| 910 |     SocketError := getsockname(hSocket, LocalHost, AddrLen);
 | 
|---|
| 911 |     if SocketError = SOCKET_ERROR then
 | 
|---|
| 912 |        NetError ('getsockname',0);
 | 
|---|
| 913 |     LocalName := inet_ntoa(LocalHost.sin_addr);
 | 
|---|
| 914 | 
 | 
|---|
| 915 | //   -- set up listening socket for DHCP return connect
 | 
|---|
| 916 |     hSocketListen := socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); // --  new socket
 | 
|---|
| 917 |     If hSocketListen = INVALID_SOCKET Then
 | 
|---|
| 918 |       NetError ('socket (listening)',0);
 | 
|---|
| 919 | 
 | 
|---|
| 920 |     LocalHost.sin_family := PF_INET;            // -- internet address type
 | 
|---|
| 921 |     LocalHost.sin_port := 0;                    // -- local listening port
 | 
|---|
| 922 |     SocketError := bind(hSocketListen, LocalHost,
 | 
|---|
| 923 |                 SizeOf(LocalHost)); // -- bind socket to address
 | 
|---|
| 924 |     If SocketError = SOCKET_ERROR Then
 | 
|---|
| 925 |       NetError( 'bind',0);
 | 
|---|
| 926 | 
 | 
|---|
| 927 |     AddrLen := sizeof(LocalHost);
 | 
|---|
| 928 |     SocketError := getsockname(hSocketListen, LocalHost,
 | 
|---|
| 929 |                 AddrLen);  // -- get listening port #
 | 
|---|
| 930 |     If SocketError = SOCKET_ERROR Then
 | 
|---|
| 931 |        NetError( 'getsockname',0);
 | 
|---|
| 932 |     LocalPort := ntohs(LocalHost.sin_port);    // -- put in proper byte order
 | 
|---|
| 933 | 
 | 
|---|
| 934 |     SocketError := listen(hSocketListen, 1);   // -- put socket in listen mode
 | 
|---|
| 935 |     If SocketError = SOCKET_ERROR Then
 | 
|---|
| 936 |             NetError( 'listen',0);
 | 
|---|
| 937 | }
 | 
|---|
| 938 |     { -- send IP address + port + workstation name and wait for OK : eg 1-30-97}
 | 
|---|
| 939 | {
 | 
|---|
| 940 |     RPCVersion := VarPack(BrokerVer);              //   eg 11-1-96
 | 
|---|
| 941 |     x := string('TCPconnect^');
 | 
|---|
| 942 |     x := ConCat(x, LocalName, upArrow);            //   local ip address
 | 
|---|
| 943 |     t := IntToStr(LocalPort);                         // callback port
 | 
|---|
| 944 |     x := ConCat(x, t, upArrow, workstation, upArrow); // workstation name
 | 
|---|
| 945 |     r := length(x) + length(RPCVersion) + 5;
 | 
|---|
| 946 |     t := string('00000') + IntToStr(r);               // eg 11-1-96
 | 
|---|
| 947 |     y := Copy(t, length(t)-4,length(t));
 | 
|---|
| 948 |     y := ConCat(y, RPCVersion, StrPack(x,5));         // rpc version
 | 
|---|
| 949 | }
 | 
|---|
| 950 |     { new protocol 030107 }
 | 
|---|
| 951 | 
 | 
|---|
| 952 | //    y := '[XWB]10' +IntToStr(CountWidth)+ '0' + '4'+#$A+'TCPConnect50'+ LPack(LocalName,CountWidth)+'f0'+LPack(IntToStr(LocalPort),CountWidth)+'f0'+LPack(workstation,CountWidth)+'f'+#4;
 | 
|---|
| 953 |     y := Prefix + '10' +IntToStr(CountWidth)+ '0' + '4'+#$A +'TCPConnect50'+ LPack(LocalName,CountWidth)+'f0'+LPack(IntToStr(0),CountWidth)+'f0'+LPack(workstation,CountWidth)+'f'+#4;
 | 
|---|
| 954 | 
 | 
|---|
| 955 | {  // need to remove selecting port etc from client, since it will now be handled on the server P36
 | 
|---|
| 956 | 
 | 
|---|
| 957 |     if ForeGroundM = True then
 | 
|---|
| 958 |     begin
 | 
|---|
| 959 |          if ChangeCursor then
 | 
|---|
| 960 |            Screen.Cursor := crDefault;
 | 
|---|
| 961 |          t := 'Start M job D EN^XWBTCP' + #13 + #10 + 'Addr = ' +
 | 
|---|
| 962 |            LocalName + #13 + #10 + 'Port = ' + IntToStr(LocalPort);
 | 
|---|
| 963 | 
 | 
|---|
| 964 |          frmDebugInfo := TfrmDebugInfo.Create(Application.MainForm);
 | 
|---|
| 965 |          try
 | 
|---|
| 966 |            frmDebugInfo.lblDebugInfo.Caption := t;
 | 
|---|
| 967 |            ShowApplicationAndFocusOK(Application);
 | 
|---|
| 968 |            frmDebugInfo.ShowModal;
 | 
|---|
| 969 |          finally
 | 
|---|
| 970 |            frmDebugInfo.Free
 | 
|---|
| 971 |          end;
 | 
|---|
| 972 | 
 | 
|---|
| 973 | //         ShowMessage(t);  //TODO
 | 
|---|
| 974 |     end;
 | 
|---|
| 975 | }  // remove debug mode from client
 | 
|---|
| 976 | 
 | 
|---|
| 977 |     tmpPChar := NetCall(hSocket, PChar(y));                {eg 11-1-96}
 | 
|---|
| 978 |     tmp := tmpPchar;
 | 
|---|
| 979 |     StrDispose(tmpPchar);
 | 
|---|
| 980 |     if CompareStr(tmp, rlost) = 0 then
 | 
|---|
| 981 |        begin
 | 
|---|
| 982 |             lin.l_onoff := 1;
 | 
|---|
| 983 |             lin.l_linger := 0;
 | 
|---|
| 984 | 
 | 
|---|
| 985 |             SocketError := setsockopt(hSocket, SOL_SOCKET, SO_LINGER,
 | 
|---|
| 986 |                         s_lin, sizeof(lin));
 | 
|---|
| 987 |             If SocketError = SOCKET_ERROR Then
 | 
|---|
| 988 |                NetError( 'setsockopt (connect)',0);
 | 
|---|
| 989 | 
 | 
|---|
| 990 |           closesocket(hSocket);
 | 
|---|
| 991 |           WSACleanup;
 | 
|---|
| 992 |           Result := 10002;
 | 
|---|
| 993 |           exit;
 | 
|---|
| 994 |        end;
 | 
|---|
| 995 |     r := CompareStr(tmp, rAccept);
 | 
|---|
| 996 |     If r <> 0 Then
 | 
|---|
| 997 |        NetError ('NetCall',XWB_M_REJECT);
 | 
|---|
| 998 | {  // JLI 021217 remove disconnect and reconnect code -- use UCX connection directly.
 | 
|---|
| 999 |     lin.l_onoff := 1;
 | 
|---|
| 1000 |     lin.l_linger := 0;
 | 
|---|
| 1001 | 
 | 
|---|
| 1002 |     SocketError := setsockopt(hSocket, SOL_SOCKET, SO_LINGER,
 | 
|---|
| 1003 |                 s_lin, sizeof(lin));
 | 
|---|
| 1004 |     If SocketError = SOCKET_ERROR Then
 | 
|---|
| 1005 |        NetError( 'setsockopt (connect)',0);
 | 
|---|
| 1006 |     SocketError := closesocket(hSocket);          { -- done with this socket
 | 
|---|
| 1007 |     If SocketError > 0 Then
 | 
|---|
| 1008 |             NetError( 'closesocket',0);
 | 
|---|
| 1009 | 
 | 
|---|
| 1010 |     { -- wait for connect from DHCP and accept it - (uses blocking call)
 | 
|---|
| 1011 |     AddrLen := SizeOf(DHCPHost);
 | 
|---|
| 1012 |     hSocket := accept(hSocketListen, @DHCPHost, @AddrLen);{ -- returns new socket
 | 
|---|
| 1013 |     If hSocket = INVALID_SOCKET Then
 | 
|---|
| 1014 |        begin
 | 
|---|
| 1015 |             NetError( 'accept',0);
 | 
|---|
| 1016 |        end;
 | 
|---|
| 1017 | 
 | 
|---|
| 1018 |     lin.l_onoff := 1;
 | 
|---|
| 1019 |     lin.l_linger := 0;
 | 
|---|
| 1020 | 
 | 
|---|
| 1021 |     SocketError := setsockopt(hSocketListen, SOL_SOCKET, SO_LINGER,
 | 
|---|
| 1022 |                 s_lin, sizeof(lin));
 | 
|---|
| 1023 |     If SocketError = SOCKET_ERROR Then
 | 
|---|
| 1024 |        NetError( 'setsockopt (connect)',0);
 | 
|---|
| 1025 | 
 | 
|---|
| 1026 |     SocketError := closesocket(hSocketListen);   // -- done with listen skt
 | 
|---|
| 1027 | 
 | 
|---|
| 1028 |     If SocketError > 0 Then
 | 
|---|
| 1029 |        begin
 | 
|---|
| 1030 |             NetError ('closesocket (listening)',0);
 | 
|---|
| 1031 |        end;
 | 
|---|
| 1032 | }             // JLI 12/17/02  end of section commented out
 | 
|---|
| 1033 | 
 | 
|---|
| 1034 |     if ChangeCursor then
 | 
|---|
| 1035 |       Screen.Cursor := crDefault;
 | 
|---|
| 1036 |     NetStart := 0;
 | 
|---|
| 1037 | { -- connection established, socket handle now in:  hSocket
 | 
|---|
| 1038 |         ifrmWinSock.txtStatus := 'socket obtained' *** }
 | 
|---|
| 1039 | end;
 | 
|---|
| 1040 | 
 | 
|---|
| 1041 | function TXWBWinsock.NetStart1(ForegroundM: boolean; Server: string;
 | 
|---|
| 1042 |     ListenerPort: integer; var hSocket: integer): Integer;
 | 
|---|
| 1043 | Var
 | 
|---|
| 1044 |   WinSockData: TWSADATA;
 | 
|---|
| 1045 |   LocalHost, DHCPHost: TSockAddr;
 | 
|---|
| 1046 |   LocalName, t, workstation, pDHCPName: string;
 | 
|---|
| 1047 |   x, y, tmp,RPCVersion, upArrow, rAccept, rLost: string;
 | 
|---|
| 1048 |   tmpPchar: PChar;
 | 
|---|
| 1049 |   pLocalname: array [0..255] of char;
 | 
|---|
| 1050 |   LocalPort, AddrLen, hSocketListen,r: integer;
 | 
|---|
| 1051 |   HostBuf,DHCPBuf: PHostEnt;
 | 
|---|
| 1052 |   lin: TLinger;
 | 
|---|
| 1053 |   s_lin: array [0..3] of char absolute lin;
 | 
|---|
| 1054 |   ChangeCursor: Boolean;
 | 
|---|
| 1055 | begin
 | 
|---|
| 1056 |   Prefix := '{XWB}';
 | 
|---|
| 1057 | { ForegroundM is a boolean value, TRUE means the M handling process is
 | 
|---|
| 1058 |   running interactively a pointer rather than passing address length
 | 
|---|
| 1059 |   by value) }
 | 
|---|
| 1060 | 
 | 
|---|
| 1061 |     { -- initialize Windows Sockets API for this task }
 | 
|---|
| 1062 |     if Screen.Cursor = crDefault then
 | 
|---|
| 1063 |       ChangeCursor := True
 | 
|---|
| 1064 |     else
 | 
|---|
| 1065 |       ChangeCursor := False;
 | 
|---|
| 1066 |     if ChangeCursor then
 | 
|---|
| 1067 |       Screen.Cursor := crHourGlass;
 | 
|---|
| 1068 |     upArrow := string('^');
 | 
|---|
| 1069 |     rAccept := string('accept');
 | 
|---|
| 1070 |     rLost := string('(connection lost)');
 | 
|---|
| 1071 | 
 | 
|---|
| 1072 |     SocketError := WSAStartup(WINSOCK1_1, WinSockData);
 | 
|---|
| 1073 |     If SocketError >0 Then
 | 
|---|
| 1074 |             NetError( 'WSAStartup',0);
 | 
|---|
| 1075 | 
 | 
|---|
| 1076 |     { -- set up a hook for blocking calls so there is no automatic DoEvents
 | 
|---|
| 1077 |      in the background }
 | 
|---|
| 1078 |     NetCallPending := False;
 | 
|---|
| 1079 |     if ForeGroundM = False then if WSASetBlockingHook(@NetBlockingHook) = nil
 | 
|---|
| 1080 |        then NetError('WSASetBlockingHook',0);
 | 
|---|
| 1081 | 
 | 
|---|
| 1082 |     { -- establish HostEnt and Address structure for local machine}
 | 
|---|
| 1083 |     SocketError := gethostname(pLocalName, 255); { -- name of local system}
 | 
|---|
| 1084 |     If SocketError >0 Then
 | 
|---|
| 1085 |        NetError ('gethostname (local)',0);
 | 
|---|
| 1086 |     HostBuf := gethostbyname(pLocalName); { -- info for local name}
 | 
|---|
| 1087 |     If HostBuf = nil Then
 | 
|---|
| 1088 |        NetError( 'gethostbyname',0);
 | 
|---|
| 1089 |     LocalHost.sin_addr.S_addr := longint(plongint(HostBuf^.h_addr_list^)^);
 | 
|---|
| 1090 |     LocalName := inet_ntoa(LocalHost.sin_addr);
 | 
|---|
| 1091 |     workstation := string(HostBuf.h_name);
 | 
|---|
| 1092 | 
 | 
|---|
| 1093 |     { -- establish HostEnt and Address structure for remote machine }
 | 
|---|
| 1094 |     if inet_addr(PChar(Server)) <> longint(INADDR_NONE) then
 | 
|---|
| 1095 |     begin
 | 
|---|
| 1096 |       DHCPHost.sin_addr.S_addr := inet_addr(PChar(Server));
 | 
|---|
| 1097 |       DHCPBuf := gethostbyaddr(@DHCPHost.sin_addr.S_addr,sizeof(DHCPHost),PF_INET);
 | 
|---|
| 1098 |     end
 | 
|---|
| 1099 |     else
 | 
|---|
| 1100 |         DHCPBuf := gethostbyname(PChar(Server)); { --  info for DHCP system}
 | 
|---|
| 1101 | 
 | 
|---|
| 1102 |     If DHCPBuf = nil Then
 | 
|---|
| 1103 |     begin
 | 
|---|
| 1104 |         { modification to take care of problems with 10-dot addresses that weren't registered - solution found by Shawn Hardenbrook }
 | 
|---|
| 1105 | //            NetError ('Error Identifying Remote Host ' + Server,0);
 | 
|---|
| 1106 | //            NetStart := 10001;
 | 
|---|
| 1107 | //            exit;
 | 
|---|
| 1108 |       DHCPHost.sin_addr.S_addr := inet_addr(PChar(Server));
 | 
|---|
| 1109 |       pDHCPName := 'UNKNOWN';
 | 
|---|
| 1110 |     end
 | 
|---|
| 1111 |     else
 | 
|---|
| 1112 |     begin;
 | 
|---|
| 1113 |       DHCPHost.sin_addr.S_addr := longint(plongint(DHCPBuf^.h_addr_list^)^);
 | 
|---|
| 1114 |       pDHCPName := inet_ntoa(DHCPHost.sin_addr);
 | 
|---|
| 1115 |     end;
 | 
|---|
| 1116 |     DHCPHost.sin_family := PF_INET;                 { -- internet address type}
 | 
|---|
| 1117 |     DHCPHost.sin_port := htons(ListenerPort);        { -- port to connect to}
 | 
|---|
| 1118 | 
 | 
|---|
| 1119 |     { -- make connection to DHCP }
 | 
|---|
| 1120 |     hSocket := socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
 | 
|---|
| 1121 |     If hSocket = INVALID_SOCKET Then
 | 
|---|
| 1122 |             NetError( 'socket',0);
 | 
|---|
| 1123 | 
 | 
|---|
| 1124 |     SocketError := connect(hSocket, DHCPHost, SizeOf(DHCPHost));
 | 
|---|
| 1125 |     If SocketError = SOCKET_ERROR Then
 | 
|---|
| 1126 |        NetError( 'connect',0);
 | 
|---|
| 1127 | 
 | 
|---|
| 1128 |     {establish local IP now that connection is done}
 | 
|---|
| 1129 |     AddrLen := SizeOf(LocalHost);
 | 
|---|
| 1130 |     SocketError := getsockname(hSocket, LocalHost, AddrLen);
 | 
|---|
| 1131 |     if SocketError = SOCKET_ERROR then
 | 
|---|
| 1132 |        NetError ('getsockname',0);
 | 
|---|
| 1133 |     LocalName := inet_ntoa(LocalHost.sin_addr);
 | 
|---|
| 1134 | 
 | 
|---|
| 1135 | //    { -- set up listening socket for DHCP return connect }
 | 
|---|
| 1136 |     hSocketListen := socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); // --  new socket
 | 
|---|
| 1137 |     If hSocketListen = INVALID_SOCKET Then
 | 
|---|
| 1138 |       NetError ('socket (listening)',0);
 | 
|---|
| 1139 | 
 | 
|---|
| 1140 |     LocalHost.sin_family := PF_INET;            // -- internet address type
 | 
|---|
| 1141 |     LocalHost.sin_port := 0;                    // -- local listening port
 | 
|---|
| 1142 |     SocketError := bind(hSocketListen, LocalHost,
 | 
|---|
| 1143 |                 SizeOf(LocalHost)); // -- bind socket to address
 | 
|---|
| 1144 |     If SocketError = SOCKET_ERROR Then
 | 
|---|
| 1145 |       NetError( 'bind',0);
 | 
|---|
| 1146 | 
 | 
|---|
| 1147 |     AddrLen := sizeof(LocalHost);
 | 
|---|
| 1148 |     SocketError := getsockname(hSocketListen, LocalHost,
 | 
|---|
| 1149 |                 AddrLen);  // -- get listening port #
 | 
|---|
| 1150 |     If SocketError = SOCKET_ERROR Then
 | 
|---|
| 1151 |        NetError( 'getsockname',0);
 | 
|---|
| 1152 |     LocalPort := ntohs(LocalHost.sin_port);    // -- put in proper byte order
 | 
|---|
| 1153 | 
 | 
|---|
| 1154 |     SocketError := listen(hSocketListen, 1);   // -- put socket in listen mode
 | 
|---|
| 1155 |     If SocketError = SOCKET_ERROR Then
 | 
|---|
| 1156 |             NetError( 'listen',0);
 | 
|---|
| 1157 | 
 | 
|---|
| 1158 |     { -- send IP address + port + workstation name and wait for OK : eg 1-30-97}
 | 
|---|
| 1159 | 
 | 
|---|
| 1160 |     RPCVersion := VarPack(BrokerVer);              //   eg 11-1-96
 | 
|---|
| 1161 |     x := string('TCPconnect^');
 | 
|---|
| 1162 |     x := ConCat(x, LocalName, upArrow);            //   local ip address
 | 
|---|
| 1163 |     t := IntToStr(LocalPort);                         // callback port
 | 
|---|
| 1164 |     x := ConCat(x, t, upArrow, workstation, upArrow); // workstation name
 | 
|---|
| 1165 |     r := length(x) + length(RPCVersion) + 5;
 | 
|---|
| 1166 |     t := string('00000') + IntToStr(r);               // eg 11-1-96
 | 
|---|
| 1167 |     y := Copy(t, length(t)-4,length(t));
 | 
|---|
| 1168 |     y := ConCat(y, RPCVersion, StrPack(x,5));         // rpc version
 | 
|---|
| 1169 |     y := Prefix + y;
 | 
|---|
| 1170 |     { new protocol 030107 }
 | 
|---|
| 1171 | 
 | 
|---|
| 1172 | //    y := '[XWB]10' +IntToStr(CountWidth)+ '0' + '4'+#$A+'TCPConnect50'+ LPack(LocalName,CountWidth)+'f0'+LPack(IntToStr(LocalPort),CountWidth)+'f0'+LPack(workstation,CountWidth)+'f'+#4;
 | 
|---|
| 1173 | //    y := '[XWB]10' +IntToStr(CountWidth)+ '0' + '4'+#$A+'TCPConnect50'+ LPack(LocalName,CountWidth)+'f0'+LPack(IntToStr(0),CountWidth)+'f0'+LPack(workstation,CountWidth)+'f'+#4;
 | 
|---|
| 1174 | 
 | 
|---|
| 1175 |   // need to remove selecting port etc from client, since it will now be handled on the server P36
 | 
|---|
| 1176 | 
 | 
|---|
| 1177 |     if ForeGroundM = True then
 | 
|---|
| 1178 |     begin
 | 
|---|
| 1179 |          if ChangeCursor then
 | 
|---|
| 1180 |            Screen.Cursor := crDefault;
 | 
|---|
| 1181 |          t := 'Start M job D EN^XWBTCP' + #13 + #10 + 'Addr = ' +
 | 
|---|
| 1182 |            LocalName + #13 + #10 + 'Port = ' + IntToStr(LocalPort);
 | 
|---|
| 1183 | 
 | 
|---|
| 1184 |          frmDebugInfo := TfrmDebugInfo.Create(Application.MainForm);
 | 
|---|
| 1185 |          try
 | 
|---|
| 1186 |            frmDebugInfo.lblDebugInfo.Caption := t;
 | 
|---|
| 1187 |            ShowApplicationAndFocusOK(Application);
 | 
|---|
| 1188 |            frmDebugInfo.ShowModal;
 | 
|---|
| 1189 |          finally
 | 
|---|
| 1190 |            frmDebugInfo.Free
 | 
|---|
| 1191 |          end;
 | 
|---|
| 1192 | 
 | 
|---|
| 1193 | //         ShowMessage(t);  //TODO
 | 
|---|
| 1194 |     end;
 | 
|---|
| 1195 |   // remove debug mode from client
 | 
|---|
| 1196 | 
 | 
|---|
| 1197 |     tmpPChar := NetCall(hSocket, PChar(y));                {eg 11-1-96}
 | 
|---|
| 1198 |     tmp := tmpPchar;
 | 
|---|
| 1199 |     StrDispose(tmpPchar);
 | 
|---|
| 1200 |     if CompareStr(tmp, rlost) = 0 then
 | 
|---|
| 1201 |        begin
 | 
|---|
| 1202 |             lin.l_onoff := 1;
 | 
|---|
| 1203 |             lin.l_linger := 0;
 | 
|---|
| 1204 | 
 | 
|---|
| 1205 |             SocketError := setsockopt(hSocket, SOL_SOCKET, SO_LINGER,
 | 
|---|
| 1206 |                         s_lin, sizeof(lin));
 | 
|---|
| 1207 |             If SocketError = SOCKET_ERROR Then
 | 
|---|
| 1208 |                NetError( 'setsockopt (connect)',0);
 | 
|---|
| 1209 | 
 | 
|---|
| 1210 |           closesocket(hSocket);
 | 
|---|
| 1211 |           WSACleanup;
 | 
|---|
| 1212 |           Result := 10002;
 | 
|---|
| 1213 |           exit;
 | 
|---|
| 1214 |        end;
 | 
|---|
| 1215 |     r := CompareStr(tmp, rAccept);
 | 
|---|
| 1216 |     If r <> 0 Then
 | 
|---|
| 1217 |        NetError ('NetCall',XWB_M_REJECT);
 | 
|---|
| 1218 |   // JLI 021217 remove disconnect and reconnect code -- use UCX connection directly.
 | 
|---|
| 1219 |     lin.l_onoff := 1;
 | 
|---|
| 1220 |     lin.l_linger := 0;
 | 
|---|
| 1221 | 
 | 
|---|
| 1222 |     SocketError := setsockopt(hSocket, SOL_SOCKET, SO_LINGER,
 | 
|---|
| 1223 |                 s_lin, sizeof(lin));
 | 
|---|
| 1224 |     If SocketError = SOCKET_ERROR Then
 | 
|---|
| 1225 |        NetError( 'setsockopt (connect)',0);
 | 
|---|
| 1226 |     SocketError := closesocket(hSocket);          // -- done with this socket
 | 
|---|
| 1227 |     If SocketError > 0 Then
 | 
|---|
| 1228 |             NetError( 'closesocket',0);
 | 
|---|
| 1229 | 
 | 
|---|
| 1230 |     // -- wait for connect from DHCP and accept it - (uses blocking call)
 | 
|---|
| 1231 |     AddrLen := SizeOf(DHCPHost);
 | 
|---|
| 1232 |     hSocket := accept(hSocketListen, @DHCPHost, @AddrLen); // -- returns new socket
 | 
|---|
| 1233 |     If hSocket = INVALID_SOCKET Then
 | 
|---|
| 1234 |        begin
 | 
|---|
| 1235 |             NetError( 'accept',0);
 | 
|---|
| 1236 |        end;
 | 
|---|
| 1237 | 
 | 
|---|
| 1238 |     lin.l_onoff := 1;
 | 
|---|
| 1239 |     lin.l_linger := 0;
 | 
|---|
| 1240 | 
 | 
|---|
| 1241 |     SocketError := setsockopt(hSocketListen, SOL_SOCKET, SO_LINGER,
 | 
|---|
| 1242 |                 s_lin, sizeof(lin));
 | 
|---|
| 1243 |     If SocketError = SOCKET_ERROR Then
 | 
|---|
| 1244 |        NetError( 'setsockopt (connect)',0);
 | 
|---|
| 1245 | 
 | 
|---|
| 1246 |     SocketError := closesocket(hSocketListen);   // -- done with listen skt
 | 
|---|
| 1247 | 
 | 
|---|
| 1248 |     If SocketError > 0 Then
 | 
|---|
| 1249 |        begin
 | 
|---|
| 1250 |             NetError ('closesocket (listening)',0);
 | 
|---|
| 1251 |        end;
 | 
|---|
| 1252 |              // JLI 12/17/02  end of section commented out
 | 
|---|
| 1253 | 
 | 
|---|
| 1254 |     if ChangeCursor then
 | 
|---|
| 1255 |       Screen.Cursor := crDefault;
 | 
|---|
| 1256 |     NetStart1 := 0;
 | 
|---|
| 1257 | { -- connection established, socket handle now in:  hSocket
 | 
|---|
| 1258 |         ifrmWinSock.txtStatus := 'socket obtained' *** }
 | 
|---|
| 1259 | end;
 | 
|---|
| 1260 | 
 | 
|---|
| 1261 | 
 | 
|---|
| 1262 | procedure TXWBWinsock.NetStop(hSocket: integer);
 | 
|---|
| 1263 | Var
 | 
|---|
| 1264 |   tmp: string;
 | 
|---|
| 1265 |   lin: TLinger;
 | 
|---|
| 1266 |   s_lin: array [0..3] of char absolute lin;
 | 
|---|
| 1267 |   ChangeCursor: Boolean;
 | 
|---|
| 1268 |   tmpPChar: PChar;
 | 
|---|
| 1269 |   Str: String;
 | 
|---|
| 1270 |   x: array [0..15] of Char;
 | 
|---|
| 1271 | begin
 | 
|---|
| 1272 |     if not IsConnected then exit;
 | 
|---|
| 1273 |     if Screen.Cursor = crDefault then
 | 
|---|
| 1274 |       ChangeCursor := True
 | 
|---|
| 1275 |     else
 | 
|---|
| 1276 |       ChangeCursor := False;
 | 
|---|
| 1277 |     if ChangeCursor then
 | 
|---|
| 1278 |       Screen.Cursor := crHourGlass;
 | 
|---|
| 1279 |     if hSocket <= 0 then
 | 
|---|
| 1280 |     begin
 | 
|---|
| 1281 |          if ChangeCursor then
 | 
|---|
| 1282 |            screen.cursor := crDefault;
 | 
|---|
| 1283 |          exit;
 | 
|---|
| 1284 |     end;
 | 
|---|
| 1285 | 
 | 
|---|
| 1286 |     StrPcopy(x, StrPack(StrPack('#BYE#',5),5));
 | 
|---|
| 1287 | 
 | 
|---|
| 1288 |     { convert to new message protocol 030107 }
 | 
|---|
| 1289 |     if Prefix = '[XWB]' then
 | 
|---|
| 1290 |       Str := Prefix + '10'+IntToStr(CountWidth)+'0' +'4'+#5+'#BYE#'+#4
 | 
|---|
| 1291 |     else
 | 
|---|
| 1292 |       Str := Prefix + x;
 | 
|---|
| 1293 |     If hSocket <> INVALID_SOCKET Then
 | 
|---|
| 1294 |     begin
 | 
|---|
| 1295 |       tmpPChar := NetCall(hSocket,Str);
 | 
|---|
| 1296 | //        tmpPChar := NetCall(hSocket, x);
 | 
|---|
| 1297 |           tmp := tmpPChar;
 | 
|---|
| 1298 |       StrDispose(tmpPChar);
 | 
|---|
| 1299 |         lin.l_onoff := 1;                    { -- shut down the M handler};
 | 
|---|
| 1300 |         lin.l_linger := 0;
 | 
|---|
| 1301 | 
 | 
|---|
| 1302 |         SocketError := setsockopt(hSocket, SOL_SOCKET, SO_LINGER,
 | 
|---|
| 1303 |                     s_lin, sizeof(lin));
 | 
|---|
| 1304 |         If SocketError = SOCKET_ERROR Then
 | 
|---|
| 1305 |            NetError( 'setsockopt (connect)',0);
 | 
|---|
| 1306 | 
 | 
|---|
| 1307 |         SocketError := closesocket(hSocket);  { -- close the socket}
 | 
|---|
| 1308 |     end;
 | 
|---|
| 1309 | 
 | 
|---|
| 1310 |     SocketError := WSAUnhookBlockingHook;     { -- restore the default mechanism}
 | 
|---|
| 1311 |     SocketError := WSACleanup;                { -- shutdown TCP API}
 | 
|---|
| 1312 |     If SocketError > 0 Then
 | 
|---|
| 1313 |        NetError( 'WSACleanup',0);             { -- check blocking calls, etc.}
 | 
|---|
| 1314 |     if ChangeCursor then
 | 
|---|
| 1315 |       Screen.Cursor := crDefault;
 | 
|---|
| 1316 |     IsConnected := False;
 | 
|---|
| 1317 | end;
 | 
|---|
| 1318 | 
 | 
|---|
| 1319 | 
 | 
|---|
| 1320 | procedure TXWBWinsock.CloseSockSystem(hSocket: integer; s: string);
 | 
|---|
| 1321 | var
 | 
|---|
| 1322 |    lin: TLinger;
 | 
|---|
| 1323 |    s_lin: array [0..3] of char absolute lin;
 | 
|---|
| 1324 | begin
 | 
|---|
| 1325 |      lin.l_onoff := 1;
 | 
|---|
| 1326 |      lin.l_linger := 0;
 | 
|---|
| 1327 | 
 | 
|---|
| 1328 |      SocketError := setsockopt(hSocket, SOL_SOCKET, SO_LINGER,
 | 
|---|
| 1329 |                  s_lin, sizeof(lin));
 | 
|---|
| 1330 |      If SocketError = SOCKET_ERROR Then
 | 
|---|
| 1331 |         NetError( 'setsockopt (connect)',0);
 | 
|---|
| 1332 | 
 | 
|---|
| 1333 |      closesocket(hSocket);
 | 
|---|
| 1334 |      WSACleanup;
 | 
|---|
| 1335 |      ShowMessage(s);  //TODO
 | 
|---|
| 1336 |      halt(1);
 | 
|---|
| 1337 | end;
 | 
|---|
| 1338 | 
 | 
|---|
| 1339 | function TXWBWinsock.GetServerPacket(hSocket: integer): string;
 | 
|---|
| 1340 | var
 | 
|---|
| 1341 |    s,sb: PChar;
 | 
|---|
| 1342 |    buflen: integer;
 | 
|---|
| 1343 | begin
 | 
|---|
| 1344 |      s := StrAlloc(1);
 | 
|---|
| 1345 |      s[0] := #0;
 | 
|---|
| 1346 |      buflen := recv(hSocket, s^, 1, 0); {get length of segment}
 | 
|---|
| 1347 |      if buflen = SOCKET_ERROR Then   // 040720 code added to check for the timing problem if initial attempt to read during connection fails
 | 
|---|
| 1348 |      begin
 | 
|---|
| 1349 |        sleep(100);
 | 
|---|
| 1350 |        buflen := recv(hSocket, s^, 1, 0);
 | 
|---|
| 1351 |      end;
 | 
|---|
| 1352 |      if buflen = SOCKET_ERROR then
 | 
|---|
| 1353 |        NetError( 'recv',0);
 | 
|---|
| 1354 |      buflen := ord(s[0]);
 | 
|---|
| 1355 |      sb := StrAlloc(buflen+1);
 | 
|---|
| 1356 |      sb[0] := #0;
 | 
|---|
| 1357 |      buflen := recv(hSocket, sb^, buflen, 0); {get security segment}
 | 
|---|
| 1358 |      if buflen = SOCKET_ERROR Then
 | 
|---|
| 1359 |         NetError( 'recv',0);
 | 
|---|
| 1360 |      sb[buflen] := #0;
 | 
|---|
| 1361 |      Result := StrPas(sb);
 | 
|---|
| 1362 |      StrDispose(sb);
 | 
|---|
| 1363 |      StrDispose(s);
 | 
|---|
| 1364 | end;
 | 
|---|
| 1365 | 
 | 
|---|
| 1366 | constructor TXWBWinsock.Create;
 | 
|---|
| 1367 | begin
 | 
|---|
| 1368 |   inherited;
 | 
|---|
| 1369 | //  NetBlockingHookVar := NetBlockingHook;
 | 
|---|
| 1370 |   CountWidth := 3;
 | 
|---|
| 1371 | end;
 | 
|---|
| 1372 | 
 | 
|---|
| 1373 | procedure TXWBWinsock.NetError(Action: string; ErrType: integer);
 | 
|---|
| 1374 | var
 | 
|---|
| 1375 |    x,s: string;
 | 
|---|
| 1376 |    r: integer;
 | 
|---|
| 1377 |    BrokerError: EBrokerError;
 | 
|---|
| 1378 |    TimeOut: Double;
 | 
|---|
| 1379 | begin
 | 
|---|
| 1380 |    Screen.Cursor := crDefault;
 | 
|---|
| 1381 |    r := 0;
 | 
|---|
| 1382 |    if ErrType > 0 then r := ErrType;
 | 
|---|
| 1383 |    if ErrType = 0 then
 | 
|---|
| 1384 |   begin
 | 
|---|
| 1385 |         // P36
 | 
|---|
| 1386 |         // code added to indicate WSAETIMEDOUT error instead of WSAEINTR
 | 
|---|
| 1387 |         // when time out period exceeded.  WSAEINTR error is misleading
 | 
|---|
| 1388 |         // since the server is still active, but took too long
 | 
|---|
| 1389 |         if NetcallPending then
 | 
|---|
| 1390 |         begin
 | 
|---|
| 1391 |           if HookTimeOut > 0 then
 | 
|---|
| 1392 |           begin
 | 
|---|
| 1393 |             TimeOut := HookTimeOut * OneSecond;
 | 
|---|
| 1394 |             if Now > (NetTimerStart + TimeOut) then
 | 
|---|
| 1395 |               r := WSAETIMEDOUT;
 | 
|---|
| 1396 |           end;
 | 
|---|
| 1397 |         end;
 | 
|---|
| 1398 |         if r = 0 then
 | 
|---|
| 1399 |           r := WSAGetLastError;
 | 
|---|
| 1400 |         if (r = WSAEINTR) or (r = WSAETIMEDOUT) then xFlush := True;
 | 
|---|
| 1401 |         if WSAIsBlocking = True then WSACancelBlockingCall;  // JLI 021210
 | 
|---|
| 1402 |   end;
 | 
|---|
| 1403 |   Case r of
 | 
|---|
| 1404 |         WSAEINTR           : x := 'WSAEINTR';
 | 
|---|
| 1405 |         WSAEBADF           : x := 'WSAEINTR';
 | 
|---|
| 1406 |         WSAEFAULT          : x := 'WSAEFAULT';
 | 
|---|
| 1407 |         WSAEINVAL          : x := 'WSAEINVAL';
 | 
|---|
| 1408 |         WSAEMFILE          : x := 'WSAEMFILE';
 | 
|---|
| 1409 |         WSAEWOULDBLOCK     : x := 'WSAEWOULDBLOCK';
 | 
|---|
| 1410 |         WSAEINPROGRESS     : x := 'WSAEINPROGRESS';
 | 
|---|
| 1411 |         WSAEALREADY        : x := 'WSAEALREADY';
 | 
|---|
| 1412 |         WSAENOTSOCK        : x := 'WSAENOTSOCK';
 | 
|---|
| 1413 |         WSAEDESTADDRREQ    : x := 'WSAEDESTADDRREQ';
 | 
|---|
| 1414 |         WSAEMSGSIZE        : x := 'WSAEMSGSIZE';
 | 
|---|
| 1415 |         WSAEPROTOTYPE      : x := 'WSAEPROTOTYPE';
 | 
|---|
| 1416 |         WSAENOPROTOOPT     : x := 'WSAENOPROTOOPT';
 | 
|---|
| 1417 |         WSAEPROTONOSUPPORT : x := 'WSAEPROTONOSUPPORT';
 | 
|---|
| 1418 |         WSAESOCKTNOSUPPORT : x := 'WSAESOCKTNOSUPPORT';
 | 
|---|
| 1419 |         WSAEOPNOTSUPP      : x := 'WSAEOPNOTSUPP';
 | 
|---|
| 1420 |         WSAEPFNOSUPPORT    : x := 'WSAEPFNOSUPPORT';
 | 
|---|
| 1421 |         WSAEAFNOSUPPORT    : x := 'WSAEAFNOSUPPORT';
 | 
|---|
| 1422 |         WSAEADDRINUSE      : x := 'WSAEADDRINUSE';
 | 
|---|
| 1423 |         WSAEADDRNOTAVAIL   : x := 'WSAEADDRNOTAVAIL';
 | 
|---|
| 1424 |         WSAENETDOWN        : x := 'WSAENETDOWN';
 | 
|---|
| 1425 |         WSAENETUNREACH     : x := 'WSAENETUNREACH';
 | 
|---|
| 1426 |         WSAENETRESET       : x := 'WSAENETRESET';
 | 
|---|
| 1427 |         WSAECONNABORTED    : x := 'WSAECONNABORTED';
 | 
|---|
| 1428 |         WSAECONNRESET      : x := 'WSAECONNRESET';
 | 
|---|
| 1429 |         WSAENOBUFS         : x := 'WSAENOBUFS';
 | 
|---|
| 1430 |         WSAEISCONN         : x := 'WSAEISCONN';
 | 
|---|
| 1431 |         WSAENOTCONN        : x := 'WSAENOTCONN';
 | 
|---|
| 1432 |         WSAESHUTDOWN       : x := 'WSAESHUTDOWN';
 | 
|---|
| 1433 |         WSAETOOMANYREFS    : x := 'WSAETOOMANYREFS';
 | 
|---|
| 1434 |         WSAETIMEDOUT       : x := 'WSAETIMEDOUT';
 | 
|---|
| 1435 |         WSAECONNREFUSED    : x := 'WSAECONNREFUSED';
 | 
|---|
| 1436 |         WSAELOOP           : x := 'WSAELOOP';
 | 
|---|
| 1437 |         WSAENAMETOOLONG    : x := 'WSAENAMETOOLONG';
 | 
|---|
| 1438 |         WSAEHOSTDOWN       : x := 'WSAEHOSTDOWN';
 | 
|---|
| 1439 |         WSAEHOSTUNREACH    : x := 'WSAEHOSTUNREACH';
 | 
|---|
| 1440 |         WSAENOTEMPTY       : x := 'WSAENOTEMPTY';
 | 
|---|
| 1441 |         WSAEPROCLIM        : x := 'WSAEPROCLIM';
 | 
|---|
| 1442 |         WSAEUSERS          : x := 'WSAEUSERS';
 | 
|---|
| 1443 |         WSAEDQUOT          : x := 'WSAEDQUOT';
 | 
|---|
| 1444 |         WSAESTALE          : x := 'WSAESTALE';
 | 
|---|
| 1445 |         WSAEREMOTE         : x := 'WSAEREMOTE';
 | 
|---|
| 1446 |         WSASYSNOTREADY     : x := 'WSASYSNOTREADY';
 | 
|---|
| 1447 |         WSAVERNOTSUPPORTED : x := 'WSAVERNOTSUPPORTED';
 | 
|---|
| 1448 |         WSANOTINITIALISED  : x := 'WSANOTINITIALISED';
 | 
|---|
| 1449 |         WSAHOST_NOT_FOUND  : x := 'WSAHOST_NOT_FOUND';
 | 
|---|
| 1450 |         WSATRY_AGAIN       : x := 'WSATRY_AGAIN';
 | 
|---|
| 1451 |         WSANO_RECOVERY     : x := 'WSANO_RECOVERY';
 | 
|---|
| 1452 |         WSANO_DATA         : x := 'WSANO_DATA';
 | 
|---|
| 1453 | 
 | 
|---|
| 1454 |         XWB_NO_HEAP        : x := 'Insufficient Heap';
 | 
|---|
| 1455 |         XWB_M_REJECT       : x := 'M Error - Use ^XTER';
 | 
|---|
| 1456 |         XWB_BadReads       : x := 'Server unable to read input data correctly.';
 | 
|---|
| 1457 |         XWB_BadSignOn      : x := 'Sign-on was not completed.';
 | 
|---|
| 1458 |         XWB_ExeNoMem       : x := 'System was out of memory, executable file was corrupt, or relocations were invalid.';
 | 
|---|
| 1459 |         XWB_ExeNoFile      : x := 'File was not found.';
 | 
|---|
| 1460 |         XWB_ExeNoPath      : x := 'Path was not found.';
 | 
|---|
| 1461 |         XWB_ExeShare       : x := 'Attempt was made to dynamically link to a task,' +
 | 
|---|
| 1462 |                                   ' or there was a sharing or network-protection error.';
 | 
|---|
| 1463 |         XWB_ExeSepSeg      : x := 'Library required separate data segments for each task.';
 | 
|---|
| 1464 |         XWB_ExeLoMem       : x := 'There was insufficient memory to start the application.';
 | 
|---|
| 1465 |         XWB_ExeWinVer      : x := 'Windows version was incorrect.';
 | 
|---|
| 1466 |         XWB_ExeBadExe      : x := 'Executable file was invalid.' +
 | 
|---|
| 1467 |                                   ' Either it was not a Windows application or there was an error in the .EXE image.';
 | 
|---|
| 1468 |         XWB_ExeDifOS       : x := 'Application was designed for a different operating system.';
 | 
|---|
| 1469 |         XWB_RpcNotReg      : X := 'Remote procedure not registered to application.';
 | 
|---|
| 1470 |         XWB_BldConnectList : x := 'BrokerConnections list could not be created';
 | 
|---|
| 1471 |         XWB_NullRpcVer     : x := 'RpcVersion cannot be empty.' + #13 + 'Default is 0 (zero).';
 | 
|---|
| 1472 |         else x := IntToStr(r);
 | 
|---|
| 1473 |   end;
 | 
|---|
| 1474 |   s := 'Error encountered.' + chr(13)+chr(10) + 'Function was: ' + Action + chr(13)+chr(10) + 'Error was: ' + x;
 | 
|---|
| 1475 |   BrokerError := EBrokerError.Create(s);
 | 
|---|
| 1476 |   BrokerError.Action := Action;
 | 
|---|
| 1477 |   BrokerError.Code := r;
 | 
|---|
| 1478 |   BrokerError.Mnemonic := x;
 | 
|---|
| 1479 |   raise BrokerError;
 | 
|---|
| 1480 | end;
 | 
|---|
| 1481 | 
 | 
|---|
| 1482 | function TXWBWinsock.BuildPar1(hSocket: integer; api, RPCVer: string; const
 | 
|---|
| 1483 |     Parameters: TParams): String;
 | 
|---|
| 1484 | var
 | 
|---|
| 1485 |   i,ParamCount: integer;
 | 
|---|
| 1486 |   num: integer;
 | 
|---|
| 1487 |   tsize: longint;
 | 
|---|
| 1488 |   arr: LongInt;
 | 
|---|
| 1489 |   param,x,hdr,strout: string;
 | 
|---|
| 1490 |   tout,psize,tResult,RPCVersion: string;
 | 
|---|
| 1491 |   sin: TStringList;
 | 
|---|
| 1492 |   subscript: string;
 | 
|---|
| 1493 | begin
 | 
|---|
| 1494 |   sin := TStringList.Create;
 | 
|---|
| 1495 |   sin.clear;
 | 
|---|
| 1496 |   x := '';
 | 
|---|
| 1497 |   param := '';
 | 
|---|
| 1498 |   arr := 0;
 | 
|---|
| 1499 |   if Parameters = nil then ParamCount := 0
 | 
|---|
| 1500 |   else ParamCount := Parameters.Count;
 | 
|---|
| 1501 |   for i := 0 to ParamCount - 1 do
 | 
|---|
| 1502 |     if Parameters[i].PType <> undefined then begin
 | 
|---|
| 1503 |       with Parameters[i] do begin
 | 
|---|
| 1504 | 
 | 
|---|
| 1505 |         {if PType= null then
 | 
|---|
| 1506 |           param:='';}
 | 
|---|
| 1507 | 
 | 
|---|
| 1508 |         if PType = literal then
 | 
|---|
| 1509 |           param := param + strpack('0' + Value,3);
 | 
|---|
| 1510 | 
 | 
|---|
| 1511 |         if PType = reference then
 | 
|---|
| 1512 |           param := param + strpack('1' + Value,3);
 | 
|---|
| 1513 | 
 | 
|---|
| 1514 |         if (PType = list) {or (PType = wordproc)} then begin
 | 
|---|
| 1515 |           Value := '.x';
 | 
|---|
| 1516 |           param := param + strpack('2' + Value,3);
 | 
|---|
| 1517 |           if Pos('.',Value) >0 then
 | 
|---|
| 1518 |             x := Copy(Value,2,length(Value));
 | 
|---|
| 1519 |             {if PType = wordproc then dec(last);}
 | 
|---|
| 1520 |             subscript := Mult.First;
 | 
|---|
| 1521 |             while subscript <> '' do begin
 | 
|---|
| 1522 |               if Mult[subscript] = '' then Mult[subscript] := #1;
 | 
|---|
| 1523 |               sin.Add(StrPack(subscript,3) + StrPack(Mult[subscript],3));
 | 
|---|
| 1524 |               subscript := Mult.Order(subscript,1);
 | 
|---|
| 1525 |             end{while};
 | 
|---|
| 1526 |             sin.Add('000');
 | 
|---|
| 1527 |             arr := 1;
 | 
|---|
| 1528 |         end{if};
 | 
|---|
| 1529 |       end{with};
 | 
|---|
| 1530 |     end{if};
 | 
|---|
| 1531 | 
 | 
|---|
| 1532 |   param := Copy(param,1,Length(param));
 | 
|---|
| 1533 |   tsize := 0;
 | 
|---|
| 1534 | 
 | 
|---|
| 1535 |   tResult := '';
 | 
|---|
| 1536 |   tout := '';
 | 
|---|
| 1537 | 
 | 
|---|
| 1538 |   hdr := BuildHdr('XWB','','','');
 | 
|---|
| 1539 |   strout := strpack(hdr + BuildApi(api,param,arr),5);
 | 
|---|
| 1540 | //  num :=0;   //  JLI 040608 to correct handling of empty arrays
 | 
|---|
| 1541 | 
 | 
|---|
| 1542 |   RPCVersion := '';
 | 
|---|
| 1543 |   RPCVersion := VarPack(RPCVer);
 | 
|---|
| 1544 | 
 | 
|---|
| 1545 |   {if sin.Count-1 > 0 then} num := sin.Count-1;   //  JLI 040608 to correct handling of empty arrays
 | 
|---|
| 1546 | //  if sin.Count-1 > 0 then num := sin.Count-1;
 | 
|---|
| 1547 |     
 | 
|---|
| 1548 | 
 | 
|---|
| 1549 |   if {num} sin.Count > 0 then     //  JLI 040608 to correct handling of empty arrays
 | 
|---|
| 1550 | //  if num > 0 then
 | 
|---|
| 1551 |   begin
 | 
|---|
| 1552 |         for i := 0 to num do
 | 
|---|
| 1553 |           tsize := tsize + length(sin.strings[i]);
 | 
|---|
| 1554 |         x := '00000' + IntToStr(tsize + length(strout)+ length(RPCVersion));
 | 
|---|
| 1555 |   end;
 | 
|---|
| 1556 |   if {num} sin.Count = 0 then   //  JLI 040608 to correct handling of empty arrays
 | 
|---|
| 1557 | //   if num = 0 then
 | 
|---|
| 1558 |    begin
 | 
|---|
| 1559 |         x := '00000' + IntToStr(length(strout)+ length(RPCVersion));
 | 
|---|
| 1560 |    end;
 | 
|---|
| 1561 | 
 | 
|---|
| 1562 |   psize := x;
 | 
|---|
| 1563 |   psize := Copy(psize,length(psize)-5,5);
 | 
|---|
| 1564 |   tResult := psize;
 | 
|---|
| 1565 |   tResult := ConCat(tResult, RPCVersion);
 | 
|---|
| 1566 |   tout := strout;
 | 
|---|
| 1567 |   tResult := ConCat(tResult, tout);
 | 
|---|
| 1568 | 
 | 
|---|
| 1569 |   if {num} sin.Count > 0 then   //  JLI 040608 to correct handling of empty arrays
 | 
|---|
| 1570 | //   if num > 0 then
 | 
|---|
| 1571 |    begin
 | 
|---|
| 1572 |         for i := 0 to num do
 | 
|---|
| 1573 |             tResult := ConCat(tResult, sin.strings[i]);
 | 
|---|
| 1574 |    end;
 | 
|---|
| 1575 | 
 | 
|---|
| 1576 |   sin.free;
 | 
|---|
| 1577 | 
 | 
|---|
| 1578 |   Result := Prefix + tResult;  {return result}
 | 
|---|
| 1579 | 
 | 
|---|
| 1580 | end;
 | 
|---|
| 1581 | 
 | 
|---|
| 1582 | end.
 | 
|---|
| 1583 | 
 | 
|---|
| 1584 | 
 | 
|---|
| 1585 | 
 | 
|---|