| 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: Contains TRPCBroker and related components. | 
|---|
| 7 | Current Release: Version 1.1 Patch 40 (January 7, 2005)) | 
|---|
| 8 | *************************************************************** } | 
|---|
| 9 |  | 
|---|
| 10 | {************************************************** | 
|---|
| 11 | This is the hierarchy of things: | 
|---|
| 12 | TRPCBroker contains | 
|---|
| 13 | TParams, which contains | 
|---|
| 14 | array of TParamRecord each of which contains | 
|---|
| 15 | TMult | 
|---|
| 16 |  | 
|---|
| 17 | v1.1*4 Silent Login changes (DCM) 10/22/98 | 
|---|
| 18 |  | 
|---|
| 19 | 1.1*6 Polling to support terminating arphaned server jobs. (P6) | 
|---|
| 20 | == DPC 4/99 | 
|---|
| 21 |  | 
|---|
| 22 | 1.1*8 Check for Multi-Division users. (P8) - REM 7/13/99 | 
|---|
| 23 |  | 
|---|
| 24 | 1.1*13 More silent login code; deleted obsolete lines (DCM) 9/10/99  // p13 | 
|---|
| 25 | LAST UPDATED: 5/24/2001   // p13  JLI | 
|---|
| 26 |  | 
|---|
| 27 | 1.1*31 Added new read only property BrokerVersion to TRPCBroker which | 
|---|
| 28 | should contain the version number for the RPCBroker | 
|---|
| 29 | (or SharedRPCBroker) in use. | 
|---|
| 30 | **************************************************} | 
|---|
| 31 | unit Trpcb; | 
|---|
| 32 |  | 
|---|
| 33 | interface | 
|---|
| 34 |  | 
|---|
| 35 | {$I IISBase.inc} | 
|---|
| 36 |  | 
|---|
| 37 | uses | 
|---|
| 38 | {Delphi standard} | 
|---|
| 39 | Classes, Controls, Dialogs, {DsgnIntf,} Forms, Graphics, Messages, SysUtils, | 
|---|
| 40 | WinProcs, WinTypes, Windows, | 
|---|
| 41 | extctrls, {P6} | 
|---|
| 42 | {VA} | 
|---|
| 43 | XWBut1, {RpcbEdtr,} MFunStr, Hash;  //P14 -- pack split | 
|---|
| 44 |  | 
|---|
| 45 | const | 
|---|
| 46 | NoMore: boolean = False; | 
|---|
| 47 | MIN_RPCTIMELIMIT: integer = 30; | 
|---|
| 48 | CURRENT_RPC_VERSION: String = 'XWB*1.1*40'; | 
|---|
| 49 |  | 
|---|
| 50 | type | 
|---|
| 51 |  | 
|---|
| 52 | TParamType = (literal, reference, list, global, empty, stream, undefined);  // 030107 JLI Modified for new message protocol | 
|---|
| 53 |  | 
|---|
| 54 | //P14 -- pack split -- Types moved from RpcbEdtr.pas. | 
|---|
| 55 | TAccessVerifyCodes = string[255];  //to use TAccessVerifyCodesProperty editor use this type | 
|---|
| 56 | TRemoteProc = string[100];         //to use TRemoteProcProperty editor use this type | 
|---|
| 57 | TServer = string[255];             //to use TServerProperty editor use this type | 
|---|
| 58 | TRpcVersion = string[255];         //to use TRpcVersionProperty editor use this type | 
|---|
| 59 |  | 
|---|
| 60 | TRPCBroker = class; | 
|---|
| 61 | TVistaLogin = class; | 
|---|
| 62 | // p13 | 
|---|
| 63 | TLoginMode = (lmAVCodes, lmAppHandle, lmNTToken); | 
|---|
| 64 | TShowErrorMsgs = (semRaise, semQuiet);  // p13 | 
|---|
| 65 | TOnLoginFailure = procedure (VistaLogin: TVistaLogin) of object; //p13 | 
|---|
| 66 | TOnRPCBFailure = procedure (RPCBroker: TRPCBroker) of object; //p13 | 
|---|
| 67 | TOnPulseError = procedure(RPCBroker: TRPCBroker; ErrorText: String) of object; | 
|---|
| 68 | // TOnRPCCall = procedure (RPCBroker: TRPCBroker; SetNum: Integer; RemoteProcedure: TRemoteProc; CurrentContext: String; RpcVersion: TRpcVersion; Param: TParams; RPCTimeLimit: Integer; Results, Sec, App: PChar; DateTime: TDateTime) of object; | 
|---|
| 69 |  | 
|---|
| 70 | {------ EBrokerError ------} | 
|---|
| 71 | EBrokerError = class(Exception) | 
|---|
| 72 | public | 
|---|
| 73 | Action: string; | 
|---|
| 74 | Code: integer; | 
|---|
| 75 | Mnemonic: string; | 
|---|
| 76 | end; | 
|---|
| 77 |  | 
|---|
| 78 | {------ TString ------} | 
|---|
| 79 |  | 
|---|
| 80 | TString = class(TObject) | 
|---|
| 81 | Str: string; | 
|---|
| 82 | end; | 
|---|
| 83 |  | 
|---|
| 84 | {------ TMult ------} | 
|---|
| 85 | {:This component defines the multiple field of a parameter.  The multiple | 
|---|
| 86 | field is used to pass string-subscripted array of data in a parameter.} | 
|---|
| 87 |  | 
|---|
| 88 | TMult = class(TComponent) | 
|---|
| 89 | private | 
|---|
| 90 | FMultiple: TStringList; | 
|---|
| 91 | procedure ClearAll; | 
|---|
| 92 | function  GetCount: Word; | 
|---|
| 93 | function  GetFirst: string; | 
|---|
| 94 | function  GetLast: string; | 
|---|
| 95 | function  GetFMultiple(Index: string): string; | 
|---|
| 96 | function  GetSorted: boolean; | 
|---|
| 97 | procedure SetFMultiple(Index: string; value: string); | 
|---|
| 98 | procedure SetSorted(Value: boolean); | 
|---|
| 99 | protected | 
|---|
| 100 | public | 
|---|
| 101 | constructor Create(AOwner: TComponent); override;      {1.1T8} | 
|---|
| 102 | destructor Destroy; override; | 
|---|
| 103 | procedure Assign(Source: TPersistent); override; | 
|---|
| 104 | function Order(const StartSubscript: string; Direction: integer): string; | 
|---|
| 105 | function Position(const Subscript: string): longint; | 
|---|
| 106 | function Subscript(const Position: longint): string; | 
|---|
| 107 | property Count: Word read GetCount; | 
|---|
| 108 | property First: string read GetFirst; | 
|---|
| 109 | property Last: string read GetLast; | 
|---|
| 110 | property MultArray[I: string]: string | 
|---|
| 111 | read GetFMultiple write SetFMultiple; default; | 
|---|
| 112 | property Sorted: boolean read GetSorted write SetSorted; | 
|---|
| 113 | end; | 
|---|
| 114 |  | 
|---|
| 115 | {------ TParamRecord ------} | 
|---|
| 116 | {:This component defines all the fields that comprise a parameter.} | 
|---|
| 117 |  | 
|---|
| 118 | TParamRecord = class(TComponent) | 
|---|
| 119 | private | 
|---|
| 120 | FMult: TMult; | 
|---|
| 121 | FValue: string; | 
|---|
| 122 | FPType: TParamType; | 
|---|
| 123 | protected | 
|---|
| 124 | public | 
|---|
| 125 | constructor Create(AOwner: TComponent); override; | 
|---|
| 126 | destructor Destroy; override; | 
|---|
| 127 | property Value: string read FValue write FValue; | 
|---|
| 128 | property PType: TParamType read FPType write FPType; | 
|---|
| 129 | property Mult: TMult read FMult write FMult; | 
|---|
| 130 | end; | 
|---|
| 131 |  | 
|---|
| 132 | {------ TParams ------} | 
|---|
| 133 | {:This component is really a collection of parameters.  Simple inclusion | 
|---|
| 134 | of this component in the Broker component provides access to all of the | 
|---|
| 135 | parameters that may be needed when calling a remote procedure.} | 
|---|
| 136 |  | 
|---|
| 137 | TParams = class(TComponent) | 
|---|
| 138 | private | 
|---|
| 139 | FParameters: TList; | 
|---|
| 140 | function GetCount: Word; | 
|---|
| 141 | function GetParameter(Index: integer): TParamRecord; | 
|---|
| 142 | procedure SetParameter(Index: integer; Parameter: TParamRecord); | 
|---|
| 143 | public | 
|---|
| 144 | constructor Create(AOwner: TComponent); override; | 
|---|
| 145 | destructor Destroy; override; | 
|---|
| 146 | procedure Assign(Source: TPersistent); override; | 
|---|
| 147 | procedure Clear; | 
|---|
| 148 | property Count: Word read GetCount; | 
|---|
| 149 | property ParamArray[I: integer]: TParamRecord | 
|---|
| 150 | read GetParameter write SetParameter; default; | 
|---|
| 151 | end; | 
|---|
| 152 |  | 
|---|
| 153 |  | 
|---|
| 154 | {------ TVistaLogin ------}     //p13 | 
|---|
| 155 | TVistaLogin = class(TPersistent) | 
|---|
| 156 | private | 
|---|
| 157 | FLogInHandle : string; | 
|---|
| 158 | FNTToken : string; | 
|---|
| 159 | FAccessCode : string; | 
|---|
| 160 | FVerifyCode : string; | 
|---|
| 161 | FDivision   : string; | 
|---|
| 162 | FMode: TLoginMode; | 
|---|
| 163 | FDivLst: TStrings; | 
|---|
| 164 | FOnFailedLogin: TOnLoginFailure; | 
|---|
| 165 | FMultiDivision : boolean; | 
|---|
| 166 | FDUZ: string; | 
|---|
| 167 | FErrorText : string; | 
|---|
| 168 | FPromptDiv : boolean; | 
|---|
| 169 | FIsProductionAccount: Boolean; | 
|---|
| 170 | FDomainName: string; | 
|---|
| 171 | procedure SetAccessCode(const Value: String); | 
|---|
| 172 | procedure SetLogInHandle(const Value: String); | 
|---|
| 173 | procedure SetNTToken(const Value: String); | 
|---|
| 174 | procedure SetVerifyCode(const Value: String); | 
|---|
| 175 | procedure SetDivision(const Value: String); | 
|---|
| 176 | //procedure SetWorkstationIPAddress(const Value: String); | 
|---|
| 177 | procedure SetMode(const Value: TLoginMode); | 
|---|
| 178 | procedure SetMultiDivision(Value: Boolean); | 
|---|
| 179 | procedure SetDuz(const Value: string); | 
|---|
| 180 | procedure SetErrorText(const Value: string); | 
|---|
| 181 | procedure SetPromptDiv(const Value: boolean); | 
|---|
| 182 | protected | 
|---|
| 183 | procedure FailedLogin(Sender: TObject); dynamic; | 
|---|
| 184 | public | 
|---|
| 185 | constructor Create(AOwner: TComponent); virtual; | 
|---|
| 186 | destructor Destroy; override; | 
|---|
| 187 | property LogInHandle: String read FLogInHandle write SetLogInHandle;  //for use by a 2ndary DHCP login OR ESSO login | 
|---|
| 188 | property NTToken: String read FNTToken write SetNTToken; | 
|---|
| 189 | property DivList: TStrings read FDivLst; | 
|---|
| 190 | property OnFailedLogin: TOnLoginFailure read FOnFailedLogin write FOnFailedLogin; | 
|---|
| 191 | property MultiDivision: Boolean read FMultiDivision write SetMultiDivision; | 
|---|
| 192 | property DUZ: string read FDUZ write SetDuz; | 
|---|
| 193 | property ErrorText: string read FErrorText write SetErrorText; | 
|---|
| 194 | property IsProductionAccount: Boolean read FIsProductionAccount write | 
|---|
| 195 | FIsProductionAccount; | 
|---|
| 196 | property DomainName: string read FDomainName write FDomainName; | 
|---|
| 197 | published | 
|---|
| 198 | property AccessCode: String read FAccessCode write SetAccessCode; | 
|---|
| 199 | property VerifyCode: String read FVerifyCode write SetVerifyCode; | 
|---|
| 200 | property Mode: TLoginMode read FMode write SetMode; | 
|---|
| 201 | property Division: String read FDivision write SetDivision; | 
|---|
| 202 | property PromptDivision: boolean read FPromptDiv write SetPromptDiv; | 
|---|
| 203 |  | 
|---|
| 204 | end; | 
|---|
| 205 |  | 
|---|
| 206 | {------ TVistaUser ------}   //holds 'generic' user attributes {p13} | 
|---|
| 207 | TVistaUser = class(TObject) | 
|---|
| 208 | private | 
|---|
| 209 | FDUZ: string; | 
|---|
| 210 | FName: string; | 
|---|
| 211 | FStandardName: string; | 
|---|
| 212 | FDivision: String; | 
|---|
| 213 | FVerifyCodeChngd: Boolean; | 
|---|
| 214 | FTitle: string; | 
|---|
| 215 | FServiceSection: string; | 
|---|
| 216 | FLanguage: string; | 
|---|
| 217 | FDtime: string; | 
|---|
| 218 | FVpid: String; | 
|---|
| 219 | procedure SetDivision(const Value: String); | 
|---|
| 220 | procedure SetDUZ(const Value: String); | 
|---|
| 221 | procedure SetName(const Value: String); | 
|---|
| 222 | procedure SetVerifyCodeChngd(const Value: Boolean); | 
|---|
| 223 | procedure SetStandardName(const Value: String); | 
|---|
| 224 | procedure SetTitle(const Value: string); | 
|---|
| 225 | procedure SetDTime(const Value: string); | 
|---|
| 226 | procedure SetLanguage(const Value: string); | 
|---|
| 227 | procedure SetServiceSection(const Value: string); | 
|---|
| 228 | public | 
|---|
| 229 | property DUZ: String read FDUZ write SetDUZ; | 
|---|
| 230 | property Name: String read FName write SetName; | 
|---|
| 231 | property StandardName: String read FStandardName write SetStandardName; | 
|---|
| 232 | property Division: String read FDivision write SetDivision; | 
|---|
| 233 | property VerifyCodeChngd: Boolean read FVerifyCodeChngd write SetVerifyCodeChngd; | 
|---|
| 234 | property Title: string read FTitle write SetTitle; | 
|---|
| 235 | property ServiceSection: string read FServiceSection write SetServiceSection; | 
|---|
| 236 | property Language: string read FLanguage write SetLanguage; | 
|---|
| 237 | property DTime: string read FDTime write SetDTime; | 
|---|
| 238 | property Vpid: string read FVpid write FVpid; | 
|---|
| 239 | end; | 
|---|
| 240 |  | 
|---|
| 241 | {------ TRPCBroker ------} | 
|---|
| 242 | {:This component, when placed on a form, allows design-time and run-time | 
|---|
| 243 | connection to the server by simply toggling the Connected property. | 
|---|
| 244 | Once connected you can access server data.} | 
|---|
| 245 |  | 
|---|
| 246 | TRPCBroker = class(TComponent) | 
|---|
| 247 | //private | 
|---|
| 248 | private | 
|---|
| 249 | FBrokerVersion: String; | 
|---|
| 250 | FIsBackwardCompatibleConnection: Boolean; | 
|---|
| 251 | FIsNewStyleConnection: Boolean; | 
|---|
| 252 | FOldConnectionOnly: Boolean; | 
|---|
| 253 | protected | 
|---|
| 254 | FAccessVerifyCodes: TAccessVerifyCodes; | 
|---|
| 255 | FClearParameters: Boolean; | 
|---|
| 256 | FClearResults: Boolean; | 
|---|
| 257 | FConnected: Boolean; | 
|---|
| 258 | FConnecting: Boolean; | 
|---|
| 259 | FCurrentContext: String; | 
|---|
| 260 | FDebugMode: Boolean; | 
|---|
| 261 | FListenerPort: integer; | 
|---|
| 262 | FParams: TParams; | 
|---|
| 263 | FResults: TStrings; | 
|---|
| 264 | FRemoteProcedure: TRemoteProc; | 
|---|
| 265 | FRpcVersion: TRpcVersion; | 
|---|
| 266 | FServer: TServer; | 
|---|
| 267 | FSocket: integer; | 
|---|
| 268 | FRPCTimeLimit : integer;    //for adjusting client RPC duration timeouts | 
|---|
| 269 | FPulse        : TTimer;     //P6 | 
|---|
| 270 | FKernelLogIn  : Boolean;    //p13 | 
|---|
| 271 | FLogIn: TVistaLogIn;    //p13 | 
|---|
| 272 | FUser: TVistaUser; //p13 | 
|---|
| 273 | FOnRPCBFailure: TOnRPCBFailure; | 
|---|
| 274 | FShowErrorMsgs: TShowErrorMsgs; | 
|---|
| 275 | FRPCBError:     String; | 
|---|
| 276 | FOnPulseError: TOnPulseError; | 
|---|
| 277 | protected | 
|---|
| 278 | procedure   SetClearParameters(Value: Boolean); virtual; | 
|---|
| 279 | procedure   SetClearResults(Value: Boolean); virtual; | 
|---|
| 280 | procedure   SetConnected(Value: Boolean); virtual; | 
|---|
| 281 | procedure   SetResults(Value: TStrings); virtual; | 
|---|
| 282 | procedure   SetServer(Value: TServer); virtual; | 
|---|
| 283 | procedure   SetRPCTimeLimit(Value: integer); virtual;  //Screen changes to timeout. | 
|---|
| 284 | procedure   DoPulseOnTimer(Sender: TObject); virtual;  //p6 | 
|---|
| 285 | procedure   SetKernelLogIn(const Value: Boolean); virtual; | 
|---|
| 286 | //  procedure   SetLogIn(const Value: TVistaLogIn); virtual; | 
|---|
| 287 | procedure   SetUser(const Value: TVistaUser); virtual; | 
|---|
| 288 | public | 
|---|
| 289 | XWBWinsock: TObject; | 
|---|
| 290 | property    AccessVerifyCodes: TAccessVerifyCodes read FAccessVerifyCodes write FAccessVerifyCodes; | 
|---|
| 291 | property    Param: TParams read FParams write FParams; | 
|---|
| 292 | property    Socket: integer read FSocket; | 
|---|
| 293 | property    RPCTimeLimit : integer read FRPCTimeLimit write SetRPCTimeLimit; | 
|---|
| 294 | destructor  Destroy; override; | 
|---|
| 295 | procedure   Call; virtual; | 
|---|
| 296 | procedure   Loaded; override; | 
|---|
| 297 | procedure   lstCall(OutputBuffer: TStrings); virtual; | 
|---|
| 298 | function    pchCall: PChar; virtual; | 
|---|
| 299 | function    strCall: string; virtual; | 
|---|
| 300 | function    CreateContext(strContext: string): boolean; virtual; | 
|---|
| 301 | property    CurrentContext: String read FCurrentContext; | 
|---|
| 302 | property    User: TVistaUser read FUser write SetUser; | 
|---|
| 303 | property    OnRPCBFailure: TOnRPCBFailure read FOnRPCBFailure write FOnRPCBFailure; | 
|---|
| 304 | property    RPCBError: String read FRPCBError write FRPCBError; | 
|---|
| 305 | property    OnPulseError: TOnPulseError read FOnPulseError write FOnPulseError; | 
|---|
| 306 | property    BrokerVersion: String read FBrokerVersion; | 
|---|
| 307 | property IsNewStyleConnection: Boolean read FIsNewStyleConnection; | 
|---|
| 308 | published | 
|---|
| 309 | constructor Create(AOwner: TComponent); override; | 
|---|
| 310 | property    ClearParameters: boolean read FClearParameters | 
|---|
| 311 | write SetClearParameters; | 
|---|
| 312 | property    ClearResults: boolean read FClearResults write SetClearResults; | 
|---|
| 313 | property    Connected: boolean read FConnected write SetConnected; | 
|---|
| 314 | property    DebugMode: boolean read FDebugMode write FDebugMode default False; | 
|---|
| 315 | property    ListenerPort: integer read FListenerPort write FListenerPort; | 
|---|
| 316 | property    Results: TStrings read FResults write SetResults; | 
|---|
| 317 | property    RemoteProcedure: TRemoteProc read FRemoteProcedure | 
|---|
| 318 | write FRemoteProcedure; | 
|---|
| 319 | property    RpcVersion: TRpcVersion read FRpcVersion write FRpcVersion; | 
|---|
| 320 | property    Server: TServer read FServer write SetServer; | 
|---|
| 321 | property    KernelLogIn: Boolean read FKernelLogIn write SetKernelLogIn; | 
|---|
| 322 | property    ShowErrorMsgs: TShowErrorMsgs read FShowErrorMsgs write FShowErrorMsgs default semRaise; | 
|---|
| 323 | property    LogIn: TVistaLogIn read FLogIn write FLogin; // SetLogIn; | 
|---|
| 324 | property    IsBackwardCompatibleConnection: Boolean read | 
|---|
| 325 | FIsBackwardCompatibleConnection write FIsBackwardCompatibleConnection | 
|---|
| 326 | default True; | 
|---|
| 327 | property    OldConnectionOnly: Boolean read FOldConnectionOnly write | 
|---|
| 328 | FOldConnectionOnly; | 
|---|
| 329 | end; | 
|---|
| 330 |  | 
|---|
| 331 | {procedure Register;}  //P14 --pack split | 
|---|
| 332 | procedure StoreConnection(Broker: TRPCBroker); | 
|---|
| 333 | function  RemoveConnection(Broker: TRPCBroker): boolean; | 
|---|
| 334 | function  DisconnectAll(Server: string; ListenerPort: integer): boolean; | 
|---|
| 335 | function  ExistingSocket(Broker: TRPCBroker): integer; | 
|---|
| 336 | procedure AuthenticateUser(ConnectingBroker: TRPCBroker); | 
|---|
| 337 | procedure GetBrokerInfo(ConnectedBroker : TRPCBroker);  //P6 | 
|---|
| 338 | function  NoSignOnNeeded : Boolean; | 
|---|
| 339 | function  ProcessExecute(Command: string; cShow: Word): Integer; | 
|---|
| 340 | function  GetAppHandle(ConnectedBroker : TRPCBroker): String; | 
|---|
| 341 | function ShowApplicationAndFocusOK(anApplication: TApplication): boolean; | 
|---|
| 342 |  | 
|---|
| 343 |  | 
|---|
| 344 | var | 
|---|
| 345 | DebugData: string; | 
|---|
| 346 | BrokerConnections: TStringList;   {this list stores all connections by socket number} | 
|---|
| 347 | BrokerAllConnections: TStringList; {this list stores all connections to all of | 
|---|
| 348 | the servers, by an application.  It's used in DisconnectAll} | 
|---|
| 349 |  | 
|---|
| 350 | implementation | 
|---|
| 351 |  | 
|---|
| 352 | uses | 
|---|
| 353 | Loginfrm, RpcbErr, SelDiv{p8}, RpcSLogin{p13}, fRPCBErrMsg, Wsockc; | 
|---|
| 354 |  | 
|---|
| 355 | const | 
|---|
| 356 | DEFAULT_PULSE    : integer = 81000; //P6 default = 45% of 3 minutes. | 
|---|
| 357 | MINIMUM_TIMEOUT  : integer = 14;    //P6 shortest allowable timeout in secs. | 
|---|
| 358 | PULSE_PERCENTAGE : integer = 45;    //P6 % of timeout for pulse frequency. | 
|---|
| 359 |  | 
|---|
| 360 | {-------------------------- TMult.Create -------------------------- | 
|---|
| 361 | ------------------------------------------------------------------} | 
|---|
| 362 | constructor TMult.Create(AOwner: TComponent); | 
|---|
| 363 | begin | 
|---|
| 364 | inherited Create(AOwner); | 
|---|
| 365 | FMultiple := TStringList.Create; | 
|---|
| 366 | end; | 
|---|
| 367 |  | 
|---|
| 368 | {------------------------- TMult.Destroy -------------------------- | 
|---|
| 369 | ------------------------------------------------------------------} | 
|---|
| 370 | destructor TMult.Destroy; | 
|---|
| 371 | begin | 
|---|
| 372 | ClearAll; | 
|---|
| 373 | FMultiple.Free; | 
|---|
| 374 | FMultiple := nil; | 
|---|
| 375 | inherited Destroy; | 
|---|
| 376 | end; | 
|---|
| 377 |  | 
|---|
| 378 | {-------------------------- TMult.Assign -------------------------- | 
|---|
| 379 | All of the items from source object are copied one by one into the | 
|---|
| 380 | target.  So if the source is later destroyed, target object will continue | 
|---|
| 381 | to hold the copy of all elements, completely unaffected. | 
|---|
| 382 | ------------------------------------------------------------------} | 
|---|
| 383 | procedure TMult.Assign(Source: TPersistent); | 
|---|
| 384 | var | 
|---|
| 385 | I: integer; | 
|---|
| 386 | SourceStrings: TStrings; | 
|---|
| 387 | S: TString; | 
|---|
| 388 | SourceMult: TMult; | 
|---|
| 389 | begin | 
|---|
| 390 | ClearAll; | 
|---|
| 391 | if Source is TMult then begin | 
|---|
| 392 | SourceMult := Source as TMult; | 
|---|
| 393 | try | 
|---|
| 394 | for I := 0 to SourceMult.FMultiple.Count - 1 do begin | 
|---|
| 395 | S := TString.Create; | 
|---|
| 396 | S.Str := (SourceMult.FMultiple.Objects[I] as TString).Str; | 
|---|
| 397 | Self.FMultiple.AddObject(SourceMult.FMultiple[I], S); | 
|---|
| 398 | end; | 
|---|
| 399 | except | 
|---|
| 400 | end; | 
|---|
| 401 | end | 
|---|
| 402 |  | 
|---|
| 403 | else begin | 
|---|
| 404 | SourceStrings := Source as TStrings; | 
|---|
| 405 | for I := 0 to SourceStrings.Count - 1 do | 
|---|
| 406 | Self[IntToStr(I)] := SourceStrings[I]; | 
|---|
| 407 | end; | 
|---|
| 408 | end; | 
|---|
| 409 |  | 
|---|
| 410 | {------------------------- TMult.ClearAll ------------------------- | 
|---|
| 411 | One by one, all Mult items are freed. | 
|---|
| 412 | ------------------------------------------------------------------} | 
|---|
| 413 | procedure TMult.ClearAll; | 
|---|
| 414 | var | 
|---|
| 415 | I: integer; | 
|---|
| 416 | begin | 
|---|
| 417 | for I := 0 to FMultiple.Count - 1 do begin | 
|---|
| 418 | FMultiple.Objects[I].Free; | 
|---|
| 419 | FMultiple.Objects[I] := nil; | 
|---|
| 420 | end; | 
|---|
| 421 | FMultiple.Clear; | 
|---|
| 422 | end; | 
|---|
| 423 |  | 
|---|
| 424 | {------------------------- TMult.GetCount ------------------------- | 
|---|
| 425 | Returns the number of elements in the multiple | 
|---|
| 426 | ------------------------------------------------------------------} | 
|---|
| 427 | function TMult.GetCount: Word; | 
|---|
| 428 | begin | 
|---|
| 429 | Result := FMultiple.Count; | 
|---|
| 430 | end; | 
|---|
| 431 |  | 
|---|
| 432 | {------------------------- TMult.GetFirst ------------------------- | 
|---|
| 433 | Returns the subscript of the first element in the multiple | 
|---|
| 434 | ------------------------------------------------------------------} | 
|---|
| 435 | function TMult.GetFirst: string; | 
|---|
| 436 | begin | 
|---|
| 437 | if FMultiple.Count > 0 then Result := FMultiple[0] | 
|---|
| 438 | else Result := ''; | 
|---|
| 439 | end; | 
|---|
| 440 |  | 
|---|
| 441 | {------------------------- TMult.GetLast -------------------------- | 
|---|
| 442 | Returns the subscript of the last element in the multiple | 
|---|
| 443 | ------------------------------------------------------------------} | 
|---|
| 444 | function TMult.GetLast: string; | 
|---|
| 445 | begin | 
|---|
| 446 | if FMultiple.Count > 0 then Result := FMultiple[FMultiple.Count - 1] | 
|---|
| 447 | else Result := ''; | 
|---|
| 448 | end; | 
|---|
| 449 |  | 
|---|
| 450 | {---------------------- TMult.GetFMultiple ------------------------ | 
|---|
| 451 | Returns the VALUE of the element whose subscript is passed. | 
|---|
| 452 | ------------------------------------------------------------------} | 
|---|
| 453 | function TMult.GetFMultiple(Index: string): string; | 
|---|
| 454 | var | 
|---|
| 455 | S: TString; | 
|---|
| 456 | BrokerComponent,ParamRecord: TComponent; | 
|---|
| 457 | I: integer; | 
|---|
| 458 | strError: string; | 
|---|
| 459 | begin | 
|---|
| 460 | try | 
|---|
| 461 | S := TString(FMultiple.Objects[FMultiple.IndexOf(Index)]); | 
|---|
| 462 | except | 
|---|
| 463 | on EListError do begin | 
|---|
| 464 | {build appropriate error message} | 
|---|
| 465 | strError := iff(Self.Name <> '', Self.Name, 'TMult_instance'); | 
|---|
| 466 | strError := strError + '[' + Index + ']' + #13#10 + 'is undefined'; | 
|---|
| 467 | try | 
|---|
| 468 | ParamRecord := Self.Owner; | 
|---|
| 469 | BrokerComponent := Self.Owner.Owner.Owner; | 
|---|
| 470 | if (ParamRecord is TParamRecord) and (BrokerComponent is TRPCBroker) then begin | 
|---|
| 471 | I := 0; | 
|---|
| 472 | {if there is an easier way to figure out which array element points | 
|---|
| 473 | to this instance of a multiple, use it}   // p13 | 
|---|
| 474 | while TRPCBroker(BrokerComponent).Param[I] <> ParamRecord do inc(I); | 
|---|
| 475 | strError := '.Param[' + IntToStr(I) + '].' + strError; | 
|---|
| 476 | strError := iff(BrokerComponent.Name <> '', BrokerComponent.Name, | 
|---|
| 477 | 'TRPCBroker_instance') + strError; | 
|---|
| 478 | end; | 
|---|
| 479 | except | 
|---|
| 480 | end; | 
|---|
| 481 | raise Exception.Create(strError); | 
|---|
| 482 | end; | 
|---|
| 483 | end; | 
|---|
| 484 | Result := S.Str; | 
|---|
| 485 | end; | 
|---|
| 486 |  | 
|---|
| 487 | {---------------------- TMult.SetGetSorted ------------------------ | 
|---|
| 488 | ------------------------------------------------------------------} | 
|---|
| 489 | function  TMult.GetSorted: boolean; | 
|---|
| 490 | begin | 
|---|
| 491 | Result := FMultiple.Sorted; | 
|---|
| 492 | end; | 
|---|
| 493 |  | 
|---|
| 494 | {---------------------- TMult.SetFMultiple ------------------------ | 
|---|
| 495 | Stores a new element in the multiple.  FMultiple (TStringList) is the | 
|---|
| 496 | structure, which is used to hold the subscript and value pair.  Subscript | 
|---|
| 497 | is stored as the String, value is stored as an object of the string. | 
|---|
| 498 | ------------------------------------------------------------------} | 
|---|
| 499 | procedure TMult.SetFMultiple(Index: string; Value: string); | 
|---|
| 500 | var | 
|---|
| 501 | S: TString; | 
|---|
| 502 | Pos: integer; | 
|---|
| 503 | begin | 
|---|
| 504 | Pos := FMultiple.IndexOf(Index);       {see if this subscript already exists} | 
|---|
| 505 | if Pos = -1 then begin                 {if subscript is new} | 
|---|
| 506 | S := TString.Create;                {create string object} | 
|---|
| 507 | S.Str := Value;                     {put value in it} | 
|---|
| 508 | FMultiple.AddObject(Index, S);      {add it} | 
|---|
| 509 | end | 
|---|
| 510 | else | 
|---|
| 511 | TString(FMultiple.Objects[Pos]).Str := Value; { otherwise replace the value} | 
|---|
| 512 | end; | 
|---|
| 513 |  | 
|---|
| 514 | {---------------------- TMult.SetSorted ------------------------ | 
|---|
| 515 | ------------------------------------------------------------------} | 
|---|
| 516 | procedure TMult.SetSorted(Value: boolean); | 
|---|
| 517 | begin | 
|---|
| 518 | FMultiple.Sorted := Value; | 
|---|
| 519 | end; | 
|---|
| 520 |  | 
|---|
| 521 | {-------------------------- TMult.Order -------------------------- | 
|---|
| 522 | Returns the subscript string of the next or previous element from the | 
|---|
| 523 | StartSubscript.  This is very similar to the $O function available in M. | 
|---|
| 524 | Null string ('') is returned when reaching beyong the first or last | 
|---|
| 525 | element, or when list is empty. | 
|---|
| 526 | Note: A major difference between the M $O and this function is that | 
|---|
| 527 | in this function StartSubscript must identify a valid subscript | 
|---|
| 528 | in the list. | 
|---|
| 529 | ------------------------------------------------------------------} | 
|---|
| 530 | function TMult.Order(const StartSubscript: string; Direction: integer): string; | 
|---|
| 531 | var | 
|---|
| 532 | Index: longint; | 
|---|
| 533 | begin | 
|---|
| 534 | Result := ''; | 
|---|
| 535 | if StartSubscript = '' then | 
|---|
| 536 | if Direction > 0 then Result := First | 
|---|
| 537 | else Result := Last | 
|---|
| 538 | else begin | 
|---|
| 539 | Index := Position(StartSubscript); | 
|---|
| 540 | if Index > -1 then | 
|---|
| 541 | if (Index < (Count - 1)) and (Direction > 0) then | 
|---|
| 542 | Result := FMultiple[Index + 1] | 
|---|
| 543 | else if (Index > 0) and (Direction < 0) then | 
|---|
| 544 | Result := FMultiple[Index - 1]; | 
|---|
| 545 | end | 
|---|
| 546 | end; | 
|---|
| 547 |  | 
|---|
| 548 | {------------------------- TMult.Position ------------------------- | 
|---|
| 549 | Returns the long integer value which is the index position of the | 
|---|
| 550 | element in the list.  Opposite of TMult.Subscript().  Remember that | 
|---|
| 551 | the list is 0 based! | 
|---|
| 552 | ------------------------------------------------------------------} | 
|---|
| 553 | function TMult.Position(const Subscript: string): longint; | 
|---|
| 554 | begin | 
|---|
| 555 | Result := FMultiple.IndexOf(Subscript); | 
|---|
| 556 | end; | 
|---|
| 557 |  | 
|---|
| 558 | {------------------------ TMult.Subscript ------------------------- | 
|---|
| 559 | Returns the string subscript of the element whose position in the list | 
|---|
| 560 | is passed in.  Opposite of TMult.Position().  Remember that the list is 0 based! | 
|---|
| 561 | ------------------------------------------------------------------} | 
|---|
| 562 | function TMult.Subscript(const Position: longint): string; | 
|---|
| 563 | begin | 
|---|
| 564 | Result := ''; | 
|---|
| 565 | if (Position > -1) and (Position < Count) then | 
|---|
| 566 | Result := FMultiple[Position]; | 
|---|
| 567 | end; | 
|---|
| 568 |  | 
|---|
| 569 | {---------------------- TParamRecord.Create ----------------------- | 
|---|
| 570 | Creates TParamRecord instance and automatically creates TMult.  The | 
|---|
| 571 | name of Mult is also set in case it may be need if exception will be raised. | 
|---|
| 572 | ------------------------------------------------------------------} | 
|---|
| 573 | constructor TParamRecord.Create(AOwner: TComponent); | 
|---|
| 574 | begin | 
|---|
| 575 | inherited Create(AOwner); | 
|---|
| 576 | FMult := TMult.Create(Self); | 
|---|
| 577 | FMult.Name := 'Mult'; | 
|---|
| 578 | {note: FMult is destroyed in the SetClearParameters method} | 
|---|
| 579 | end; | 
|---|
| 580 |  | 
|---|
| 581 | destructor TParamRecord.Destroy; | 
|---|
| 582 | begin | 
|---|
| 583 | FMult.Free; | 
|---|
| 584 | FMult := nil; | 
|---|
| 585 | inherited; | 
|---|
| 586 | end; | 
|---|
| 587 |  | 
|---|
| 588 | {------------------------- TParams.Create ------------------------- | 
|---|
| 589 | ------------------------------------------------------------------} | 
|---|
| 590 | constructor TParams.Create(AOwner: TComponent); | 
|---|
| 591 | begin | 
|---|
| 592 | inherited Create(AOwner); | 
|---|
| 593 | FParameters := TList.Create;   {for now, empty list} | 
|---|
| 594 | end; | 
|---|
| 595 |  | 
|---|
| 596 | {------------------------ TParams.Destroy ------------------------- | 
|---|
| 597 | ------------------------------------------------------------------} | 
|---|
| 598 | destructor TParams.Destroy; | 
|---|
| 599 | begin | 
|---|
| 600 | Clear;                         {clear the Multiple first!} | 
|---|
| 601 | FParameters.Free; | 
|---|
| 602 | FParameters := nil; | 
|---|
| 603 | inherited Destroy; | 
|---|
| 604 | end; | 
|---|
| 605 |  | 
|---|
| 606 | {------------------------- TParams.Assign ------------------------- | 
|---|
| 607 | ------------------------------------------------------------------} | 
|---|
| 608 | procedure TParams.Assign(Source: TPersistent); | 
|---|
| 609 | var | 
|---|
| 610 | I: integer; | 
|---|
| 611 | SourceParams: TParams; | 
|---|
| 612 | begin | 
|---|
| 613 | Self.Clear; | 
|---|
| 614 | SourceParams := Source as TParams; | 
|---|
| 615 | for I := 0 to SourceParams.Count - 1 do begin | 
|---|
| 616 | Self[I].Value := SourceParams[I].Value; | 
|---|
| 617 | Self[I].PType := SourceParams[I].PType; | 
|---|
| 618 | Self[I].Mult.Assign(SourceParams[I].Mult); | 
|---|
| 619 | end | 
|---|
| 620 | end; | 
|---|
| 621 |  | 
|---|
| 622 | {------------------------- TParams.Clear -------------------------- | 
|---|
| 623 | ------------------------------------------------------------------} | 
|---|
| 624 | procedure TParams.Clear; | 
|---|
| 625 | var | 
|---|
| 626 | ParamRecord: TParamRecord; | 
|---|
| 627 | I: integer; | 
|---|
| 628 | begin | 
|---|
| 629 | if FParameters <> nil then begin | 
|---|
| 630 | for I := 0 to FParameters.Count - 1 do begin | 
|---|
| 631 | ParamRecord := TParamRecord(FParameters.Items[I]); | 
|---|
| 632 | if ParamRecord <> nil then begin  //could be nil if params were skipped by developer | 
|---|
| 633 | ParamRecord.FMult.Free; | 
|---|
| 634 | ParamRecord.FMult := nil; | 
|---|
| 635 | ParamRecord.Free; | 
|---|
| 636 | end; | 
|---|
| 637 | end; | 
|---|
| 638 | FParameters.Clear;             {release FParameters TList} | 
|---|
| 639 | end; | 
|---|
| 640 | end; | 
|---|
| 641 |  | 
|---|
| 642 | {------------------------ TParams.GetCount ------------------------ | 
|---|
| 643 | ------------------------------------------------------------------} | 
|---|
| 644 | function TParams.GetCount: Word; | 
|---|
| 645 | begin | 
|---|
| 646 | if FParameters = nil then Result := 0 | 
|---|
| 647 | else Result := FParameters.Count; | 
|---|
| 648 | end; | 
|---|
| 649 |  | 
|---|
| 650 | {---------------------- TParams.GetParameter ---------------------- | 
|---|
| 651 | ------------------------------------------------------------------} | 
|---|
| 652 | function TParams.GetParameter(Index: integer): TParamRecord; | 
|---|
| 653 | begin | 
|---|
| 654 | if Index >= FParameters.Count then             {if element out of bounds,} | 
|---|
| 655 | while FParameters.Count <= Index do | 
|---|
| 656 | FParameters.Add(nil);                     {setup place holders} | 
|---|
| 657 | if FParameters.Items[Index] = nil then begin   {if just a place holder,} | 
|---|
| 658 | {point it to new memory block} | 
|---|
| 659 | FParameters.Items[Index] := TParamRecord.Create(Self); | 
|---|
| 660 | TParamRecord(FParameters.Items[Index]).PType := undefined; {initialize} | 
|---|
| 661 | end; | 
|---|
| 662 | Result := FParameters.Items[Index];            {return requested parameter} | 
|---|
| 663 | end; | 
|---|
| 664 |  | 
|---|
| 665 | {---------------------- TParams.SetParameter ---------------------- | 
|---|
| 666 | ------------------------------------------------------------------} | 
|---|
| 667 | procedure TParams.SetParameter(Index: integer; Parameter: TParamRecord); | 
|---|
| 668 | begin | 
|---|
| 669 | if Index >= FParameters.Count then             {if element out of bounds,} | 
|---|
| 670 | while FParameters.Count <= Index do | 
|---|
| 671 | FParameters.Add(nil);                     {setup place holders} | 
|---|
| 672 | if FParameters.Items[Index] = nil then         {if just a place holder,} | 
|---|
| 673 | FParameters.Items[Index] := Parameter;      {point it to passed parameter} | 
|---|
| 674 | end; | 
|---|
| 675 |  | 
|---|
| 676 | {------------------------ TRPCBroker.Create ----------------------- | 
|---|
| 677 | ------------------------------------------------------------------} | 
|---|
| 678 | constructor TRPCBroker.Create(AOwner: TComponent); | 
|---|
| 679 | begin | 
|---|
| 680 | inherited Create(AOwner); | 
|---|
| 681 | {set defaults} | 
|---|
| 682 |  | 
|---|
| 683 | // This constant defined in the interface section needs to be updated for each release | 
|---|
| 684 | FBrokerVersion := CURRENT_RPC_VERSION; | 
|---|
| 685 |  | 
|---|
| 686 | FClearParameters := boolean(StrToInt | 
|---|
| 687 | (ReadRegDataDefault(HKLM,REG_BROKER,'ClearParameters','1'))); | 
|---|
| 688 | FClearResults := boolean(StrToInt | 
|---|
| 689 | (ReadRegDataDefault(HKLM,REG_BROKER,'ClearResults','1'))); | 
|---|
| 690 | FDebugMode := False; | 
|---|
| 691 | FParams := TParams.Create(Self); | 
|---|
| 692 | FResults := TStringList.Create; | 
|---|
| 693 | FServer := ReadRegDataDefault(HKLM,REG_BROKER,'Server','BROKERSERVER'); | 
|---|
| 694 | FPulse  := TTimer.Create(Self);  //P6 | 
|---|
| 695 | FListenerPort := StrToInt | 
|---|
| 696 | (ReadRegDataDefault(HKLM,REG_BROKER,'ListenerPort','9200')); | 
|---|
| 697 | FRpcVersion := '0'; | 
|---|
| 698 | FRPCTimeLimit := MIN_RPCTIMELIMIT; | 
|---|
| 699 | with FPulse do ///P6 | 
|---|
| 700 | begin | 
|---|
| 701 | Enabled := False;  //P6 | 
|---|
| 702 | Interval := DEFAULT_PULSE; //P6 | 
|---|
| 703 | OnTimer  := DoPulseOnTimer;  //P6 | 
|---|
| 704 | end; | 
|---|
| 705 | FLogin := TVistaLogin.Create(Self);  //p13 | 
|---|
| 706 | FKernelLogin := True;  //p13 | 
|---|
| 707 | FUser := TVistaUser.Create; //p13 | 
|---|
| 708 | FShowErrorMsgs := semRaise; //p13 | 
|---|
| 709 | XWBWinsock := TXWBWinsock.Create; | 
|---|
| 710 |  | 
|---|
| 711 | FIsBackwardCompatibleConnection := True;  // default | 
|---|
| 712 | Application.ProcessMessages; | 
|---|
| 713 | end; | 
|---|
| 714 |  | 
|---|
| 715 | {----------------------- TRPCBroker.Destroy ----------------------- | 
|---|
| 716 | ------------------------------------------------------------------} | 
|---|
| 717 | destructor TRPCBroker.Destroy; | 
|---|
| 718 | begin | 
|---|
| 719 | Connected := False; | 
|---|
| 720 | TXWBWinsock(XWBWinsock).Free; | 
|---|
| 721 | FParams.Free; | 
|---|
| 722 | FParams := nil; | 
|---|
| 723 | FResults.Free; | 
|---|
| 724 | FResults := nil; | 
|---|
| 725 | FPulse.Free; //P6 | 
|---|
| 726 | FPulse := nil; | 
|---|
| 727 | FUser.Free; | 
|---|
| 728 | FUser := nil; | 
|---|
| 729 | FLogin.Free; | 
|---|
| 730 | FLogin := nil; | 
|---|
| 731 | inherited Destroy; | 
|---|
| 732 | end; | 
|---|
| 733 |  | 
|---|
| 734 | {--------------------- TRPCBroker.CreateContext ------------------- | 
|---|
| 735 | This function is part of the overall Broker security. | 
|---|
| 736 | The passed context string is essentially a Client/Server type option | 
|---|
| 737 | on the server.  The server sets up MenuMan environment variables for this | 
|---|
| 738 | context which will later be used to screen RPCs.  Only those RPCs which are | 
|---|
| 739 | in the multiple field of this context option will be permitted to run. | 
|---|
| 740 | ------------------------------------------------------------------} | 
|---|
| 741 | function TRPCBroker.CreateContext(strContext: string): boolean; | 
|---|
| 742 | var | 
|---|
| 743 | InternalBroker: TRPCBroker;                       {use separate component} | 
|---|
| 744 | Str: String; | 
|---|
| 745 | begin | 
|---|
| 746 | Result := False; | 
|---|
| 747 | Connected := True; | 
|---|
| 748 | InternalBroker := nil; | 
|---|
| 749 | try | 
|---|
| 750 | InternalBroker := TRPCBroker.Create(Self); | 
|---|
| 751 | InternalBroker.FSocket := Self.Socket;   // p13 -- permits multiple broker connections to same server/port | 
|---|
| 752 | with InternalBroker do | 
|---|
| 753 | begin | 
|---|
| 754 | { | 
|---|
| 755 | TXWBWinsock(InternalBroker.XWBWinsock).IsBackwardsCompatible := TXWBWinsock(Self.XWBWinsock).IsBackwardsCompatible; | 
|---|
| 756 | TXWBWinsock(InternalBroker.XWBWinsock).OriginalConnectionOnly := TXWBWinsock(Self.XWBWinsock).OriginalConnectionOnly; | 
|---|
| 757 | } | 
|---|
| 758 | Tag := 1234; | 
|---|
| 759 | ShowErrorMsgs := Self.ShowerrorMsgs; | 
|---|
| 760 | Server := Self.Server;                   {inherit application server} | 
|---|
| 761 | ListenerPort := Self.ListenerPort;       {inherit listener port} | 
|---|
| 762 | DebugMode := Self.DebugMode;             {inherit debug mode property} | 
|---|
| 763 | RemoteProcedure := 'XWB CREATE CONTEXT'; {set up RPC} | 
|---|
| 764 | Param[0].PType := literal; | 
|---|
| 765 | Param[0].Value := Encrypt(strContext); | 
|---|
| 766 | try | 
|---|
| 767 | Str := strCall; | 
|---|
| 768 | if Str = '1' then | 
|---|
| 769 | begin                   // make the call  // p13 | 
|---|
| 770 | Result := True;                       // p13 | 
|---|
| 771 | self.FCurrentContext := strContext;        // p13 | 
|---|
| 772 | end                                     // p13 | 
|---|
| 773 | else | 
|---|
| 774 | begin | 
|---|
| 775 | Result := False; | 
|---|
| 776 | self.FCurrentContext := ''; | 
|---|
| 777 | end; | 
|---|
| 778 | except            // Code added to return False if User doesn't have access | 
|---|
| 779 | on e: EBrokerError do | 
|---|
| 780 | begin | 
|---|
| 781 | self.FCurrentContext := ''; | 
|---|
| 782 | if Pos('does not have access to option',e.Message) > 0 then | 
|---|
| 783 | begin | 
|---|
| 784 | Result := False | 
|---|
| 785 | end | 
|---|
| 786 | else | 
|---|
| 787 | Raise; | 
|---|
| 788 | end; | 
|---|
| 789 | end; | 
|---|
| 790 | if RPCBError <> '' then | 
|---|
| 791 | self.RPCBError := RPCBError; | 
|---|
| 792 | end; | 
|---|
| 793 | finally | 
|---|
| 794 | InternalBroker.XWBWinsock := nil; | 
|---|
| 795 | InternalBroker.Free;                            {release memory} | 
|---|
| 796 | end; | 
|---|
| 797 | end; | 
|---|
| 798 |  | 
|---|
| 799 | {------------------------ TRPCBroker.Loaded ----------------------- | 
|---|
| 800 | ------------------------------------------------------------------} | 
|---|
| 801 | procedure TRPCBroker.Loaded; | 
|---|
| 802 | begin | 
|---|
| 803 | inherited Loaded; | 
|---|
| 804 | end; | 
|---|
| 805 |  | 
|---|
| 806 | {------------------------- TRPCBroker.Call ------------------------ | 
|---|
| 807 | ------------------------------------------------------------------} | 
|---|
| 808 | procedure TRPCBroker.Call; | 
|---|
| 809 | var | 
|---|
| 810 | ResultBuffer: TStrings; | 
|---|
| 811 | begin | 
|---|
| 812 | ResultBuffer := TStringList.Create; | 
|---|
| 813 | try | 
|---|
| 814 | if ClearResults then ClearResults := True; | 
|---|
| 815 | lstCall(ResultBuffer); | 
|---|
| 816 | Self.Results.AddStrings(ResultBuffer); | 
|---|
| 817 | finally | 
|---|
| 818 | ResultBuffer.Clear; | 
|---|
| 819 | ResultBuffer.Free; | 
|---|
| 820 | end; | 
|---|
| 821 | end; | 
|---|
| 822 |  | 
|---|
| 823 | {----------------------- TRPCBroker.lstCall ----------------------- | 
|---|
| 824 | ------------------------------------------------------------------} | 
|---|
| 825 | procedure TRPCBroker.lstCall(OutputBuffer: TStrings); | 
|---|
| 826 | var | 
|---|
| 827 | ManyStrings: PChar; | 
|---|
| 828 | begin | 
|---|
| 829 | ManyStrings := pchCall;            {make the call} | 
|---|
| 830 | OutputBuffer.SetText(ManyStrings); {parse result of call, format as list} | 
|---|
| 831 | StrDispose(ManyStrings);           {raw result no longer needed, get back mem} | 
|---|
| 832 | end; | 
|---|
| 833 |  | 
|---|
| 834 | {----------------------- TRPCBroker.strCall ----------------------- | 
|---|
| 835 | ------------------------------------------------------------------} | 
|---|
| 836 | function TRPCBroker.strCall: string; | 
|---|
| 837 | var | 
|---|
| 838 | ResultString: PChar; | 
|---|
| 839 | begin | 
|---|
| 840 | ResultString := pchCall;           {make the call} | 
|---|
| 841 | Result := StrPas(ResultString);    {convert and present as Pascal string} | 
|---|
| 842 | StrDispose(ResultString);          {raw result no longer needed, get back mem} | 
|---|
| 843 | end; | 
|---|
| 844 |  | 
|---|
| 845 | {--------------------- TRPCBroker.SetConnected -------------------- | 
|---|
| 846 | ------------------------------------------------------------------} | 
|---|
| 847 | procedure TRPCBroker.SetConnected(Value: Boolean); | 
|---|
| 848 | var | 
|---|
| 849 | BrokerDir, Str1, Str2, Str3 :string; | 
|---|
| 850 | begin | 
|---|
| 851 | RPCBError := ''; | 
|---|
| 852 | Login.ErrorText := ''; | 
|---|
| 853 | if (Connected <> Value) and not(csReading in ComponentState) then begin | 
|---|
| 854 | if Value and (FConnecting <> Value) then begin                 {connect} | 
|---|
| 855 | FSocket := ExistingSocket(Self); | 
|---|
| 856 | FConnecting := True; // FConnected := True; | 
|---|
| 857 | try | 
|---|
| 858 | if FSocket = 0  then | 
|---|
| 859 | begin | 
|---|
| 860 | {Execute Client Agent from directory in Registry.} | 
|---|
| 861 | BrokerDir := ReadRegData(HKLM, REG_BROKER, 'BrokerDr'); | 
|---|
| 862 | if BrokerDir <> '' then | 
|---|
| 863 | ProcessExecute(BrokerDir + '\ClAgent.Exe', sw_ShowNoActivate) | 
|---|
| 864 | else | 
|---|
| 865 | ProcessExecute('ClAgent.Exe', sw_ShowNoActivate); | 
|---|
| 866 | if DebugMode and (not OldConnectionOnly) then | 
|---|
| 867 | begin | 
|---|
| 868 | Str1 := 'Control of debugging has been moved from the client to the server. To start a Debug session, do the following:'+#13#10#13#10; | 
|---|
| 869 | Str2 := '1. On the server, set initial breakpoints where desired.'+#13#10+'2. DO DEBUG^XWBTCPM.'+#13#10+'3. Enter a unique Listener port number (i.e., a port number not in general use).'+#13#10; | 
|---|
| 870 | Str3 := '4. Connect the client application using the port number entered in Step #3.'; | 
|---|
| 871 | ShowMessage(Str1 + Str2 + Str3); | 
|---|
| 872 | end; | 
|---|
| 873 | TXWBWinsock(XWBWinsock).IsBackwardsCompatible := FIsBackwardCompatibleConnection; | 
|---|
| 874 | TXWBWinsock(XWBWinsock).OldConnectionOnly := FOldConnectionOnly; | 
|---|
| 875 | FSocket := TXWBWinsock(XWBWinsock).NetworkConnect(DebugMode, FServer, | 
|---|
| 876 | ListenerPort, FRPCTimeLimit); | 
|---|
| 877 | AuthenticateUser(Self); | 
|---|
| 878 | FPulse.Enabled := True; //P6 Start heartbeat. | 
|---|
| 879 | StoreConnection(Self);  //MUST store connection before CreateContext() | 
|---|
| 880 | CreateContext('');      //Closes XUS SIGNON context. | 
|---|
| 881 | end | 
|---|
| 882 | else | 
|---|
| 883 | begin                     //p13 | 
|---|
| 884 | StoreConnection(Self); | 
|---|
| 885 | FPulse.Enabled := True; //p13 | 
|---|
| 886 | end;                      //p13 | 
|---|
| 887 | FConnected := True;         // jli mod 12/17/01 | 
|---|
| 888 | FConnecting := False; | 
|---|
| 889 | except | 
|---|
| 890 | on E: EBrokerError do begin | 
|---|
| 891 | if E.Code = XWB_BadSignOn then | 
|---|
| 892 | TXWBWinsock(XWBWinsock).NetworkDisconnect(FSocket); | 
|---|
| 893 | FSocket := 0; | 
|---|
| 894 | FConnected := False; | 
|---|
| 895 | FConnecting := False; | 
|---|
| 896 | FRPCBError := E.Message;               // p13  handle errors as specified | 
|---|
| 897 | if Login.ErrorText <> '' then | 
|---|
| 898 | FRPCBError := E.Message + chr(10) + Login.ErrorText; | 
|---|
| 899 | if Assigned(FOnRPCBFailure) then       // p13 | 
|---|
| 900 | FOnRPCBFailure(Self)                 // p13 | 
|---|
| 901 | else if ShowErrorMsgs = semRaise then | 
|---|
| 902 | Raise;                               // p13 | 
|---|
| 903 | //          raise;   {this is where I would do OnNetError} | 
|---|
| 904 | end{on}; | 
|---|
| 905 | end{try}; | 
|---|
| 906 | end{if} | 
|---|
| 907 | else if not Value then | 
|---|
| 908 | begin                           //p13 | 
|---|
| 909 | FConnected := False;          //p13 | 
|---|
| 910 | FPulse.Enabled := False;      //p13 | 
|---|
| 911 | if RemoveConnection(Self) = NoMore then begin | 
|---|
| 912 | {FPulse.Enabled := False;  ///P6;p13 } | 
|---|
| 913 | TXWBWinsock(XWBWinsock).NetworkDisconnect(Socket);   {actually disconnect from server} | 
|---|
| 914 | FSocket := 0;                {store internal} | 
|---|
| 915 | //FConnected := False;      //p13 | 
|---|
| 916 | end{if}; | 
|---|
| 917 | end; {else} | 
|---|
| 918 | end{if}; | 
|---|
| 919 | end; | 
|---|
| 920 |  | 
|---|
| 921 | {----------------- TRPCBroker.SetClearParameters ------------------ | 
|---|
| 922 | ------------------------------------------------------------------} | 
|---|
| 923 | procedure TRPCBroker.SetClearParameters(Value: Boolean); | 
|---|
| 924 | begin | 
|---|
| 925 | if Value then FParams.Clear; | 
|---|
| 926 | FClearParameters := Value; | 
|---|
| 927 | end; | 
|---|
| 928 |  | 
|---|
| 929 | {------------------- TRPCBroker.SetClearResults ------------------- | 
|---|
| 930 | ------------------------------------------------------------------} | 
|---|
| 931 | procedure TRPCBroker.SetClearResults(Value: Boolean); | 
|---|
| 932 | begin | 
|---|
| 933 | if Value then begin   {if True} | 
|---|
| 934 | FResults.Clear; | 
|---|
| 935 | end; | 
|---|
| 936 | FClearResults := Value; | 
|---|
| 937 | end; | 
|---|
| 938 |  | 
|---|
| 939 | {---------------------- TRPCBroker.SetResults --------------------- | 
|---|
| 940 | ------------------------------------------------------------------} | 
|---|
| 941 | procedure TRPCBroker.SetResults(Value: TStrings); | 
|---|
| 942 | begin | 
|---|
| 943 | FResults.Assign(Value); | 
|---|
| 944 | end; | 
|---|
| 945 |  | 
|---|
| 946 | {----------------------- TRPCBroker.SetRPCTimeLimit ----------------- | 
|---|
| 947 | ------------------------------------------------------------------} | 
|---|
| 948 | procedure   TRPCBroker.SetRPCTimeLimit(Value: integer); | 
|---|
| 949 | begin | 
|---|
| 950 | if Value <> FRPCTimeLimit then | 
|---|
| 951 | if Value > MIN_RPCTIMELIMIT then | 
|---|
| 952 | FRPCTimeLimit := Value | 
|---|
| 953 | else | 
|---|
| 954 | FRPCTimeLimit := MIN_RPCTIMELIMIT; | 
|---|
| 955 | end; | 
|---|
| 956 |  | 
|---|
| 957 | {----------------------- TRPCBroker.SetServer --------------------- | 
|---|
| 958 | ------------------------------------------------------------------} | 
|---|
| 959 | procedure TRPCBroker.SetServer(Value: TServer); | 
|---|
| 960 | begin | 
|---|
| 961 | {if changing the name of the server, make sure to disconnect first} | 
|---|
| 962 | if (Value <> FServer) and Connected then begin | 
|---|
| 963 | Connected := False; | 
|---|
| 964 | end; | 
|---|
| 965 | FServer := Value; | 
|---|
| 966 | end; | 
|---|
| 967 |  | 
|---|
| 968 | {--------------------- TRPCBroker.pchCall ---------------------- | 
|---|
| 969 | Lowest level remote procedure call that a TRPCBroker component can make. | 
|---|
| 970 | 1. Returns PChar. | 
|---|
| 971 | 2. Converts Remote Procedure to PChar internally. | 
|---|
| 972 | ------------------------------------------------------------------} | 
|---|
| 973 | function TRPCBroker.pchCall: PChar; | 
|---|
| 974 | var | 
|---|
| 975 | Value, Sec, App: PChar; | 
|---|
| 976 | BrokerError: EBrokerError; | 
|---|
| 977 | blnRestartPulse : boolean;   //P6 | 
|---|
| 978 | begin | 
|---|
| 979 | RPCBError := ''; | 
|---|
| 980 | Connected := True; | 
|---|
| 981 | BrokerError := nil; | 
|---|
| 982 | Value := nil; | 
|---|
| 983 | blnRestartPulse := False;   //P6 | 
|---|
| 984 |  | 
|---|
| 985 | Sec := StrAlloc(255); | 
|---|
| 986 | App := StrAlloc(255); | 
|---|
| 987 |  | 
|---|
| 988 | try | 
|---|
| 989 | if FPulse.Enabled then          ///P6 If Broker was sending pulse, | 
|---|
| 990 | begin | 
|---|
| 991 | FPulse.Enabled := False;      ///   Stop pulse & | 
|---|
| 992 | blnRestartPulse := True;     //   Set flag to restart pulse after RPC. | 
|---|
| 993 | end; | 
|---|
| 994 | { | 
|---|
| 995 | if Assigned(FOnRPCCall) then | 
|---|
| 996 | begin | 
|---|
| 997 | FOnRPCCall(Self, 1, RemoteProcedure, CurrentContext, RpcVersion, Param, FRPCTimeLimit, '', '', '', Now); | 
|---|
| 998 | end; | 
|---|
| 999 | } | 
|---|
| 1000 | try | 
|---|
| 1001 | Value := TXWBWinsock(XWBWinsock).tCall(Socket, RemoteProcedure, RpcVersion, Param, | 
|---|
| 1002 | Sec, App,FRPCTimeLimit); | 
|---|
| 1003 | { | 
|---|
| 1004 | if Assigned(FOnRPCCall) then | 
|---|
| 1005 | begin | 
|---|
| 1006 | FOnRPCCall(Self, 2, RemoteProcedure, CurrentContext, RpcVersion, Param, FRPCTimeLimit, Result, Sec, App, Now); | 
|---|
| 1007 | end; | 
|---|
| 1008 | } | 
|---|
| 1009 | if (StrLen(Sec) > 0) then | 
|---|
| 1010 | begin | 
|---|
| 1011 | BrokerError := EBrokerError.Create(StrPas(Sec)); | 
|---|
| 1012 | BrokerError.Code := 0; | 
|---|
| 1013 | BrokerError.Action := 'Error Returned'; | 
|---|
| 1014 | end; | 
|---|
| 1015 | except | 
|---|
| 1016 | on Etemp: EBrokerError do | 
|---|
| 1017 | with Etemp do | 
|---|
| 1018 | begin                             //save copy of error | 
|---|
| 1019 | BrokerError := EBrokerError.Create(message);  //field by field | 
|---|
| 1020 | BrokerError.Action := Action; | 
|---|
| 1021 | BrokerError.Code := Code; | 
|---|
| 1022 | BrokerError.Mnemonic := Mnemonic; | 
|---|
| 1023 | if Value <> nil then | 
|---|
| 1024 | StrDispose(Value); | 
|---|
| 1025 | Value := StrNew(''); | 
|---|
| 1026 | {if severe error, mark connection as closed.  Per Enrique, we should | 
|---|
| 1027 | replace this check with some function, yet to be developed, which | 
|---|
| 1028 | will test the link.} | 
|---|
| 1029 | if ((Code >= 10050)and(Code <=10058))or(Action = 'connection lost') then | 
|---|
| 1030 | begin | 
|---|
| 1031 | Connected := False; | 
|---|
| 1032 | blnRestartPulse := False;  //P6 | 
|---|
| 1033 | end; | 
|---|
| 1034 | end; | 
|---|
| 1035 | end; | 
|---|
| 1036 | finally | 
|---|
| 1037 | StrDispose(Sec); {do something with these} | 
|---|
| 1038 | Sec := nil; | 
|---|
| 1039 | StrDispose(App); | 
|---|
| 1040 | App := nil; | 
|---|
| 1041 | if ClearParameters then ClearParameters := True;    //prepare for next call | 
|---|
| 1042 | end; | 
|---|
| 1043 | Result := Value; | 
|---|
| 1044 | if Result = nil then Result := StrNew('');            //return empty string | 
|---|
| 1045 | if blnRestartPulse then FPulse.Enabled := True;       //Restart pulse. (P6) | 
|---|
| 1046 | if BrokerError <> nil then | 
|---|
| 1047 | begin | 
|---|
| 1048 | FRPCBError := BrokerError.Message;               // p13  handle errors as specified | 
|---|
| 1049 | if Login.ErrorText <> '' then | 
|---|
| 1050 | FRPCBError := BrokerError.Message + chr(10) + Login.ErrorText; | 
|---|
| 1051 | if Assigned(FOnRPCBFailure) then       // p13 | 
|---|
| 1052 | begin | 
|---|
| 1053 | FOnRPCBFailure(Self); | 
|---|
| 1054 | StrDispose(Result); | 
|---|
| 1055 | end | 
|---|
| 1056 | else if FShowErrorMsgs = semRaise then | 
|---|
| 1057 | begin | 
|---|
| 1058 | StrDispose(Result);                 // return memory we won't use - caused a memory leak | 
|---|
| 1059 | Raise BrokerError;                               // p13 | 
|---|
| 1060 | end | 
|---|
| 1061 | else   // silent, just return error message in FRPCBError | 
|---|
| 1062 | BrokerError.Free;   // return memory in BrokerError - otherwise is a memory leak | 
|---|
| 1063 | //          raise;   {this is where I would do OnNetError} | 
|---|
| 1064 | end;  // if BrokerError <> nil | 
|---|
| 1065 | end; | 
|---|
| 1066 |  | 
|---|
| 1067 |  | 
|---|
| 1068 | {-------------------------- DisconnectAll ------------------------- | 
|---|
| 1069 | Find all connections in BrokerAllConnections list for the passed in | 
|---|
| 1070 | server:listenerport combination and disconnect them. If at least one | 
|---|
| 1071 | connection to the server:listenerport is found, then it and all other | 
|---|
| 1072 | Brokers to the same server:listenerport will be disconnected; True | 
|---|
| 1073 | will be returned.  Otherwise False will return. | 
|---|
| 1074 | ------------------------------------------------------------------} | 
|---|
| 1075 | function DisconnectAll(Server: string; ListenerPort: integer): boolean; | 
|---|
| 1076 | var | 
|---|
| 1077 | Index: integer; | 
|---|
| 1078 | begin | 
|---|
| 1079 | Result := False; | 
|---|
| 1080 | while (Assigned(BrokerAllConnections) and | 
|---|
| 1081 | (BrokerAllConnections.Find(Server + ':' + IntToStr(ListenerPort), Index))) do begin | 
|---|
| 1082 | Result := True; | 
|---|
| 1083 | TRPCBroker(BrokerAllConnections.Objects[Index]).Connected := False; | 
|---|
| 1084 | {if the call above disconnected the last connection in the list, then | 
|---|
| 1085 | the whole list will be destroyed, making it necessary to check if it's | 
|---|
| 1086 | still assigned.} | 
|---|
| 1087 | end; | 
|---|
| 1088 | end; | 
|---|
| 1089 |  | 
|---|
| 1090 | {------------------------- StoreConnection ------------------------ | 
|---|
| 1091 | Each broker connection is stored in BrokerConnections list. | 
|---|
| 1092 | ------------------------------------------------------------------} | 
|---|
| 1093 | procedure StoreConnection(Broker: TRPCBroker); | 
|---|
| 1094 | begin | 
|---|
| 1095 | if BrokerConnections = nil then {list is created when 1st entry is added} | 
|---|
| 1096 | try | 
|---|
| 1097 | BrokerConnections := TStringList.Create; | 
|---|
| 1098 | BrokerConnections.Sorted := True; | 
|---|
| 1099 | BrokerConnections.Duplicates := dupAccept;  {store every connection} | 
|---|
| 1100 | BrokerAllConnections := TStringList.Create; | 
|---|
| 1101 | BrokerAllConnections.Sorted := True; | 
|---|
| 1102 | BrokerAllConnections.Duplicates := dupAccept; | 
|---|
| 1103 | except | 
|---|
| 1104 | TXWBWinsock(Broker.XWBWinsock).NetError('store connection',XWB_BldConnectList) | 
|---|
| 1105 | end; | 
|---|
| 1106 | BrokerAllConnections.AddObject(Broker.Server + ':' + | 
|---|
| 1107 | IntToStr(Broker.ListenerPort), Broker); | 
|---|
| 1108 | BrokerConnections.AddObject(IntToStr(Broker.Socket), Broker); | 
|---|
| 1109 | end; | 
|---|
| 1110 |  | 
|---|
| 1111 | {------------------------ RemoveConnection ------------------------ | 
|---|
| 1112 | Result of this function will be False, if there are no more connections | 
|---|
| 1113 | to the same server:listenerport as the passed in Broker.  If at least | 
|---|
| 1114 | one other connection is found to the same server:listenerport, then Result | 
|---|
| 1115 | will be True. | 
|---|
| 1116 | ------------------------------------------------------------------} | 
|---|
| 1117 | function RemoveConnection(Broker: TRPCBroker): boolean; | 
|---|
| 1118 | var | 
|---|
| 1119 | Index: integer; | 
|---|
| 1120 | begin | 
|---|
| 1121 | Result := False; | 
|---|
| 1122 | if Assigned(BrokerConnections) then begin | 
|---|
| 1123 | {remove connection record of passed in Broker component} | 
|---|
| 1124 | BrokerConnections.Delete(BrokerConnections.IndexOfObject(Broker)); | 
|---|
| 1125 | {look for one other connection to the same server:port} | 
|---|
| 1126 | //    Result := BrokerConnections.Find(Broker.Server + ':' + IntToStr(Broker.ListenerPort), Index); | 
|---|
| 1127 | Result := BrokerConnections.Find(IntToStr(Broker.Socket), Index); | 
|---|
| 1128 | if BrokerConnections.Count = 0 then begin {if last entry removed,} | 
|---|
| 1129 | BrokerConnections.Free;                 {destroy whole list structure} | 
|---|
| 1130 | BrokerConnections := nil; | 
|---|
| 1131 | end; | 
|---|
| 1132 | end;  // if Assigned(BrokerConnections) | 
|---|
| 1133 | if Assigned(BrokerAllConnections) then begin | 
|---|
| 1134 | BrokerAllConnections.Delete(BrokerAllConnections.IndexOfObject(Broker)); | 
|---|
| 1135 | if BrokerAllConnections.Count = 0 then begin | 
|---|
| 1136 | BrokerAllConnections.Free; | 
|---|
| 1137 | BrokerAllConnections := nil; | 
|---|
| 1138 | end; | 
|---|
| 1139 | end;   // if Assigned(BrokerAllConnections) | 
|---|
| 1140 | end; | 
|---|
| 1141 |  | 
|---|
| 1142 | {------------------------- ExistingSocket ------------------------- | 
|---|
| 1143 | ------------------------------------------------------------------} | 
|---|
| 1144 | function ExistingSocket(Broker: TRPCBroker): integer; | 
|---|
| 1145 | // var | 
|---|
| 1146 | //   Index: integer; | 
|---|
| 1147 | begin | 
|---|
| 1148 | Result := Broker.Socket; | 
|---|
| 1149 | {  Result := 0;                        // p13 to permit multiple Broker connections | 
|---|
| 1150 |  | 
|---|
| 1151 | if Assigned(BrokerConnections) and | 
|---|
| 1152 | BrokerConnections.Find(Broker.Server + ':' + IntToStr(Broker.ListenerPort), Index) then | 
|---|
| 1153 | Result := TRPCBroker(BrokerConnections.Objects[Index]).Socket; | 
|---|
| 1154 | } | 
|---|
| 1155 | end; | 
|---|
| 1156 |  | 
|---|
| 1157 | {------------------------ AuthenticateUser ------------------------ | 
|---|
| 1158 | ------------------------------------------------------------------} | 
|---|
| 1159 | procedure AuthenticateUser(ConnectingBroker: TRPCBroker); | 
|---|
| 1160 | var | 
|---|
| 1161 | SaveClearParmeters, SaveClearResults: boolean; | 
|---|
| 1162 | SaveParam: TParams; | 
|---|
| 1163 | SaveRemoteProcedure, SaveRpcVersion: string; | 
|---|
| 1164 | SaveResults: TStrings; | 
|---|
| 1165 | blnSignedOn: boolean; | 
|---|
| 1166 | SaveKernelLogin: boolean; | 
|---|
| 1167 | SaveVistaLogin: TVistaLogin; | 
|---|
| 1168 | OldExceptionHandler: TExceptionEvent; | 
|---|
| 1169 | OldHandle: THandle; | 
|---|
| 1170 | begin | 
|---|
| 1171 | With ConnectingBroker do | 
|---|
| 1172 | begin | 
|---|
| 1173 | SaveParam := TParams.Create(nil); | 
|---|
| 1174 | SaveParam.Assign(Param);                  //save off settings | 
|---|
| 1175 | SaveRemoteProcedure := RemoteProcedure; | 
|---|
| 1176 | SaveRpcVersion := RpcVersion; | 
|---|
| 1177 | SaveResults := Results; | 
|---|
| 1178 | SaveClearParmeters := ClearParameters; | 
|---|
| 1179 | SaveClearResults := ClearResults; | 
|---|
| 1180 | ClearParameters := True;                  //set'em as I need'em | 
|---|
| 1181 | ClearResults := True; | 
|---|
| 1182 | SaveKernelLogin := FKernelLogin;     //  p13 | 
|---|
| 1183 | SaveVistaLogin := FLogin;            //  p13 | 
|---|
| 1184 | end; | 
|---|
| 1185 |  | 
|---|
| 1186 | blnSignedOn := False;                       //initialize to bad sign-on | 
|---|
| 1187 |  | 
|---|
| 1188 | if ConnectingBroker.AccessVerifyCodes <> '' then   // p13 handle as AVCode single signon | 
|---|
| 1189 | begin | 
|---|
| 1190 | ConnectingBroker.Login.AccessCode := Piece(ConnectingBroker.AccessVerifyCodes, ';', 1); | 
|---|
| 1191 | ConnectingBroker.Login.VerifyCode := Piece(ConnectingBroker.AccessVerifyCodes, ';', 2); | 
|---|
| 1192 | ConnectingBroker.Login.Mode := lmAVCodes; | 
|---|
| 1193 | ConnectingBroker.FKernelLogIn := False; | 
|---|
| 1194 | end; | 
|---|
| 1195 |  | 
|---|
| 1196 | if ConnectingBroker.FKernelLogIn then | 
|---|
| 1197 | begin   //p13 | 
|---|
| 1198 | if Assigned(Application.OnException) then | 
|---|
| 1199 | OldExceptionHandler := Application.OnException | 
|---|
| 1200 | else | 
|---|
| 1201 | OldExceptionHandler := nil; | 
|---|
| 1202 | Application.OnException := TfrmErrMsg.RPCBShowException; | 
|---|
| 1203 | frmSignon := TfrmSignon.Create(Application); | 
|---|
| 1204 | try | 
|---|
| 1205 |  | 
|---|
| 1206 | //    ShowApplicationAndFocusOK(Application); | 
|---|
| 1207 | OldHandle := GetForegroundWindow; | 
|---|
| 1208 | SetForegroundWindow(frmSignon.Handle); | 
|---|
| 1209 | PrepareSignonForm(ConnectingBroker); | 
|---|
| 1210 | if SetUpSignOn then                       //SetUpSignOn in loginfrm unit. | 
|---|
| 1211 | begin                                     //True if signon needed | 
|---|
| 1212 | {                                               // p13 handle as AVCode single signon | 
|---|
| 1213 | if ConnectingBroker.AccessVerifyCodes <> '' then | 
|---|
| 1214 | begin {do non interactive logon | 
|---|
| 1215 | frmSignon.accessCode.Text := Piece(ConnectingBroker.AccessVerifyCodes, ';', 1); | 
|---|
| 1216 | frmSignon.verifyCode.Text := Piece(ConnectingBroker.AccessVerifyCodes, ';', 2); | 
|---|
| 1217 | //Application.ProcessMessages; | 
|---|
| 1218 | frmSignon.btnOk.Click; | 
|---|
| 1219 | end | 
|---|
| 1220 | else frmSignOn.ShowModal;               //do interactive logon | 
|---|
| 1221 | } | 
|---|
| 1222 | //      ShowApplicationAndFocusOK(Application); | 
|---|
| 1223 | //      SetForegroundWindow(frmSignOn.Handle); | 
|---|
| 1224 | if frmSignOn.lblServer.Caption <> '' then | 
|---|
| 1225 | begin | 
|---|
| 1226 | frmSignOn.ShowModal;                    //do interactive logon   // p13 | 
|---|
| 1227 | if frmSignOn.Tag = 1 then               //Tag=1 for good logon | 
|---|
| 1228 | blnSignedOn := True;                   //Successfull logon | 
|---|
| 1229 | end | 
|---|
| 1230 | end | 
|---|
| 1231 | else                                      //False when no logon needed | 
|---|
| 1232 | blnSignedOn := NoSignOnNeeded;          //Returns True always (for now!) | 
|---|
| 1233 | if blnSignedOn then                       //P6 If logged on, retrieve user info. | 
|---|
| 1234 | begin | 
|---|
| 1235 | GetBrokerInfo(ConnectingBroker); | 
|---|
| 1236 | if not SelDiv.ChooseDiv('',ConnectingBroker) then | 
|---|
| 1237 | begin | 
|---|
| 1238 | blnSignedOn := False;//P8 | 
|---|
| 1239 | {Select division if multi-division user.  First parameter is 'userid' | 
|---|
| 1240 | (DUZ or username) for future use. (P8)} | 
|---|
| 1241 | ConnectingBroker.Login.ErrorText := 'Failed to select Division';  // p13 set some text indicating problem | 
|---|
| 1242 | end; | 
|---|
| 1243 | end; | 
|---|
| 1244 | SetForegroundWindow(OldHandle); | 
|---|
| 1245 | finally | 
|---|
| 1246 | frmSignon.Free; | 
|---|
| 1247 | //      frmSignon.Release;                        //get rid of signon form | 
|---|
| 1248 |  | 
|---|
| 1249 | //      if ConnectingBroker.Owner is TForm then | 
|---|
| 1250 | //        SetForegroundWindow(TForm(ConnectingBroker.Owner).Handle) | 
|---|
| 1251 | //      else | 
|---|
| 1252 | //        SetForegroundWindow(ActiveWindow); | 
|---|
| 1253 | ShowApplicationAndFocusOK(Application); | 
|---|
| 1254 | end ; //try | 
|---|
| 1255 | if Assigned(OldExceptionHandler) then | 
|---|
| 1256 | Application.OnException := OldExceptionHandler; | 
|---|
| 1257 | end;   //if kernellogin | 
|---|
| 1258 | // p13  following section for silent signon | 
|---|
| 1259 | if not ConnectingBroker.FKernelLogIn then | 
|---|
| 1260 | if ConnectingBroker.FLogin <> nil then     //the user.  vistalogin contains login info | 
|---|
| 1261 | blnsignedon := SilentLogin(ConnectingBroker);    // RpcSLogin unit | 
|---|
| 1262 | if not blnsignedon then | 
|---|
| 1263 | begin | 
|---|
| 1264 | ConnectingBroker.FLogin.FailedLogin(ConnectingBroker.FLogin); | 
|---|
| 1265 | TXWBWinsock(ConnectingBroker.XWBWinsock).NetworkDisconnect(ConnectingBroker.FSocket); | 
|---|
| 1266 | end | 
|---|
| 1267 | else | 
|---|
| 1268 | GetBrokerInfo(ConnectingBroker); | 
|---|
| 1269 |  | 
|---|
| 1270 | //reset the Broker | 
|---|
| 1271 | with ConnectingBroker do | 
|---|
| 1272 | begin | 
|---|
| 1273 | ClearParameters := SaveClearParmeters; | 
|---|
| 1274 | ClearResults := SaveClearResults; | 
|---|
| 1275 | Param.Assign(SaveParam);                  //restore settings | 
|---|
| 1276 | SaveParam.Free; | 
|---|
| 1277 | RemoteProcedure := SaveRemoteProcedure; | 
|---|
| 1278 | RpcVersion := SaveRpcVersion; | 
|---|
| 1279 | Results := SaveResults; | 
|---|
| 1280 | FKernelLogin := SaveKernelLogin;         // p13 | 
|---|
| 1281 | FLogin := SaveVistaLogin;                // p13 | 
|---|
| 1282 | end; | 
|---|
| 1283 |  | 
|---|
| 1284 | if not blnSignedOn then                     //Flag for unsuccessful signon. | 
|---|
| 1285 | TXWBWinsock(ConnectingBroker.XWBWinsock).NetError('',XWB_BadSignOn);               //Will raise error. | 
|---|
| 1286 |  | 
|---|
| 1287 | end; | 
|---|
| 1288 |  | 
|---|
| 1289 | {------------------------ GetBrokerInfo ------------------------ | 
|---|
| 1290 | P6  Retrieve information about user with XWB GET BROKER INFO | 
|---|
| 1291 | RPC. For now, only Timeout value is retrieved in Results[0]. | 
|---|
| 1292 | ------------------------------------------------------------------} | 
|---|
| 1293 | procedure GetBrokerInfo(ConnectedBroker: TRPCBroker); | 
|---|
| 1294 | begin | 
|---|
| 1295 | GetUserInfo(ConnectedBroker);  //  p13  Get User info into User property (TVistaUser object) | 
|---|
| 1296 | With ConnectedBroker do        //(dcm) Use one of objects below | 
|---|
| 1297 | begin                          // and skip this RPC? or make this and | 
|---|
| 1298 | RemoteProcedure := 'XWB GET BROKER INFO';   // others below as components | 
|---|
| 1299 | try | 
|---|
| 1300 | Call; | 
|---|
| 1301 | if Results.Count > 0 then | 
|---|
| 1302 | if StrToInt(Results[0]) > MINIMUM_TIMEOUT then | 
|---|
| 1303 | FPulse.Interval := (StrToInt(Results[0]) * 10 * PULSE_PERCENTAGE); | 
|---|
| 1304 | except | 
|---|
| 1305 | On e: EBrokerError do | 
|---|
| 1306 | ShowMessage('A problem was encountered getting Broker information.  '+e.Message);  //TODO | 
|---|
| 1307 | end; | 
|---|
| 1308 | end; | 
|---|
| 1309 | end; | 
|---|
| 1310 |  | 
|---|
| 1311 | {------------------------ NoSignOnNeeded ------------------------ | 
|---|
| 1312 | ------------------------------------------------------------------} | 
|---|
| 1313 | {Currently a placeholder for actions that may be needed in connection | 
|---|
| 1314 | with authenticating a user who needn't sign on (Single Sign on feature). | 
|---|
| 1315 | Returns True if no signon is needed | 
|---|
| 1316 | False if signon is needed.} | 
|---|
| 1317 | function  NoSignOnNeeded : Boolean; | 
|---|
| 1318 | begin | 
|---|
| 1319 | Result := True; | 
|---|
| 1320 | end; | 
|---|
| 1321 |  | 
|---|
| 1322 | {------------------------- ProcessExecute ------------------------- | 
|---|
| 1323 | This function is borrowed from "Delphi 2 Developer's Guide" by Pacheco & Teixera. | 
|---|
| 1324 | See chapter 11, page 406.  It encapsulates and simplifies use of | 
|---|
| 1325 | Windows CreateProcess function. | 
|---|
| 1326 | ------------------------------------------------------------------} | 
|---|
| 1327 | function ProcessExecute(Command: string; cShow: Word): Integer; | 
|---|
| 1328 | { This method encapsulates the call to CreateProcess() which creates | 
|---|
| 1329 | a new process and its primary thread. This is the method used in | 
|---|
| 1330 | Win32 to execute another application, This method requires the use | 
|---|
| 1331 | of the TStartInfo and TProcessInformation structures. These structures | 
|---|
| 1332 | are not documented as part of the Delphi 2.0 online help but rather | 
|---|
| 1333 | the Win32 help as STARTUPINFO and PROCESS_INFORMATION. | 
|---|
| 1334 |  | 
|---|
| 1335 | The CommandLine paremeter specifies the pathname of the file to | 
|---|
| 1336 | execute. | 
|---|
| 1337 |  | 
|---|
| 1338 | The cShow paremeter specifies one of the SW_XXXX constants which | 
|---|
| 1339 | specifies how to display the window. This value is assigned to the | 
|---|
| 1340 | sShowWindow field of the TStartupInfo structure. } | 
|---|
| 1341 | var | 
|---|
| 1342 | Rslt: LongBool; | 
|---|
| 1343 | StartUpInfo: TStartUpInfo;  // documented as STARTUPINFO | 
|---|
| 1344 | ProcessInfo: TProcessInformation; // documented as PROCESS_INFORMATION | 
|---|
| 1345 | begin | 
|---|
| 1346 | { Clear the StartupInfo structure } | 
|---|
| 1347 | FillChar(StartupInfo, SizeOf(TStartupInfo), 0); | 
|---|
| 1348 | { Initialize the StartupInfo structure with required data. | 
|---|
| 1349 | Here, we assign the SW_XXXX constant to the wShowWindow field | 
|---|
| 1350 | of StartupInfo. When specifing a value to this field the | 
|---|
| 1351 | STARTF_USESSHOWWINDOW flag must be set in the dwFlags field. | 
|---|
| 1352 | Additional information on the TStartupInfo is provided in the Win32 | 
|---|
| 1353 | online help under STARTUPINFO. } | 
|---|
| 1354 | with StartupInfo do begin | 
|---|
| 1355 | cb := SizeOf(TStartupInfo); // Specify size of structure | 
|---|
| 1356 | dwFlags := STARTF_USESHOWWINDOW or STARTF_FORCEONFEEDBACK; | 
|---|
| 1357 | wShowWindow := cShow | 
|---|
| 1358 | end; | 
|---|
| 1359 |  | 
|---|
| 1360 | { Create the process by calling CreateProcess(). This function | 
|---|
| 1361 | fills the ProcessInfo structure with information about the new | 
|---|
| 1362 | process and its primary thread. Detailed information is provided | 
|---|
| 1363 | in the Win32 online help for the TProcessInfo structure under | 
|---|
| 1364 | PROCESS_INFORMATION. } | 
|---|
| 1365 | Rslt := CreateProcess(PChar(Command), nil, nil, nil, False, | 
|---|
| 1366 | NORMAL_PRIORITY_CLASS, nil, nil, StartupInfo, ProcessInfo); | 
|---|
| 1367 | { If Rslt is true, then the CreateProcess call was successful. | 
|---|
| 1368 | Otherwise, GetLastError will return an error code representing the | 
|---|
| 1369 | error which occurred. } | 
|---|
| 1370 | if Rslt then | 
|---|
| 1371 | with ProcessInfo do begin | 
|---|
| 1372 | { Wait until the process is in idle. } | 
|---|
| 1373 | WaitForInputIdle(hProcess, INFINITE); | 
|---|
| 1374 | CloseHandle(hThread); // Free the hThread  handle | 
|---|
| 1375 | CloseHandle(hProcess);// Free the hProcess handle | 
|---|
| 1376 | Result := 0;          // Set Result to 0, meaning successful | 
|---|
| 1377 | end | 
|---|
| 1378 | else Result := GetLastError; // Set result to the error code. | 
|---|
| 1379 | end; | 
|---|
| 1380 |  | 
|---|
| 1381 |  | 
|---|
| 1382 | {----------------------- GetAppHandle -------------------------- | 
|---|
| 1383 | Library function to return an Application Handle from the server | 
|---|
| 1384 | which can be passed as a command line argument to an application | 
|---|
| 1385 | the current application is starting.  The new application can use | 
|---|
| 1386 | this AppHandle to perform a silent login via the lmAppHandle mode | 
|---|
| 1387 | ----------------------------------------------------------------} | 
|---|
| 1388 | function  GetAppHandle(ConnectedBroker : TRPCBroker): String;   // p13 | 
|---|
| 1389 | begin | 
|---|
| 1390 | Result := ''; | 
|---|
| 1391 | with ConnectedBroker do | 
|---|
| 1392 | begin | 
|---|
| 1393 | RemoteProcedure := 'XUS GET TOKEN'; | 
|---|
| 1394 | Call; | 
|---|
| 1395 | Result := Results[0]; | 
|---|
| 1396 | end; | 
|---|
| 1397 | end; | 
|---|
| 1398 |  | 
|---|
| 1399 | {----------------------- TRPCBroker.DoPulseOnTimer----------------- | 
|---|
| 1400 | Called from the OnTimer event of the Pulse property. | 
|---|
| 1401 | Broker environment should be the same after the procedure as before. | 
|---|
| 1402 | Note: Results is not changed by strCall; so, Results needn't be saved. | 
|---|
| 1403 | ------------------------------------------------------------------} | 
|---|
| 1404 | procedure TRPCBroker.DoPulseOnTimer(Sender: TObject);  //P6 | 
|---|
| 1405 | var | 
|---|
| 1406 | SaveClearParameters : Boolean; | 
|---|
| 1407 | SaveParam : TParams; | 
|---|
| 1408 | SaveRemoteProcedure, SaveRPCVersion : string; | 
|---|
| 1409 | begin | 
|---|
| 1410 | SaveClearParameters := ClearParameters;  //Save existing properties | 
|---|
| 1411 | SaveParam := TParams.Create(nil); | 
|---|
| 1412 | SaveParam.Assign(Param); | 
|---|
| 1413 | SaveRemoteProcedure := RemoteProcedure; | 
|---|
| 1414 | SaveRPCVersion      := RPCVersion; | 
|---|
| 1415 | RemoteProcedure := 'XWB IM HERE';       //Set Properties for IM HERE | 
|---|
| 1416 | ClearParameters  := True;               //Erase existing PARAMs | 
|---|
| 1417 | RPCVersion      := '1.106'; | 
|---|
| 1418 | try | 
|---|
| 1419 | try | 
|---|
| 1420 | strCall;                                //Make the call | 
|---|
| 1421 | except on e: EBrokerError do | 
|---|
| 1422 | begin | 
|---|
| 1423 | //        Connected := False;                // set the connection as disconnected | 
|---|
| 1424 | if Assigned(FOnPulseError) then | 
|---|
| 1425 | FOnPulseError(Self, e.Message) | 
|---|
| 1426 | else | 
|---|
| 1427 | raise e; | 
|---|
| 1428 | end; | 
|---|
| 1429 | end; | 
|---|
| 1430 | finally | 
|---|
| 1431 | ClearParameters := SaveClearParameters;  //Restore pre-existing properties. | 
|---|
| 1432 | Param.Assign(SaveParam); | 
|---|
| 1433 | SaveParam.Free; | 
|---|
| 1434 | RemoteProcedure := SaveRemoteProcedure; | 
|---|
| 1435 | RPCVersion      := SaveRPCVersion; | 
|---|
| 1436 | end; | 
|---|
| 1437 |  | 
|---|
| 1438 | end; | 
|---|
| 1439 |  | 
|---|
| 1440 | procedure TRPCBroker.SetKernelLogIn(const Value: Boolean);   // p13 | 
|---|
| 1441 | begin | 
|---|
| 1442 | FKernelLogIn := Value; | 
|---|
| 1443 | end; | 
|---|
| 1444 | { | 
|---|
| 1445 | procedure TRPCBroker.SetLogIn(const Value: TVistaLogIn);     // p13 | 
|---|
| 1446 | begin | 
|---|
| 1447 | FLogIn := Value; | 
|---|
| 1448 | end; | 
|---|
| 1449 | } | 
|---|
| 1450 | procedure TRPCBroker.SetUser(const Value: TVistaUser);       // p13 | 
|---|
| 1451 | begin | 
|---|
| 1452 | FUser := Value; | 
|---|
| 1453 | end; | 
|---|
| 1454 |  | 
|---|
| 1455 |  | 
|---|
| 1456 | {*****TVistaLogin***** p13} | 
|---|
| 1457 |  | 
|---|
| 1458 | constructor TVistaLogin.Create(AOwner: TComponent);           // p13 | 
|---|
| 1459 | begin | 
|---|
| 1460 | inherited create; | 
|---|
| 1461 | FDivLst := TStringList.Create; | 
|---|
| 1462 | end; | 
|---|
| 1463 |  | 
|---|
| 1464 | destructor TVistaLogin.Destroy;                              // p13 | 
|---|
| 1465 | begin | 
|---|
| 1466 | FDivLst.Free; | 
|---|
| 1467 | FDivLst := nil; | 
|---|
| 1468 | inherited; | 
|---|
| 1469 | end; | 
|---|
| 1470 |  | 
|---|
| 1471 | procedure TVistaLogin.FailedLogin(Sender: TObject);         // p13 | 
|---|
| 1472 | begin | 
|---|
| 1473 | if Assigned(FOnFailedLogin) then FOnFailedLogin(Self) | 
|---|
| 1474 | else  TXWBWinsock(TRPCBroker(Sender).XWBWinsock).NetError('',XWB_BadSignOn); | 
|---|
| 1475 | end; | 
|---|
| 1476 |  | 
|---|
| 1477 | procedure TVistaLogin.SetAccessCode(const Value: String);   // p13 | 
|---|
| 1478 | begin | 
|---|
| 1479 | FAccessCode := Value; | 
|---|
| 1480 | end; | 
|---|
| 1481 |  | 
|---|
| 1482 | procedure TVistaLogin.SetDivision(const Value: String);     // p13 | 
|---|
| 1483 | begin | 
|---|
| 1484 | FDivision := Value; | 
|---|
| 1485 | end; | 
|---|
| 1486 |  | 
|---|
| 1487 | procedure TVistaLogin.SetDuz(const Value: string);          // p13 | 
|---|
| 1488 | begin | 
|---|
| 1489 | FDUZ := Value; | 
|---|
| 1490 | end; | 
|---|
| 1491 |  | 
|---|
| 1492 | procedure TVistaLogin.SetErrorText(const Value: string);    // p13 | 
|---|
| 1493 | begin | 
|---|
| 1494 | FErrorText := Value; | 
|---|
| 1495 | end; | 
|---|
| 1496 |  | 
|---|
| 1497 | procedure TVistaLogin.SetLogInHandle(const Value: String);   // p13 | 
|---|
| 1498 | begin | 
|---|
| 1499 | FLogInHandle := Value; | 
|---|
| 1500 | end; | 
|---|
| 1501 |  | 
|---|
| 1502 | procedure TVistaLogin.SetMode(const Value: TLoginMode);      // p13 | 
|---|
| 1503 | begin | 
|---|
| 1504 | FMode := Value; | 
|---|
| 1505 | end; | 
|---|
| 1506 |  | 
|---|
| 1507 | procedure TVistaLogin.SetMultiDivision(Value: Boolean);      // p13 | 
|---|
| 1508 | begin | 
|---|
| 1509 | FMultiDivision := Value; | 
|---|
| 1510 | end; | 
|---|
| 1511 |  | 
|---|
| 1512 | procedure TVistaLogin.SetNTToken(const Value: String);       // p13 | 
|---|
| 1513 | begin | 
|---|
| 1514 | end; | 
|---|
| 1515 |  | 
|---|
| 1516 | procedure TVistaLogin.SetPromptDiv(const Value: boolean);    // p13 | 
|---|
| 1517 | begin | 
|---|
| 1518 | FPromptDiv := Value; | 
|---|
| 1519 | end; | 
|---|
| 1520 |  | 
|---|
| 1521 | procedure TVistaLogin.SetVerifyCode(const Value: String);    // p13 | 
|---|
| 1522 | begin | 
|---|
| 1523 | FVerifyCode := Value; | 
|---|
| 1524 | end; | 
|---|
| 1525 |  | 
|---|
| 1526 | {***** TVistaUser ***** p13 } | 
|---|
| 1527 |  | 
|---|
| 1528 | procedure TVistaUser.SetDivision(const Value: String);       // p13 | 
|---|
| 1529 | begin | 
|---|
| 1530 | FDivision := Value; | 
|---|
| 1531 | end; | 
|---|
| 1532 |  | 
|---|
| 1533 | procedure TVistaUser.SetDTime(const Value: string);          // p13 | 
|---|
| 1534 | begin | 
|---|
| 1535 | FDTime := Value; | 
|---|
| 1536 | end; | 
|---|
| 1537 |  | 
|---|
| 1538 | procedure TVistaUser.SetDUZ(const Value: String);             // p13 | 
|---|
| 1539 | begin | 
|---|
| 1540 | FDUZ := Value; | 
|---|
| 1541 | end; | 
|---|
| 1542 |  | 
|---|
| 1543 | procedure TVistaUser.SetLanguage(const Value: string);       // p13 | 
|---|
| 1544 | begin | 
|---|
| 1545 | FLanguage := Value; | 
|---|
| 1546 | end; | 
|---|
| 1547 |  | 
|---|
| 1548 | procedure TVistaUser.SetName(const Value: String);           // p13 | 
|---|
| 1549 | begin | 
|---|
| 1550 | FName := Value; | 
|---|
| 1551 | end; | 
|---|
| 1552 |  | 
|---|
| 1553 | procedure TVistaUser.SetServiceSection(const Value: string);  // p13 | 
|---|
| 1554 | begin | 
|---|
| 1555 | FServiceSection := Value; | 
|---|
| 1556 | end; | 
|---|
| 1557 |  | 
|---|
| 1558 | procedure TVistaUser.SetStandardName(const Value: String);    // p13 | 
|---|
| 1559 | begin | 
|---|
| 1560 | FStandardName := Value; | 
|---|
| 1561 | end; | 
|---|
| 1562 |  | 
|---|
| 1563 | procedure TVistaUser.SetTitle(const Value: string);           // p13 | 
|---|
| 1564 | begin | 
|---|
| 1565 | FTitle := Value; | 
|---|
| 1566 | end; | 
|---|
| 1567 |  | 
|---|
| 1568 | procedure TVistaUser.SetVerifyCodeChngd(const Value: Boolean);   // p13 | 
|---|
| 1569 | begin | 
|---|
| 1570 | FVerifyCodeChngd := Value; | 
|---|
| 1571 | end; | 
|---|
| 1572 |  | 
|---|
| 1573 | Function ShowApplicationAndFocusOK(anApplication: TApplication): boolean; | 
|---|
| 1574 | var | 
|---|
| 1575 | j: integer; | 
|---|
| 1576 | Stat2: set of (sWinVisForm,sWinVisApp,sIconized); | 
|---|
| 1577 | hFGWnd: THandle; | 
|---|
| 1578 | begin | 
|---|
| 1579 | Stat2 := []; {sWinVisForm,sWinVisApp,sIconized} | 
|---|
| 1580 |  | 
|---|
| 1581 | If anApplication.MainForm <> nil then | 
|---|
| 1582 | If IsWindowVisible(anApplication.MainForm.Handle) | 
|---|
| 1583 | then Stat2 := Stat2 + [sWinVisForm]; | 
|---|
| 1584 |  | 
|---|
| 1585 | If IsWindowVisible(anApplication.Handle) | 
|---|
| 1586 | then Stat2 := Stat2 + [sWinVisApp]; | 
|---|
| 1587 |  | 
|---|
| 1588 | If IsIconic(anApplication.Handle) | 
|---|
| 1589 | then Stat2 := Stat2 + [sIconized]; | 
|---|
| 1590 |  | 
|---|
| 1591 | Result := true; | 
|---|
| 1592 | If sIconized in Stat2 then begin {A} | 
|---|
| 1593 | j := SendMessage(anApplication.Handle,WM_SYSCOMMAND,SC_RESTORE,0); | 
|---|
| 1594 | Result := j<>0; | 
|---|
| 1595 | end; | 
|---|
| 1596 | If Stat2 * [sWinVisForm,sIconized] = [] then begin {S} | 
|---|
| 1597 | if anApplication.MainForm <> nil then | 
|---|
| 1598 | anApplication.MainForm.Show; | 
|---|
| 1599 | end; | 
|---|
| 1600 | If (Stat2 * [sWinVisForm,sIconized] <> []) or | 
|---|
| 1601 | (sWinVisApp in Stat2) then begin {G} | 
|---|
| 1602 | {$IFNDEF D6_OR_HIGHER} | 
|---|
| 1603 | hFGWnd := GetForegroundWindow; | 
|---|
| 1604 | try | 
|---|
| 1605 | AttachThreadInput( | 
|---|
| 1606 | GetWindowThreadProcessId(hFGWnd, nil), | 
|---|
| 1607 | GetCurrentThreadId,True); | 
|---|
| 1608 | Result := SetForegroundWindow(anApplication.Handle); | 
|---|
| 1609 | finally | 
|---|
| 1610 | AttachThreadInput( | 
|---|
| 1611 | GetWindowThreadProcessId(hFGWnd, nil), | 
|---|
| 1612 | GetCurrentThreadId, False); | 
|---|
| 1613 | end; | 
|---|
| 1614 | {$ENDIF} | 
|---|
| 1615 | end; | 
|---|
| 1616 | end; | 
|---|
| 1617 |  | 
|---|
| 1618 | end. | 
|---|
| 1619 |  | 
|---|