ViewVC Help
View File | Revision Log | Show Annotations | Download File | View Changeset | Root Listing
root/public/ibx/trunk/runtime/IBServices.pas
(Generate patch)

Comparing ibx/trunk/runtime/IBServices.pas (file contents):
Revision 31 by tony, Tue Jul 14 15:31:25 2015 UTC vs.
Revision 143 by tony, Fri Feb 23 12:11:21 2018 UTC

# Line 1 | Line 1
1 < {************************************************************************}
2 < {                                                                        }
3 < {       Borland Delphi Visual Component Library                          }
4 < {       InterBase Express core components                                }
5 < {                                                                        }
6 < {       Copyright (c) 1998-2000 Inprise Corporation                      }
7 < {                                                                        }
8 < {    InterBase Express is based in part on the product                   }
9 < {    Free IB Components, written by Gregory H. Deatz for                 }
10 < {    Hoagland, Longo, Moran, Dunst & Doukas Company.                     }
11 < {    Free IB Components is used under license.                           }
12 < {                                                                        }
13 < {    The contents of this file are subject to the InterBase              }
14 < {    Public License Version 1.0 (the "License"); you may not             }
15 < {    use this file except in compliance with the License. You            }
16 < {    may obtain a copy of the License at http://www.Inprise.com/IPL.html }
17 < {    Software distributed under the License is distributed on            }
18 < {    an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either              }
19 < {    express or implied. See the License for the specific language       }
20 < {    governing rights and limitations under the License.                 }
21 < {    The Original Code was created by InterBase Software Corporation     }
22 < {       and its successors.                                              }
23 < {    Portions created by Inprise Corporation are Copyright (C) Inprise   }
24 < {       Corporation. All Rights Reserved.                                }
25 < {    Contributor(s): Jeff Overcash                                       }
26 < {                                                                        }
27 < {    IBX For Lazarus (Firebird Express)                                  }
28 < {    Contributor: Tony Whyman, MWA Software http://www.mwasoftware.co.uk }
29 < {    Portions created by MWA Software are copyright McCallum Whyman      }
30 < {    Associates Ltd 2011                                                 }
31 < {                                                                        }
32 < {************************************************************************}
33 <
34 < {
35 <  InterBase Express provides component interfaces to
36 <  functions introduced in InterBase 6.0.  The Services
37 <  components (TIB*Service, TIBServerProperties)
38 <  function only if you have installed InterBase 6.0 or
39 <  later software, including Firebird
40 < }
41 <
42 < unit IBServices;
43 <
44 < {$Mode Delphi}
45 <
46 < interface
47 <
48 < uses
49 < {$IFDEF WINDOWS }
50 <  Windows,
51 < {$ELSE}
52 <  unix,
53 < {$ENDIF}
54 <  SysUtils, Classes, IBHeader, IB, IBExternals, CustApp;
55 <
56 < const
57 <  DefaultBufferSize = 32000;
58 <
59 <  SPBPrefix = 'isc_spb_';
60 <  SPBConstantNames: array[1..isc_spb_last_spb_constant] of String = (
61 <    'user_name',
62 <    'sys_user_name',
63 <    'sys_user_name_enc',
64 <    'password',
65 <    'password_enc',
66 <    'command_line',
67 <    'db_name',
68 <    'verbose',
69 <    'options',
70 <    'connect_timeout',
71 <    'dummy_packet_interval',
72 <    'sql_role_name'
73 <  );
74 <
75 <  SPBConstantValues: array[1..isc_spb_last_spb_constant] of Integer = (
76 <    isc_spb_user_name_mapped_to_server,
77 <    isc_spb_sys_user_name_mapped_to_server,
78 <    isc_spb_sys_user_name_enc_mapped_to_server,
79 <    isc_spb_password_mapped_to_server,
80 <    isc_spb_password_enc_mapped_to_server,
81 <    isc_spb_command_line_mapped_to_server,
82 <    isc_spb_dbname_mapped_to_server,
83 <    isc_spb_verbose_mapped_to_server,
84 <    isc_spb_options_mapped_to_server,
85 <    isc_spb_connect_timeout_mapped_to_server,
86 <    isc_spb_dummy_packet_interval_mapped_to_server,
87 <    isc_spb_sql_role_name_mapped_to_server
88 <  );
89 <
90 < type
91 <  TProtocol = (TCP, SPX, NamedPipe, Local);
92 <  TOutputBufferOption = (ByLine, ByChunk);
93 <
94 <  TIBCustomService = class;
95 <
96 <  TLoginEvent = procedure(Database: TIBCustomService;
97 <    LoginParams: TStrings) of object;
98 <
99 <  { TIBCustomService }
100 <
101 <  TIBCustomService = class(TComponent)
102 <  private
103 <    FIBLoaded: Boolean;
104 <    FParamsChanged : Boolean;
105 <    FSPB, FQuerySPB : PChar;
106 <    FSPBLength, FQuerySPBLength : Short;
107 <    FTraceFlags: TTraceFlags;
108 <    FOnLogin: TLoginEvent;
109 <    FLoginPrompt: Boolean;
110 <    FBufferSize: Integer;
111 <    FOutputBuffer: PChar;
112 <    FQueryParams: String;
113 <    FServerName: string;
114 <    FHandle: TISC_SVC_HANDLE;
115 <    FStreamedActive  : Boolean;
116 <    FOnAttach: TNotifyEvent;
117 <    FOutputBufferOption: TOutputBufferOption;
118 <    FProtocol: TProtocol;
119 <    FParams: TStrings;
120 <    function GetActive: Boolean;
121 <    function GetServiceParamBySPB(const Idx: Integer): String;
122 <    procedure SetActive(const Value: Boolean);
123 <    procedure SetBufferSize(const Value: Integer);
124 <    procedure SetParams(const Value: TStrings);
125 <    procedure SetServerName(const Value: string);
126 <    procedure SetProtocol(const Value: TProtocol);
127 <    procedure SetServiceParamBySPB(const Idx: Integer;
128 <      const Value: String);
129 <    function IndexOfSPBConst(st: String): Integer;
130 <    procedure ParamsChange(Sender: TObject);
131 <    procedure ParamsChanging(Sender: TObject);
132 <    procedure CheckServerName;
133 <    function Call(ErrCode: ISC_STATUS; RaiseError: Boolean): ISC_STATUS;
134 <    function ParseString(var RunLen: Integer): string;
135 <    function ParseInteger(var RunLen: Integer): Integer;
136 <    procedure GenerateSPB(sl: TStrings; var SPB: String; var SPBLength: Short);
137 <
138 <  protected
139 <    procedure Loaded; override;
140 <    function Login: Boolean;
141 <    procedure CheckActive;
142 <    procedure CheckInactive;
143 <    procedure HandleException(Sender: TObject);
144 <    property OutputBuffer : PChar read FOutputBuffer;
145 <    property OutputBufferOption : TOutputBufferOption read FOutputBufferOption write FOutputBufferOption;
146 <    property BufferSize : Integer read FBufferSize write SetBufferSize default DefaultBufferSize;
147 <    procedure InternalServiceQuery;
148 <    property ServiceQueryParams: String read FQueryParams write FQueryParams;
149 <
150 <  public
151 <    constructor Create(AOwner: TComponent); override;
152 <    destructor Destroy; override;
153 <    procedure Attach;
154 <    procedure Detach;
155 <    property Handle: TISC_SVC_HANDLE read FHandle;
156 <    property ServiceParamBySPB[const Idx: Integer]: String read GetServiceParamBySPB
157 <                                                      write SetServiceParamBySPB;
158 <  published
159 <    property Active: Boolean read GetActive write SetActive default False;
160 <    property ServerName: string read FServerName write SetServerName;
161 <    property Protocol: TProtocol read FProtocol write SetProtocol default Local;
162 <    property Params: TStrings read FParams write SetParams;
163 <    property LoginPrompt: Boolean read FLoginPrompt write FLoginPrompt default True;
164 <    property TraceFlags: TTraceFlags read FTraceFlags write FTraceFlags;
165 <    property OnAttach: TNotifyEvent read FOnAttach write FOnAttach;
166 <    property OnLogin: TLoginEvent read FOnLogin write FOnLogin;
167 <  end;
168 <
169 <  TDatabaseInfo = class
170 <  public
171 <    NoOfAttachments: Integer;
172 <    NoOfDatabases: Integer;
173 <    DbName: array of string;
174 <    constructor Create;
175 <    destructor Destroy; override;
176 <  end;
177 <
178 <  TLicenseInfo = class
179 <  public
180 <    Key: array of string;
181 <    Id: array of string;
182 <    Desc: array of string;
183 <    LicensedUsers: Integer;
184 <    constructor Create;
185 <    destructor Destroy; override;
186 <  end;
187 <
188 <  TLicenseMaskInfo = class
189 <  public
190 <    LicenseMask: Integer;
191 <    CapabilityMask: Integer;
192 <  end;
193 <
194 <  TConfigFileData = class
195 <  public
196 <    ConfigFileValue: array of integer;
197 <    ConfigFileKey: array of integer;
198 <    constructor Create;
199 <    destructor Destroy; override;
200 <  end;
201 <
202 <  TConfigParams = class
203 <  public
204 <    ConfigFileData: TConfigFileData;
205 <    ConfigFileParams: array of string;
206 <    BaseLocation: string;
207 <    LockFileLocation: string;
208 <    MessageFileLocation: string;
209 <    SecurityDatabaseLocation: string;
210 <    constructor Create;
211 <    destructor Destroy; override;
212 <  end;
213 <
214 <  TVersionInfo = class
215 <    ServerVersion: String;
216 <    ServerImplementation: string;
217 <    ServiceVersion: Integer;
218 <  end;
219 <
220 <  TPropertyOption = (Database, License, LicenseMask, ConfigParameters, Version);
221 <  TPropertyOptions = set of TPropertyOption;
222 <
223 <  TIBServerProperties = class(TIBCustomService)
224 <  private
225 <    FOptions: TPropertyOptions;
226 <    FDatabaseInfo: TDatabaseInfo;
227 <    FLicenseInfo: TLicenseInfo;
228 <    FLicenseMaskInfo: TLicenseMaskInfo;
229 <    FVersionInfo: TVersionInfo;
230 <    FConfigParams: TConfigParams;
231 <    procedure ParseConfigFileData(var RunLen: Integer);
232 <  public
233 <    constructor Create(AOwner: TComponent); override;
234 <    destructor Destroy; override;
235 <    procedure Fetch;
236 <    procedure FetchDatabaseInfo;
237 <    procedure FetchLicenseInfo;
238 <    procedure FetchLicenseMaskInfo;
239 <    procedure FetchConfigParams;
240 <    procedure FetchVersionInfo;
241 <    property DatabaseInfo: TDatabaseInfo read FDatabaseInfo;
242 <    property LicenseInfo: TLicenseInfo read FLicenseInfo;
243 <    property LicenseMaskInfo: TLicenseMaskInfo read FLicenseMaskInfo;
244 <    property VersionInfo: TVersionInfo read FVersionInfo;
245 <    property ConfigParams: TConfigParams read FConfigParams;
246 <  published
247 <    property Options : TPropertyOptions read FOptions write FOptions;
248 <  end;
249 <
250 <  TIBControlService = class (TIBCustomService)
251 <  private
252 <    FStartParams: String;
253 <    FStartSPB: PChar;
254 <    FStartSPBLength: Integer;
255 <    function GetIsServiceRunning: Boolean;
256 <  protected
257 <    property ServiceStartParams: String read FStartParams write FStartParams;
258 <    procedure SetServiceStartOptions; virtual;
259 <    procedure ServiceStartAddParam (Value: string; param: Integer); overload;
260 <    procedure ServiceStartAddParam (Value: Integer; param: Integer); overload;
261 <    procedure InternalServiceStart;
262 <
263 <  public
264 <    constructor Create(AOwner: TComponent); override;
265 <    procedure ServiceStart; virtual;
266 <    property IsServiceRunning : Boolean read GetIsServiceRunning;
267 <  end;
268 <
269 <  TIBControlAndQueryService = class (TIBControlService)
270 <  private
271 <    FEof: Boolean;
272 <    FAction: Integer;
273 <    procedure SetAction(Value: Integer);
274 <  protected
275 <    property Action: Integer read FAction write SetAction;
276 <  public
277 <    constructor create (AOwner: TComponent); override;
278 <    function GetNextLine : String;
279 <    function GetNextChunk : String;
280 <    property Eof: boolean read FEof;
281 <  published
282 <    property BufferSize;
283 <  end;
284 <
285 <  TShutdownMode = (Forced, DenyTransaction, DenyAttachment);
286 <
287 <  TIBConfigService = class(TIBControlService)
288 <  private
289 <    FDatabaseName: string;
290 <    procedure SetDatabaseName(const Value: string);
291 <  protected
292 <
293 <  public
294 <    procedure ServiceStart; override;
295 <    procedure ShutdownDatabase (Options: TShutdownMode; Wait: Integer);
296 <    procedure SetSweepInterval (Value: Integer);
297 <    procedure SetDBSqlDialect (Value: Integer);
298 <    procedure SetPageBuffers (Value: Integer);
299 <    procedure ActivateShadow;
300 <    procedure BringDatabaseOnline;
301 <    procedure SetReserveSpace (Value: Boolean);
302 <    procedure SetAsyncMode (Value: Boolean);
303 <    procedure SetReadOnly (Value: Boolean);
304 <  published
305 <    property DatabaseName: string read FDatabaseName write SetDatabaseName;
306 <  end;
307 <
308 <  TIBLogService = class(TIBControlAndQueryService)
309 <  private
310 <
311 <  protected
312 <    procedure SetServiceStartOptions; override;
313 <  public
314 <  published
315 <  end;
316 <
317 <  TStatOption = (DataPages, DbLog, HeaderPages, IndexPages, SystemRelations);
318 <  TStatOptions = set of TStatOption;
319 <
320 <  TIBStatisticalService = class(TIBControlAndQueryService)
321 <  private
322 <    FDatabaseName: string;
323 <    FOptions: TStatOptions;
324 <    procedure SetDatabaseName(const Value: string);
325 <  protected
326 <    procedure SetServiceStartOptions; override;
327 <  public
328 <  published
329 <    property DatabaseName: string read FDatabaseName write SetDatabaseName;
330 <    property Options :  TStatOptions read FOptions write FOptions;
331 <  end;
332 <
333 <
334 <  TIBBackupRestoreService = class(TIBControlAndQueryService)
335 <  private
336 <    FVerbose: Boolean;
337 <  protected
338 <  public
339 <  published
340 <    property Verbose : Boolean read FVerbose write FVerbose default False;
341 <  end;
342 <
343 <  TBackupOption = (IgnoreChecksums, IgnoreLimbo, MetadataOnly, NoGarbageCollection,
344 <    OldMetadataDesc, NonTransportable, ConvertExtTables);
345 <  TBackupOptions = set of TBackupOption;
346 <
347 <  TIBBackupService = class (TIBBackupRestoreService)
348 <  private
349 <    FDatabaseName: string;
350 <    FOptions: TBackupOptions;
351 <    FBackupFile: TStrings;
352 <    FBlockingFactor: Integer;
353 <    procedure SetBackupFile(const Value: TStrings);
354 <  protected
355 <    procedure SetServiceStartOptions; override;
356 <  public
357 <    constructor Create(AOwner: TComponent); override;
358 <    destructor Destroy; override;
359 <
360 <  published
361 <    { a name=value pair of filename and length }
362 <    property BackupFile: TStrings read FBackupFile write SetBackupFile;
363 <    property BlockingFactor: Integer read FBlockingFactor write FBlockingFactor;
364 <    property DatabaseName: string read FDatabaseName write FDatabaseName;
365 <    property Options : TBackupOptions read FOptions write FOptions;
366 <  end;
367 <
368 <  TRestoreOption = (DeactivateIndexes, NoShadow, NoValidityCheck, OneRelationAtATime,
369 <    Replace, CreateNewDB, UseAllSpace);
370 <
371 <  TRestoreOptions = set of TRestoreOption;
372 <  TIBRestoreService = class (TIBBackupRestoreService)
373 <  private
374 <    FDatabaseName: TStrings;
375 <    FBackupFile: TStrings;
376 <    FOptions: TRestoreOptions;
377 <    FPageSize: Integer;
378 <    FPageBuffers: Integer;
379 <    procedure SetBackupFile(const Value: TStrings);
380 <    procedure SetDatabaseName(const Value: TStrings);
381 <  protected
382 <    procedure SetServiceStartOptions; override;
383 <  public
384 <    constructor Create(AOwner: TComponent); override;
385 <    destructor Destroy; override;
386 <  published
387 <    { a name=value pair of filename and length }
388 <    property DatabaseName: TStrings read FDatabaseName write SetDatabaseName;
389 <    property BackupFile: TStrings read FBackupFile write SetBackupFile;
390 <    property PageSize: Integer read FPageSize write FPageSize;
391 <    property PageBuffers: Integer read FPageBuffers write FPageBuffers;
392 <    property Options : TRestoreOptions read FOptions write FOptions default [CreateNewDB];
393 <  end;
394 <
395 <  TValidateOption = (LimboTransactions, CheckDB, IgnoreChecksum, KillShadows, MendDB,
396 <    SweepDB, ValidateDB, ValidateFull);
397 <  TValidateOptions = set of TValidateOption;
398 <
399 <  TTransactionGlobalAction = (CommitGlobal, RollbackGlobal, RecoverTwoPhaseGlobal,
400 <                             NoGlobalAction);
401 <  TTransactionState = (LimboState, CommitState, RollbackState, UnknownState);
402 <  TTransactionAdvise = (CommitAdvise, RollbackAdvise, UnknownAdvise);
403 <  TTransactionAction = (CommitAction, RollbackAction);
404 <
405 <  TLimboTransactionInfo = class
406 <  public
407 <    MultiDatabase: Boolean;
408 <    ID: Integer;
409 <    HostSite: String;
410 <    RemoteSite: String;
411 <    RemoteDatabasePath: String;
412 <    State: TTransactionState;
413 <    Advise: TTransactionAdvise;
414 <    Action: TTransactionAction;
415 <  end;
416 <
417 <  TIBValidationService = class(TIBControlAndQueryService)
418 <  private
419 <    FDatabaseName: string;
420 <    FOptions: TValidateOptions;
421 <    FLimboTransactionInfo: array of TLimboTransactionInfo;
422 <    FGlobalAction: TTransactionGlobalAction;
423 <    procedure SetDatabaseName(const Value: string);
424 <    function GetLimboTransactionInfo(index: integer): TLimboTransactionInfo;
425 <    function GetLimboTransactionInfoCount: integer;
426 <
427 <  protected
428 <    procedure SetServiceStartOptions; override;
429 <  public
430 <    constructor Create(AOwner: TComponent); override;
431 <    destructor Destroy; override;
432 <    procedure FetchLimboTransactionInfo;
433 <    procedure FixLimboTransactionErrors;
434 <    property LimboTransactionInfo[Index: integer]: TLimboTransactionInfo read GetLimboTransactionInfo;
435 <    property LimboTransactionInfoCount: Integer read GetLimboTransactionInfoCount;
436 <
437 <  published
438 <    property DatabaseName: string read FDatabaseName write SetDatabaseName;
439 <    property Options: TValidateOptions read FOptions write FOptions;
440 <    property GlobalAction: TTransactionGlobalAction read FGlobalAction
441 <                                         write FGlobalAction;
442 <  end;
443 <
444 <  TUserInfo = class
445 <  public
446 <    UserName: string;
447 <    FirstName: string;
448 <    MiddleName: string;
449 <    LastName: string;
450 <    GroupID: Integer;
451 <    UserID: Integer;
452 <  end;
453 <
454 <  TSecurityAction = (ActionAddUser, ActionDeleteUser, ActionModifyUser, ActionDisplayUser);
455 <  TSecurityModifyParam = (ModifyFirstName, ModifyMiddleName, ModifyLastName, ModifyUserId,
456 <                         ModifyGroupId, ModifyPassword);
457 <  TSecurityModifyParams = set of TSecurityModifyParam;
458 <
459 <  TIBSecurityService = class(TIBControlAndQueryService)
460 <  private
461 <    FUserID: Integer;
462 <    FGroupID: Integer;
463 <    FFirstName: string;
464 <    FUserName: string;
465 <    FPassword: string;
466 <    FSQLRole: string;
467 <    FLastName: string;
468 <    FMiddleName: string;
469 <    FUserInfo: array of TUserInfo;
470 <    FSecurityAction: TSecurityAction;
471 <    FModifyParams: TSecurityModifyParams;
472 <    procedure ClearParams;
473 <    procedure SetSecurityAction (Value: TSecurityAction);
474 <    procedure SetFirstName (Value: String);
475 <    procedure SetMiddleName (Value: String);
476 <    procedure SetLastName (Value: String);
477 <    procedure SetPassword (Value: String);
478 <    procedure SetUserId (Value: Integer);
479 <    procedure SetGroupId (Value: Integer);
480 <
481 <    procedure FetchUserInfo;
482 <    function GetUserInfo(Index: Integer): TUserInfo;
483 <    function GetUserInfoCount: Integer;
484 <
485 <  protected
486 <    procedure Loaded; override;
487 <    procedure SetServiceStartOptions; override;
488 <  public
489 <    constructor Create(AOwner: TComponent); override;
490 <    destructor Destroy; override;
491 <    procedure DisplayUsers;
492 <    procedure DisplayUser(UserName: string);
493 <    procedure AddUser;
494 <    procedure DeleteUser;
495 <    procedure ModifyUser;
496 <    property  UserInfo[Index: Integer]: TUserInfo read GetUserInfo;
497 <    property  UserInfoCount: Integer read GetUserInfoCount;
498 <
499 <  published
500 <    property SecurityAction: TSecurityAction read FSecurityAction
501 <                                             write SetSecurityAction;
502 <    property SQlRole : string read FSQLRole write FSQLrole;
503 <    property UserName : string read FUserName write FUserName;
504 <    property FirstName : string read FFirstName write SetFirstName;
505 <    property MiddleName : string read FMiddleName write SetMiddleName;
506 <    property LastName : string read FLastName write SetLastName;
507 <    property UserID : Integer read FUserID write SetUserID;
508 <    property GroupID : Integer read FGroupID write SetGroupID;
509 <    property Password : string read FPassword write setPassword;
510 <  end;
511 <
512 <
513 < implementation
514 <
515 < uses
516 <  IBIntf , IBSQLMonitor, Math;
517 <
518 < { TIBCustomService }
519 <
520 < procedure TIBCustomService.Attach;
521 < var
522 <  SPB: String;
523 <  ConnectString: String;
524 < begin
525 <  CheckInactive;
526 <  CheckServerName;
527 <
528 <  if FLoginPrompt and not Login then
529 <    IBError(ibxeOperationCancelled, [nil]);
530 <
531 <  { Generate a new SPB if necessary }
532 <  if FParamsChanged then
533 <  begin
534 <    FParamsChanged := False;
535 <    GenerateSPB(FParams, SPB, FSPBLength);
536 <    IBAlloc(FSPB, 0, FsPBLength);
537 <    Move(SPB[1], FSPB[0], FSPBLength);
538 <  end;
539 <  case FProtocol of
540 <    TCP: ConnectString := FServerName + ':service_mgr'; {do not localize}
541 <    SPX: ConnectString := FServerName + '@service_mgr'; {do not localize}
542 <    NamedPipe: ConnectString := '\\' + FServerName + '\service_mgr'; {do not localize}
543 <    Local: ConnectString := 'service_mgr'; {do not localize}
544 <  end;
545 <  if call(isc_service_attach(StatusVector, Length(ConnectString),
546 <                         PChar(ConnectString), @FHandle,
547 <                         FSPBLength, FSPB), False) > 0 then
548 <  begin
549 <    FHandle := nil;
550 <    IBDataBaseError;
551 <  end;
552 <
553 <  if Assigned(FOnAttach) then
554 <    FOnAttach(Self);
555 <
556 <  MonitorHook.ServiceAttach(Self);
557 < end;
558 <
559 < procedure TIBCustomService.Loaded;
560 < begin
561 <  inherited Loaded;
562 <  try
563 <    if FStreamedActive and (not Active) then
564 <      Attach;
565 <  except
566 <    if csDesigning in ComponentState then
567 <       HandleException(self)
568 <    else
569 <      raise;
570 <  end;
571 < end;
572 <
573 < function TIBCustomService.Login: Boolean;
574 < var
575 <  IndexOfUser, IndexOfPassword: Integer;
576 <  Username, Password: String;
577 <  LoginParams: TStrings;
578 < begin
579 <  if Assigned(FOnLogin) then begin
580 <    result := True;
581 <    LoginParams := TStringList.Create;
582 <    try
583 <      LoginParams.Assign(Params);
584 <      FOnLogin(Self, LoginParams);
585 <      Params.Assign (LoginParams);
586 <    finally
587 <      LoginParams.Free;
588 <    end;
589 <  end
590 <  else
591 <  if assigned(IBGUIInterface)  then
592 <  begin
593 <    IndexOfUser := IndexOfSPBConst(SPBConstantNames[isc_spb_user_name]);
594 <    if IndexOfUser <> -1 then
595 <      Username := Copy(Params[IndexOfUser],
596 <                                         Pos('=', Params[IndexOfUser]) + 1, {mbcs ok}
597 <                                         Length(Params[IndexOfUser]));
598 <    IndexOfPassword := IndexOfSPBConst(SPBConstantNames[isc_spb_password]);
599 <    if IndexOfPassword <> -1 then
600 <      Password := Copy(Params[IndexOfPassword],
601 <                                         Pos('=', Params[IndexOfPassword]) + 1, {mbcs ok}
602 <                                         Length(Params[IndexOfPassword]));
603 <    result := IBGUIInterface.ServerLoginDialog(serverName, Username, Password);
604 <    if result then
605 <    begin
606 <      IndexOfPassword := IndexOfSPBConst(SPBConstantNames[isc_spb_password]);
607 <      if IndexOfUser = -1 then
608 <        Params.Add(SPBConstantNames[isc_spb_user_name] + '=' + Username)
609 <      else
610 <        Params[IndexOfUser] := SPBConstantNames[isc_spb_user_name] +
611 <                                 '=' + Username;
612 <      if IndexOfPassword = -1 then
613 <        Params.Add(SPBConstantNames[isc_spb_password] + '=' + Password)
614 <      else
615 <        Params[IndexOfPassword] := SPBConstantNames[isc_spb_password] +
616 <                                     '=' + Password;
617 <    end
618 <  end
619 <  else
620 <    IBError(ibxeNoLoginDialog,[]);
621 < end;
622 <
623 < procedure TIBCustomService.CheckActive;
624 < begin
625 <  if FStreamedActive and (not Active) then
626 <    Loaded;
627 <  if FHandle = nil then
628 <    IBError(ibxeServiceActive, [nil]);
629 < end;
630 <
631 < procedure TIBCustomService.CheckInactive;
632 < begin
633 <  if FHandle <> nil then
634 <    IBError(ibxeServiceInActive, [nil]);
635 < end;
636 <
637 < procedure TIBCustomService.HandleException(Sender: TObject);
638 < var aParent: TComponent;
639 < begin
640 <  aParent := Owner;
641 <  while aParent <> nil do
642 <  begin
643 <    if aParent is TCustomApplication then
644 <    begin
645 <      TCustomApplication(aParent).HandleException(Sender);
646 <      Exit;
647 <    end;
648 <    aParent := aParent.Owner;
649 <  end;
650 <  SysUtils.ShowException(ExceptObject,ExceptAddr);
651 < end;
652 <
653 < constructor TIBCustomService.Create(AOwner: TComponent);
654 < begin
655 <  inherited Create(AOwner);
656 <  FIBLoaded := False;
657 <  CheckIBLoaded;
658 <  FIBLoaded := True;
659 <  FserverName := '';
660 <  FParams := TStringList.Create;
661 <  FParamsChanged := True;
662 <  TStringList(FParams).OnChange := ParamsChange;
663 <  TStringList(FParams).OnChanging := ParamsChanging;
664 <  FSPB := nil;
665 <  FQuerySPB := nil;
666 <  FBufferSize := DefaultBufferSize;
667 <  FHandle := nil;
668 <  FLoginPrompt := True;
669 <  FTraceFlags := [];
670 <  FOutputbuffer := nil;
671 <  FProtocol := Local;
672 <  if (AOwner <> nil) and
673 <     (AOwner is TCustomApplication) and
674 <     TCustomApplication(AOwner).ConsoleApplication then
675 <    LoginPrompt := false;
676 < end;
677 <
678 < destructor TIBCustomService.Destroy;
679 < begin
680 <  if FIBLoaded then
681 <  begin
682 <    if FHandle <> nil then
683 <      Detach;
684 <    FreeMem(FSPB);
685 <    FSPB := nil;
686 <    FParams.Free;
687 <  end;
688 <  ReallocMem(FOutputBuffer, 0);
689 <  inherited Destroy;
690 < end;
691 <
692 < procedure TIBCustomService.Detach;
693 < begin
694 <  CheckActive;
695 <  if (Call(isc_service_detach(StatusVector, @FHandle), False) > 0) then
696 <  begin
697 <    FHandle := nil;
698 <    IBDataBaseError;
699 <  end
700 <  else
701 <    FHandle := nil;
702 <  MonitorHook.ServiceDetach(Self);
703 < end;
704 <
705 < function TIBCustomService.GetActive: Boolean;
706 < begin
707 <  result := FHandle <> nil;
708 < end;
709 <
710 < function TIBCustomService.GetServiceParamBySPB(const Idx: Integer): String;
711 < var
712 <  ConstIdx, EqualsIdx: Integer;
713 < begin
714 <  if (Idx > 0) and (Idx <= isc_spb_last_spb_constant) then
715 <  begin
716 <    ConstIdx := IndexOfSPBConst(SPBConstantNames[Idx]);
717 <    if ConstIdx = -1 then
718 <      result := ''
719 <    else
720 <    begin
721 <      result := Params[ConstIdx];
722 <      EqualsIdx := Pos('=', result); {mbcs ok}
723 <      if EqualsIdx = 0 then
724 <        result := ''
725 <      else
726 <        result := Copy(result, EqualsIdx + 1, Length(result));
727 <    end;
728 <  end
729 <  else
730 <    result := '';
731 < end;
732 <
733 < procedure TIBCustomService.InternalServiceQuery;
734 < begin
735 <  FQuerySPBLength := Length(FQueryParams);
736 <  if FQuerySPBLength = 0 then
737 <    IBError(ibxeQueryParamsError, [nil]);
738 <  IBAlloc(FQuerySPB, 0, FQuerySPBLength);
739 <  Move(FQueryParams[1], FQuerySPB[0], FQuerySPBLength);
740 <  if (FOutputBuffer = nil) then
741 <    IBAlloc(FOutputBuffer, 0, FBufferSize);
742 <  try
743 <    if call(isc_service_query(StatusVector, @FHandle, nil, 0, nil,
744 <                           FQuerySPBLength, FQuerySPB,
745 <                           FBufferSize, FOutputBuffer), False) > 0 then
746 <    begin
747 <      FHandle := nil;
748 <      IBDataBaseError;
749 <    end;
750 <  finally
751 <    FreeMem(FQuerySPB);
752 <    FQuerySPB := nil;
753 <    FQuerySPBLength := 0;
754 <    FQueryParams := '';
755 <  end;
756 <  MonitorHook.ServiceQuery(Self);
757 < end;
758 <
759 < procedure TIBCustomService.SetActive(const Value: Boolean);
760 < begin
761 <  if csReading in ComponentState then
762 <    FStreamedActive := Value
763 <  else
764 <    if Value <> Active then  
765 <      if Value then
766 <        Attach
767 <      else
768 <        Detach;
769 < end;
770 <
771 < procedure TIBCustomService.SetBufferSize(const Value: Integer);
772 < begin
773 <  if (FOutputBuffer <> nil) and (Value <> FBufferSize) then
774 <    IBAlloc(FOutputBuffer, 0, FBufferSize);
775 < end;
776 <
777 < procedure TIBCustomService.SetParams(const Value: TStrings);
778 < begin
779 <  FParams.Assign(Value);
780 < end;
781 <
782 < procedure TIBCustomService.SetServerName(const Value: string);
783 < begin
784 <  if FServerName <> Value then
785 <  begin
786 <    CheckInactive;
787 <    FServerName := Value;
788 <  end;
789 < end;
790 <
791 < procedure TIBCustomService.SetProtocol(const Value: TProtocol);
792 < begin
793 <  if FProtocol <> Value then
794 <  begin
795 <    CheckInactive;
796 <    FProtocol := Value;
797 <    if (Value = Local) then
798 <      FServerName := '';
799 <  end;
800 < end;
801 <
802 < procedure TIBCustomService.SetServiceParamBySPB(const Idx: Integer;
803 <  const Value: String);
804 < var
805 <  ConstIdx: Integer;
806 < begin
807 <  ConstIdx := IndexOfSPBConst(SPBConstantNames[Idx]);
808 <  if (Value = '') then
809 <  begin
810 <    if ConstIdx <> -1 then
811 <      Params.Delete(ConstIdx);
812 <  end
813 <  else
814 <  begin
815 <    if (ConstIdx = -1) then
816 <      Params.Add(SPBConstantNames[Idx] + '=' + Value)
817 <    else
818 <      Params[ConstIdx] := SPBConstantNames[Idx] + '=' + Value;
819 <  end;
820 < end;
821 <
822 < function TIBCustomService.IndexOfSPBConst(st: String): Integer;
823 < var
824 <  i, pos_of_str: Integer;
825 < begin
826 <  result := -1;
827 <  for i := 0 to Params.Count - 1 do
828 <  begin
829 <    pos_of_str := Pos(st, Params[i]); {mbcs ok}
830 <    if (pos_of_str = 1) or (pos_of_str = Length(SPBPrefix) + 1) then
831 <    begin
832 <      result := i;
833 <      break;
834 <    end;
835 <  end;
836 < end;
837 <
838 < procedure TIBCustomService.ParamsChange(Sender: TObject);
839 < begin
840 <  FParamsChanged := True;
841 < end;
842 <
843 < procedure TIBCustomService.ParamsChanging(Sender: TObject);
844 < begin
845 <  CheckInactive;
846 < end;
847 <
848 < procedure TIBCustomService.CheckServerName;
849 < begin
850 <  if (FServerName = '') and (FProtocol <> Local) then
851 <    IBError(ibxeServerNameMissing, [nil]);
852 < end;
853 <
854 < function TIBCustomService.Call(ErrCode: ISC_STATUS;
855 <  RaiseError: Boolean): ISC_STATUS;
856 < begin
857 <  result := ErrCode;
858 <  if RaiseError and (ErrCode > 0) then
859 <    IBDataBaseError;
860 < end;
861 <
862 < function TIBCustomService.ParseString(var RunLen: Integer): string;
863 < var
864 <  Len: UShort;
865 <  tmp: Char;
866 < begin
867 <  Len := isc_vax_integer(OutputBuffer + RunLen, 2);
868 <  RunLen := RunLen + 2;
869 <  if (Len <> 0) then
870 <  begin
871 <    tmp := OutputBuffer[RunLen + Len];
872 <    OutputBuffer[RunLen + Len] := #0;
873 <    result := String(PChar(@OutputBuffer[RunLen]));
874 <    OutputBuffer[RunLen + Len] := tmp;
875 <    RunLen := RunLen + Len;
876 <  end
877 <  else
878 <    result := '';
879 < end;
880 <
881 < function TIBCustomService.ParseInteger(var RunLen: Integer): Integer;
882 < begin
883 <  result := isc_vax_integer(OutputBuffer + RunLen, 4);
884 <  RunLen := RunLen + 4;
885 < end;
886 <
887 < {
888 < * GenerateSPB -
889 < *  Given a string containing a textual representation
890 < *  of the Service parameters, generate a service
891 < *  parameter buffer, and return it and its length
892 < *  in SPB and SPBLength, respectively.
893 < }
894 < procedure TIBCustomService.GenerateSPB(sl: TStrings; var SPB: String;
895 <  var SPBLength: Short);
896 < var
897 <  i, j, SPBVal, SPBServerVal: UShort;
898 <  param_name, param_value: String;
899 < begin
900 <  { The SPB is initially empty, with the exception that
901 <   the SPB version must be the first byte of the string.
902 <  }
903 <  SPBLength := 2;
904 <  SPB := Char(isc_spb_version);
905 <  SPB := SPB + Char(isc_spb_current_version);
906 <  { Iterate through the textual service parameters, constructing
907 <   a SPB on-the-fly }
908 <  if sl.Count > 0 then
909 <  for i := 0 to sl.Count - 1 do
910 <  begin
911 <   { Get the parameter's name and value from the list,
912 <     and make sure that the name is all lowercase with
913 <     no leading 'isc_spb_' prefix }
914 <    if (Trim(sl.Names[i]) = '') then continue;
915 <    param_name := LowerCase(sl.Names[i]); {mbcs ok}
916 <    param_value := Copy(sl[i], Pos('=', sl[i]) + 1, Length(sl[i])); {mbcs ok}
917 <    if (Pos(SPBPrefix, param_name) = 1) then {mbcs ok}
918 <      Delete(param_name, 1, Length(SPBPrefix));
919 <    { We want to translate the parameter name to some integer
920 <      value. We do this by scanning through a list of known
921 <      service parameter names (SPBConstantNames, defined above). }
922 <    SPBVal := 0;
923 <    SPBServerVal := 0;
924 <    { Find the parameter }
925 <    for j := 1 to isc_spb_last_spb_constant do
926 <      if (param_name = SPBConstantNames[j]) then
927 <      begin
928 <        SPBVal := j;
929 <        SPBServerVal := SPBConstantValues[j];
930 <        break;
931 <      end;
932 <    case SPBVal of
933 <      isc_spb_user_name, isc_spb_password:
934 <      begin
935 <        SPB := SPB +
936 <               Char(SPBServerVal) +
937 <               Char(Length(param_value)) +
938 <               param_value;
939 <        Inc(SPBLength, 2 + Length(param_value));
940 <      end;
941 <      else
942 <      begin
943 <        if (SPBVal > 0) and
944 <           (SPBVal <= isc_dpb_last_dpb_constant) then
945 <          IBError(ibxeSPBConstantNotSupported,
946 <                   [SPBConstantNames[SPBVal]])
947 <        else
948 <          IBError(ibxeSPBConstantUnknown, [SPBVal]);
949 <      end;
950 <    end;
951 <  end;
952 < end;
953 <
954 < { TIBServerProperties }
955 < constructor TIBServerProperties.Create(AOwner: TComponent);
956 < begin
957 <  inherited Create(AOwner);
958 <  FDatabaseInfo := TDatabaseInfo.Create;
959 <  FLicenseInfo := TLicenseInfo.Create;
960 <  FLicenseMaskInfo := TLicenseMaskInfo.Create;
961 <  FVersionInfo := TVersionInfo.Create;
962 <  FConfigParams := TConfigParams.Create;
963 < end;
964 <
965 < destructor TIBServerProperties.Destroy;
966 < begin
967 <  FDatabaseInfo.Free;
968 <  FLicenseInfo.Free;
969 <  FLicenseMaskInfo.Free;
970 <  FVersionInfo.Free;
971 <  FConfigParams.Free;
972 <  inherited Destroy;
973 < end;
974 <
975 < procedure TIBServerProperties.ParseConfigFileData(var RunLen: Integer);
976 < begin
977 <  Inc(RunLen);
978 <  with FConfigParams.ConfigFileData do
979 <  begin
980 <    SetLength (ConfigFileValue, Length(ConfigFileValue)+1);
981 <    SetLength (ConfigFileKey, Length(ConfigFileKey)+1);
982 <
983 <    ConfigFileKey[High(ConfigFileKey)] := Integer(OutputBuffer[RunLen-1]);
984 <    ConfigFileValue[High(ConfigFileValue)] := ParseInteger(RunLen);
985 <  end;
986 < end;
987 <
988 < procedure TIBServerProperties.Fetch;
989 < begin
990 <  if (Database in Options) then
991 <    FetchDatabaseInfo;
992 <  if (License in Options) then
993 <    FetchLicenseInfo;
994 <  if (LicenseMask in Options) then
995 <    FetchLicenseMaskInfo;
996 <  if (ConfigParameters in Options) then
997 <    FetchConfigParams;
998 <  if (Version in Options) then
999 <    FetchVersionInfo;
1000 < end;
1001 <
1002 < procedure TIBServerProperties.FetchConfigParams;
1003 < var
1004 <  RunLen: Integer;
1005 <
1006 < begin
1007 <  ServiceQueryParams := Char(isc_info_svc_get_config) +
1008 <                        Char(isc_info_svc_get_env) +
1009 <                        Char(isc_info_svc_get_env_lock) +
1010 <                        Char(isc_info_svc_get_env_msg) +
1011 <                        Char(isc_info_svc_user_dbpath);
1012 <
1013 <  InternalServiceQuery;
1014 <  RunLen := 0;
1015 <  While (not (Integer(OutputBuffer[RunLen]) = isc_info_end)) do
1016 <  begin
1017 <    case Integer(OutputBuffer[RunLen]) of
1018 <      isc_info_svc_get_config:
1019 <      begin
1020 <        FConfigParams.ConfigFileData.ConfigFileKey := nil;
1021 <        FConfigParams.ConfigFileData.ConfigFileValue := nil;
1022 <        Inc (RunLen);
1023 <        while (not (Integer(OutputBuffer[RunLen]) = isc_info_flag_end)) do
1024 <          ParseConfigFileData (RunLen);
1025 <        if (Integer(OutputBuffer[RunLen]) = isc_info_flag_end) then
1026 <          Inc (RunLen);
1027 <      end;
1028 <
1029 <      isc_info_svc_get_env:
1030 <      begin
1031 <        Inc (RunLen);
1032 <        FConfigParams.BaseLocation := ParseString(RunLen);
1033 <      end;
1034 <
1035 <      isc_info_svc_get_env_lock:
1036 <      begin
1037 <        Inc (RunLen);
1038 <        FConfigParams.LockFileLocation := ParseString(RunLen);
1039 <      end;
1040 <
1041 <      isc_info_svc_get_env_msg:
1042 <      begin
1043 <        Inc (RunLen);
1044 <        FConfigParams.MessageFileLocation := ParseString(RunLen);
1045 <      end;
1046 <
1047 <      isc_info_svc_user_dbpath:
1048 <      begin
1049 <        Inc (RunLen);
1050 <        FConfigParams.SecurityDatabaseLocation := ParseString(RunLen);
1051 <      end;
1052 <      else
1053 <        IBError(ibxeOutputParsingError, [nil]);
1054 <    end;
1055 <  end;
1056 < end;
1057 <
1058 < procedure TIBServerProperties.FetchDatabaseInfo;
1059 < var
1060 <  i, RunLen: Integer;
1061 < begin
1062 <  ServiceQueryParams := Char(isc_info_svc_svr_db_info);
1063 <  InternalServiceQuery;
1064 <  if (OutputBuffer[0] <> Char(isc_info_svc_svr_db_info)) then
1065 <      IBError(ibxeOutputParsingError, [nil]);
1066 <  RunLen := 1;
1067 <  if (OutputBuffer[RunLen] <> Char(isc_spb_num_att)) then
1068 <      IBError(ibxeOutputParsingError, [nil]);
1069 <  Inc(RunLen);
1070 <  FDatabaseInfo.NoOfAttachments := ParseInteger(RunLen);
1071 <  if (OutputBuffer[RunLen] <> Char(isc_spb_num_db)) then
1072 <      IBError(ibxeOutputParsingError, [nil]);
1073 <  Inc(RunLen);
1074 <  FDatabaseInfo.NoOfDatabases := ParseInteger(RunLen);
1075 <  FDatabaseInfo.DbName := nil;
1076 <  SetLength(FDatabaseInfo.DbName, FDatabaseInfo.NoOfDatabases);
1077 <  i := 0;
1078 <  while (OutputBuffer[RunLen] <> Char(isc_info_flag_end)) do
1079 <  begin
1080 <    if (OutputBuffer[RunLen] <> Char(SPBConstantValues[isc_spb_dbname])) then
1081 <      IBError(ibxeOutputParsingError, [nil]);
1082 <    Inc(RunLen);
1083 <    FDatabaseInfo.DbName[i] := ParseString(RunLen);
1084 <    Inc (i);
1085 <  end;
1086 < end;
1087 <
1088 < procedure TIBServerProperties.FetchLicenseInfo;
1089 < var
1090 <  i, RunLen: Integer;
1091 <  done: Integer;
1092 < begin
1093 <  ServiceQueryParams := Char(isc_info_svc_get_license) +
1094 <                        Char(isc_info_svc_get_licensed_users);
1095 <  InternalServiceQuery;
1096 <  RunLen := 0;
1097 <  done := 0;
1098 <  i := 0;
1099 <  FLicenseInfo.key := nil;
1100 <  FLicenseInfo.id := nil;
1101 <  FLicenseInfo.desc := nil;
1102 <
1103 <  While done < 2 do begin
1104 <    Inc(Done);
1105 <    Inc(RunLen);
1106 <    case Integer(OutputBuffer[RunLen-1]) of
1107 <      isc_info_svc_get_license:
1108 <      begin
1109 <        while (OutputBuffer[RunLen] <> Char(isc_info_flag_end)) do
1110 <        begin
1111 <          if (i >= Length(FLicenseInfo.key)) then
1112 <          begin
1113 <            SetLength(FLicenseInfo.key, i + 10);
1114 <            SetLength(FLicenseInfo.id, i + 10);
1115 <            SetLength(FLicenseInfo.desc, i + 10);
1116 <          end;
1117 <          if (OutputBuffer[RunLen] <> Char(isc_spb_lic_id)) then
1118 <              IBError(ibxeOutputParsingError, [nil]);
1119 <          Inc(RunLen);
1120 <          FLicenseInfo.id[i] := ParseString(RunLen);
1121 <          if (OutputBuffer[RunLen] <> Char(isc_spb_lic_key)) then
1122 <              IBError(ibxeOutputParsingError, [nil]);
1123 <          Inc(RunLen);
1124 <          FLicenseInfo.key[i] := ParseString(RunLen);
1125 <          if (OutputBuffer[RunLen] <> Char(7)) then
1126 <              IBError(ibxeOutputParsingError, [nil]);
1127 <          Inc(RunLen);
1128 <          FLicenseInfo.desc[i] := ParseString(RunLen);
1129 <          Inc(i);
1130 <        end;
1131 <        Inc(RunLen);
1132 <        if (Length(FLicenseInfo.key) > i) then
1133 <        begin
1134 <          SetLength(FLicenseInfo.key, i);
1135 <          SetLength(FLicenseInfo.id, i);
1136 <          SetLength(FLicenseInfo.desc, i);
1137 <        end;
1138 <      end;
1139 <      isc_info_svc_get_licensed_users:
1140 <        FLicenseInfo.LicensedUsers := ParseInteger(RunLen);
1141 <      else
1142 <        IBError(ibxeOutputParsingError, [nil]);
1143 <    end;
1144 <  end;
1145 < end;
1146 <
1147 < procedure TIBServerProperties.FetchLicenseMaskInfo();
1148 < var
1149 <  done,RunLen:integer;
1150 < begin
1151 <  ServiceQueryParams := Char(isc_info_svc_get_license_mask) +
1152 <                        Char(isc_info_svc_capabilities);
1153 <  InternalServiceQuery;
1154 <  RunLen := 0;
1155 <  done := 0;
1156 <  While done <= 1 do
1157 <  begin
1158 <    Inc(done);
1159 <    Inc(RunLen);
1160 <    case Integer(OutputBuffer[RunLen-1]) of
1161 <      isc_info_svc_get_license_mask:
1162 <        FLicenseMaskInfo.LicenseMask := ParseInteger(RunLen);
1163 <      isc_info_svc_capabilities:
1164 <        FLicenseMaskInfo.CapabilityMask := ParseInteger(RunLen);
1165 <      else
1166 <        IBError(ibxeOutputParsingError, [nil]);
1167 <    end;
1168 <  end;
1169 < end;
1170 <
1171 <
1172 < procedure TIBServerProperties.FetchVersionInfo;
1173 < var
1174 <  RunLen: Integer;
1175 <  done: Integer;
1176 < begin
1177 <  ServiceQueryParams := Char(isc_info_svc_version) +
1178 <                        Char(isc_info_svc_server_version) +
1179 <                        Char(isc_info_svc_implementation);
1180 <  InternalServiceQuery;
1181 <  RunLen := 0;
1182 <  done := 0;
1183 <
1184 <  While done <= 2 do
1185 <  begin
1186 <    Inc(done);
1187 <    Inc(RunLen);
1188 <    case Integer(OutputBuffer[RunLen-1]) of
1189 <      isc_info_svc_version:
1190 <        FVersionInfo.ServiceVersion := ParseInteger(RunLen);
1191 <      isc_info_svc_server_version:
1192 <        FVersionInfo.ServerVersion := ParseString(RunLen);
1193 <      isc_info_svc_implementation:
1194 <        FVersionInfo.ServerImplementation := ParseString(RunLen);
1195 <      else
1196 <        IBError(ibxeOutputParsingError, [nil]);
1197 <    end;
1198 <  end;
1199 < end;
1200 <
1201 < { TIBControlService }
1202 < procedure TIBControlService.SetServiceStartOptions;
1203 < begin
1204 <
1205 < end;
1206 <
1207 < function TIBControlService.GetIsServiceRunning: Boolean;
1208 < var
1209 <  RunLen: Integer;
1210 < begin
1211 <  ServiceQueryParams := Char(isc_info_svc_running);
1212 <  InternalServiceQuery;
1213 <  if (OutputBuffer[0] <> Char(isc_info_svc_running)) then
1214 <    IBError(ibxeOutputParsingError, [nil]);
1215 <  RunLen := 1;
1216 <  if (ParseInteger(RunLen) = 1) then
1217 <    result := True
1218 <  else
1219 <    result := False;
1220 < end;
1221 <
1222 < procedure TIBControlService.ServiceStartAddParam (Value: string; param: Integer);
1223 < var
1224 <  Len: UShort;
1225 < begin
1226 <  Len := Length(Value);
1227 <  if Len > 0 then
1228 <  begin
1229 <    FStartParams  := FStartParams +
1230 <                     Char(Param) +
1231 <                     PChar(@Len)[0] +
1232 <                     PChar(@Len)[1] +
1233 <                     Value;
1234 <  end;
1235 < end;
1236 <
1237 < procedure TIBControlService.ServiceStartAddParam (Value: Integer; param: Integer);
1238 < begin
1239 <  FStartParams  := FStartParams +
1240 <                   Char(Param) +
1241 <                   PChar(@Value)[0] +
1242 <                   PChar(@Value)[1] +
1243 <                   PChar(@Value)[2] +
1244 <                   PChar(@Value)[3];
1245 < end;
1246 <
1247 < constructor TIBControlService.Create(AOwner: TComponent);
1248 < begin
1249 <  inherited create(AOwner);
1250 <  FStartParams := '';
1251 <  FStartSPB := nil;
1252 <  FStartSPBLength := 0;
1253 < end;
1254 <
1255 < procedure TIBControlService.InternalServiceStart;
1256 < begin
1257 <  FStartSPBLength := Length(FStartParams);
1258 <  if FStartSPBLength = 0 then
1259 <    IBError(ibxeStartParamsError, [nil]);
1260 <  IBAlloc(FStartSPB, 0, FStartSPBLength);
1261 <  Move(FStartParams[1], FStartSPB[0], FstartSPBLength);
1262 <  try
1263 <    if call(isc_service_start(StatusVector, @FHandle, nil,
1264 <                           FStartSPBLength, FStartSPB), False) > 0 then
1265 <    begin
1266 <      FHandle := nil;
1267 <      IBDataBaseError;
1268 <    end;
1269 <  finally
1270 <    FreeMem(FStartSPB);
1271 <    FStartSPB := nil;
1272 <    FStartSPBLength := 0;
1273 <    FStartParams := '';
1274 <  end;
1275 <  MonitorHook.ServiceStart(Self);
1276 < end;
1277 <
1278 < procedure TIBControlService.ServiceStart;
1279 < begin
1280 <  CheckActive;
1281 <  SetServiceStartOptions;
1282 <  InternalServiceStart;
1283 < end;
1284 <
1285 < { TIBConfigService }
1286 <
1287 < procedure TIBConfigService.ServiceStart;
1288 < begin
1289 <  IBError(ibxeUseSpecificProcedures, [nil]);
1290 < end;
1291 <
1292 < procedure TIBConfigService.ActivateShadow;
1293 < begin
1294 <  ServiceStartParams  := Char(isc_action_svc_properties);
1295 <  ServiceStartAddParam (FDatabaseName, SPBConstantValues[isc_spb_dbname]);
1296 <  ServiceStartAddParam (isc_spb_prp_activate, SPBConstantValues[isc_spb_options]);
1297 <  InternalServiceStart;
1298 < end;
1299 <
1300 < procedure TIBConfigService.BringDatabaseOnline;
1301 < begin
1302 <  ServiceStartParams  := Char(isc_action_svc_properties);
1303 <  ServiceStartAddParam (FDatabaseName, SPBConstantValues[isc_spb_dbname]);
1304 <  ServiceStartAddParam (isc_spb_prp_db_online, SPBConstantValues[isc_spb_options]);
1305 <  InternalServiceStart;
1306 < end;
1307 <
1308 < procedure TIBConfigService.SetAsyncMode(Value: Boolean);
1309 < begin
1310 <  ServiceStartParams  := Char(isc_action_svc_properties);
1311 <  ServiceStartAddParam (FDatabaseName, SPBConstantValues[isc_spb_dbname]);
1312 <  ServiceStartParams := ServiceStartParams +
1313 <                        Char(isc_spb_prp_write_mode);
1314 <  if Value then
1315 <    ServiceStartParams  := ServiceStartParams +
1316 <                           Char(isc_spb_prp_wm_async)
1317 <  else
1318 <    ServiceStartParams  := ServiceStartParams +
1319 <                           Char(isc_spb_prp_wm_sync);
1320 <  InternalServiceStart;
1321 < end;
1322 <
1323 < procedure TIBConfigService.SetDatabaseName(const Value: string);
1324 < begin
1325 <  FDatabaseName := Value;
1326 < end;
1327 <
1328 < procedure TIBConfigService.SetPageBuffers(Value: Integer);
1329 < begin
1330 <  ServiceStartParams  := Char(isc_action_svc_properties);
1331 <  ServiceStartAddParam (FDatabaseName, SPBConstantValues[isc_spb_dbname]);
1332 <  ServiceStartAddParam (Value, isc_spb_prp_page_buffers);
1333 <  InternalServiceStart;
1334 < end;
1335 <
1336 < procedure TIBConfigService.SetReadOnly(Value: Boolean);
1337 < begin
1338 <  ServiceStartParams  := Char(isc_action_svc_properties);
1339 <  ServiceStartAddParam (FDatabaseName, SPBConstantValues[isc_spb_dbname]);
1340 <  ServiceStartParams := ServiceStartParams +
1341 <                         Char(isc_spb_prp_access_mode);
1342 <  if Value then
1343 <    ServiceStartParams  := ServiceStartParams +
1344 <                           Char(isc_spb_prp_am_readonly)
1345 <  else
1346 <    ServiceStartParams  := ServiceStartParams +
1347 <                           Char(isc_spb_prp_am_readwrite);
1348 <  InternalServiceStart;
1349 < end;
1350 <
1351 < procedure TIBConfigService.SetReserveSpace(Value: Boolean);
1352 < begin
1353 <  ServiceStartParams  := Char(isc_action_svc_properties);
1354 <  ServiceStartAddParam (FDatabaseName, SPBConstantValues[isc_spb_dbname]);
1355 <  ServiceStartParams := ServiceStartParams +
1356 <                        Char(isc_spb_prp_reserve_space);
1357 <  if Value then
1358 <    ServiceStartParams  := ServiceStartParams +
1359 <                           Char(isc_spb_prp_res)
1360 <  else
1361 <    ServiceStartParams  := ServiceStartParams +
1362 <                           Char(isc_spb_prp_res_use_full);
1363 <  InternalServiceStart;
1364 < end;
1365 <
1366 < procedure TIBConfigService.SetSweepInterval(Value: Integer);
1367 < begin
1368 <  ServiceStartParams  := Char(isc_action_svc_properties);
1369 <  ServiceStartAddParam (FDatabaseName, SPBConstantValues[isc_spb_dbname]);
1370 <  ServiceStartAddParam (Value, isc_spb_prp_sweep_interval);
1371 <  InternalServiceStart;
1372 < end;
1373 <
1374 < procedure TIBConfigService.SetDBSqlDialect(Value: Integer);
1375 < begin
1376 <  ServiceStartParams  := Char(isc_action_svc_properties);
1377 <  ServiceStartAddParam (FDatabaseName, SPBConstantValues[isc_spb_dbname]);
1378 <  ServiceStartAddParam (Value, isc_spb_prp_set_sql_dialect);
1379 <  InternalServiceStart;
1380 < end;
1381 <
1382 < procedure TIBConfigService.ShutdownDatabase(Options: TShutdownMode;
1383 <  Wait: Integer);
1384 < begin
1385 <  ServiceStartParams  := Char(isc_action_svc_properties);
1386 <  ServiceStartAddParam (FDatabaseName, SPBConstantValues[isc_spb_dbname]);
1387 <  if (Options = Forced) then
1388 <    ServiceStartAddParam (Wait, isc_spb_prp_shutdown_db)
1389 <  else if (Options = DenyTransaction) then
1390 <    ServiceStartAddParam (Wait, isc_spb_prp_deny_new_transactions)
1391 <  else
1392 <    ServiceStartAddParam (Wait, isc_spb_prp_deny_new_attachments);
1393 <  InternalServiceStart;
1394 < end;
1395 <
1396 < { TIBStatisticalService }
1397 <
1398 < procedure TIBStatisticalService.SetDatabaseName(const Value: string);
1399 < begin
1400 <  FDatabaseName := Value;
1401 < end;
1402 <
1403 < procedure TIBStatisticalService.SetServiceStartOptions;
1404 < var
1405 <  param: Integer;
1406 < begin
1407 <  if FDatabaseName = '' then
1408 <    IBError(ibxeStartParamsError, [nil]);
1409 <  param := 0;
1410 <  if (DataPages in Options) then
1411 <    param := param or isc_spb_sts_data_pages;
1412 <  if (DbLog in Options) then
1413 <    param := param or isc_spb_sts_db_log;
1414 <  if (HeaderPages in Options) then
1415 <    param := param or isc_spb_sts_hdr_pages;
1416 <  if (IndexPages in Options) then
1417 <    param := param or isc_spb_sts_idx_pages;
1418 <  if (SystemRelations in Options) then
1419 <    param := param or isc_spb_sts_sys_relations;
1420 <  Action := isc_action_svc_db_stats;
1421 <  ServiceStartParams  := Char(isc_action_svc_db_stats);
1422 <  ServiceStartAddParam (FDatabaseName, SPBConstantValues[isc_spb_dbname]);
1423 <  ServiceStartAddParam (param, SPBConstantValues[isc_spb_options]);
1424 < end;
1425 <
1426 < { TIBBackupService }
1427 < procedure TIBBackupService.SetServiceStartOptions;
1428 < var
1429 <  param, i: Integer;
1430 <  value: String;
1431 < begin
1432 <  if FDatabaseName = '' then
1433 <    IBError(ibxeStartParamsError, [nil]);
1434 <  param := 0;
1435 <  if (IgnoreChecksums in Options) then
1436 <    param := param or isc_spb_bkp_ignore_checksums;
1437 <  if (IgnoreLimbo in Options) then
1438 <    param := param or isc_spb_bkp_ignore_limbo;
1439 <  if (MetadataOnly in Options) then
1440 <    param := param or isc_spb_bkp_metadata_only;
1441 <  if (NoGarbageCollection in Options) then
1442 <    param := param or isc_spb_bkp_no_garbage_collect;
1443 <  if (OldMetadataDesc in Options) then
1444 <    param := param or isc_spb_bkp_old_descriptions;
1445 <  if (NonTransportable in Options) then
1446 <    param := param or isc_spb_bkp_non_transportable;
1447 <  if (ConvertExtTables in Options) then
1448 <    param := param or isc_spb_bkp_convert;
1449 <  Action := isc_action_svc_backup;
1450 <  ServiceStartParams  := Char(isc_action_svc_backup);
1451 <  ServiceStartAddParam(FDatabaseName, SPBConstantValues[isc_spb_dbname]);
1452 <  ServiceStartAddParam(param, SPBConstantValues[isc_spb_options]);
1453 <  if Verbose then
1454 <    ServiceStartParams := ServiceStartParams + Char(SPBConstantValues[isc_spb_verbose]);
1455 <  if FBlockingFactor > 0 then
1456 <    ServiceStartAddParam(FBlockingFactor, isc_spb_bkp_factor);
1457 <  for i := 0 to FBackupFile.Count - 1 do
1458 <  begin
1459 <    if (Trim(FBackupFile[i]) = '') then
1460 <      continue;
1461 <    if (Pos('=', FBackupFile[i]) <> 0) then
1462 <    begin {mbcs ok}
1463 <      ServiceStartAddParam(FBackupFile.Names[i], isc_spb_bkp_file);
1464 <      value := Copy(FBackupFile[i], Pos('=', FBackupFile[i]) + 1, Length(FBackupFile.Names[i])); {mbcs ok}
1465 <      param := StrToInt(value);
1466 <      ServiceStartAddParam(param, isc_spb_bkp_length);
1467 <    end
1468 <    else
1469 <      ServiceStartAddParam(FBackupFile[i], isc_spb_bkp_file);
1470 <  end;
1471 < end;
1472 <
1473 < constructor TIBBackupService.Create(AOwner: TComponent);
1474 < begin
1475 <  inherited Create(AOwner);
1476 <  FBackupFile := TStringList.Create;
1477 < end;
1478 <
1479 < destructor TIBBackupService.Destroy;
1480 < begin
1481 <  FBackupFile.Free;
1482 <  inherited Destroy;
1483 < end;
1484 <
1485 < procedure TIBBackupService.SetBackupFile(const Value: TStrings);
1486 < begin
1487 <  FBackupFile.Assign(Value);
1488 < end;
1489 <
1490 < { TIBRestoreService }
1491 <
1492 < procedure TIBRestoreService.SetServiceStartOptions;
1493 < var
1494 <  param, i: Integer;
1495 <  value: String;
1496 < begin
1497 <  param := 0;
1498 <  if (DeactivateIndexes in Options) then
1499 <    param := param or isc_spb_res_deactivate_idx;
1500 <  if (NoShadow in Options) then
1501 <    param := param or isc_spb_res_no_shadow;
1502 <  if (NoValidityCheck in Options) then
1503 <    param := param or isc_spb_res_no_validity;
1504 <  if (OneRelationAtATime in Options) then
1505 <    param := param or isc_spb_res_one_at_a_time;
1506 <  if (Replace in Options) then
1507 <    param := param or isc_spb_res_replace;
1508 <  if (CreateNewDB in Options) then
1509 <    param := param or isc_spb_res_create;
1510 <  if (UseAllSpace in Options) then
1511 <    param := param or isc_spb_res_use_all_space;
1512 <  Action := isc_action_svc_restore;
1513 <  ServiceStartParams  := Char(isc_action_svc_restore);
1514 <  ServiceStartAddParam(param, SPBConstantValues[isc_spb_options]);
1515 <  if Verbose then ServiceStartParams := ServiceStartParams + Char(SPBConstantValues[isc_spb_verbose]);
1516 <  if FPageSize > 0 then
1517 <    ServiceStartAddParam(FPageSize, isc_spb_res_page_size);
1518 <  if FPageBuffers > 0 then
1519 <    ServiceStartAddParam(FPageBuffers, isc_spb_res_buffers);
1520 <  for i := 0 to FBackupFile.Count - 1 do
1521 <  begin
1522 <    if (Trim(FBackupFile[i]) = '') then continue;
1523 <    if (Pos('=', FBackupFile[i]) <> 0) then  {mbcs ok}
1524 <    begin
1525 <      ServiceStartAddParam(FBackupFile.Names[i], isc_spb_bkp_file);
1526 <      value := Copy(FBackupFile[i], Pos('=', FBackupFile[i]) + 1, Length(FBackupFile.Names[i])); {mbcs ok}
1527 <      param := StrToInt(value);
1528 <      ServiceStartAddParam(param, isc_spb_bkp_length);
1529 <    end
1530 <    else
1531 <      ServiceStartAddParam(FBackupFile[i], isc_spb_bkp_file);
1532 <  end;
1533 <  for i := 0 to FDatabaseName.Count - 1 do
1534 <  begin
1535 <    if (Trim(FDatabaseName[i]) = '') then continue;
1536 <    if (Pos('=', FDatabaseName[i]) <> 0) then {mbcs ok}
1537 <    begin
1538 <      ServiceStartAddParam(FDatabaseName.Names[i], SPBConstantValues[isc_spb_dbname]);
1539 <      value := Copy(FDatabaseName[i], Pos('=', FDatabaseName[i]) + 1, Length(FDatabaseName[i])); {mbcs ok}
1540 <      param := StrToInt(value);
1541 <      ServiceStartAddParam(param, isc_spb_res_length);
1542 <    end
1543 <    else
1544 <      ServiceStartAddParam(FDatabaseName[i], SPBConstantValues[isc_spb_dbname]);
1545 <  end;
1546 < end;
1547 <
1548 < constructor TIBRestoreService.Create(AOwner: TComponent);
1549 < begin
1550 <  inherited Create(AOwner);
1551 <  FDatabaseName := TStringList.Create;
1552 <  FBackupFile := TStringList.Create;
1553 <  Include (FOptions, CreateNewDB);
1554 < end;
1555 <
1556 < destructor TIBRestoreService.Destroy;
1557 < begin
1558 <  FDatabaseName.Free;
1559 <  FBackupFile.Free;
1560 <  inherited Destroy;
1561 < end;
1562 <
1563 < procedure TIBRestoreService.SetBackupFile(const Value: TStrings);
1564 < begin
1565 <  FBackupFile.Assign(Value);
1566 < end;
1567 <
1568 < procedure TIBRestoreService.SetDatabaseName(const Value: TStrings);
1569 < begin
1570 <  FDatabaseName.Assign(Value);
1571 < end;
1572 <
1573 < { TIBValidationService }
1574 < constructor TIBValidationService.Create(AOwner: TComponent);
1575 < begin
1576 <  inherited Create(AOwner);
1577 < end;
1578 <
1579 < destructor TIBValidationService.Destroy;
1580 < var
1581 <  i : Integer;
1582 < begin
1583 <  for i := 0 to High(FLimboTransactionInfo) do
1584 <    FLimboTransactionInfo[i].Free;
1585 <  FLimboTransactionInfo := nil;
1586 <  inherited Destroy;
1587 < end;
1588 <
1589 < procedure TIBValidationService.FetchLimboTransactionInfo;
1590 < var
1591 <  i, RunLen: Integer;
1592 <  Value: Char;
1593 < begin
1594 <  ServiceQueryParams := Char(isc_info_svc_limbo_trans);
1595 <  InternalServiceQuery;
1596 <  RunLen := 0;
1597 <  if (OutputBuffer[RunLen] <> Char(isc_info_svc_limbo_trans)) then
1598 <    IBError(ibxeOutputParsingError, [nil]);
1599 <  Inc(RunLen, 3);
1600 <  for i := 0 to High(FLimboTransactionInfo) do
1601 <    FLimboTransactionInfo[i].Free;
1602 <  FLimboTransactionInfo := nil;
1603 <  i := 0;
1604 <  while (OutputBuffer[RunLen] <> Char(isc_info_end)) do
1605 <  begin
1606 <    if (i >= Length(FLimboTransactionInfo)) then
1607 <      SetLength(FLimboTransactionInfo, i + 10);
1608 <    if FLimboTransactionInfo[i] = nil then
1609 <      FLimboTransactionInfo[i] := TLimboTransactionInfo.Create;
1610 <    with FLimboTransactionInfo[i] do
1611 <    begin
1612 <      if (OutputBuffer[RunLen] = Char(isc_spb_single_tra_id)) then
1613 <      begin
1614 <        Inc(RunLen);
1615 <        MultiDatabase := False;
1616 <        ID := ParseInteger(RunLen);
1617 <      end
1618 <      else
1619 <      begin
1620 <        Inc(RunLen);
1621 <        MultiDatabase := True;
1622 <        ID := ParseInteger(RunLen);
1623 <        HostSite := ParseString(RunLen);
1624 <        if (OutputBuffer[RunLen] <> Char(isc_spb_tra_state)) then
1625 <          IBError(ibxeOutputParsingError, [nil]);
1626 <        Inc(RunLen);
1627 <        Value := OutputBuffer[RunLen];
1628 <        Inc(RunLen);
1629 <        if (Value = Char(isc_spb_tra_state_limbo)) then
1630 <          State := LimboState
1631 <        else
1632 <          if (Value = Char(isc_spb_tra_state_commit)) then
1633 <            State := CommitState
1634 <          else
1635 <            if (Value = Char(isc_spb_tra_state_rollback)) then
1636 <              State := RollbackState
1637 <            else
1638 <              State := UnknownState;
1639 <        RemoteSite := ParseString(RunLen);
1640 <        RemoteDatabasePath := ParseString(RunLen);
1641 <        Value := OutputBuffer[RunLen];
1642 <        Inc(RunLen);
1643 <        if (Value = Char(isc_spb_tra_advise_commit)) then
1644 <        begin
1645 <          Advise := CommitAdvise;
1646 <          Action:= CommitAction;
1647 <        end
1648 <        else
1649 <          if (Value = Char(isc_spb_tra_advise_rollback)) then
1650 <          begin
1651 <            Advise := RollbackAdvise;
1652 <            Action := RollbackAction;
1653 <          end
1654 <          else
1655 <          begin
1656 <            { if no advice commit as default }
1657 <            Advise := UnknownAdvise;
1658 <            Action:= CommitAction;
1659 <          end;
1660 <      end;
1661 <      Inc (i);
1662 <    end;
1663 <  end;
1664 <  if (i > 0) then
1665 <    SetLength(FLimboTransactionInfo, i+1);
1666 < end;
1667 <
1668 < procedure TIBValidationService.FixLimboTransactionErrors;
1669 < var
1670 <  i: Integer;
1671 < begin
1672 <  ServiceStartParams  := Char(isc_action_svc_repair);
1673 <  ServiceStartAddParam (FDatabaseName, SPBConstantValues[isc_spb_dbname]);
1674 <  if (FGlobalAction = NoGlobalAction) then
1675 <  begin
1676 <    i := 0;
1677 <    while (FLimboTransactionInfo[i].ID <> 0) do
1678 <    begin
1679 <      if (FLimboTransactionInfo[i].Action = CommitAction) then
1680 <        ServiceStartAddParam (FLimboTransactionInfo[i].ID, isc_spb_rpr_commit_trans)
1681 <      else
1682 <        ServiceStartAddParam (FLimboTransactionInfo[i].ID, isc_spb_rpr_rollback_trans);                              
1683 <      Inc(i);
1684 <    end;
1685 <  end
1686 <  else
1687 <  begin
1688 <    i := 0;
1689 <    if (FGlobalAction = CommitGlobal) then
1690 <      while (FLimboTransactionInfo[i].ID <> 0) do
1691 <      begin
1692 <        ServiceStartAddParam (FLimboTransactionInfo[i].ID, isc_spb_rpr_commit_trans);
1693 <        Inc(i);
1694 <      end
1695 <    else
1696 <      while (FLimboTransactionInfo[i].ID <> 0) do
1697 <      begin
1698 <        ServiceStartAddParam (FLimboTransactionInfo[i].ID, isc_spb_rpr_rollback_trans);
1699 <        Inc(i);
1700 <      end;
1701 <  end;
1702 <  InternalServiceStart;
1703 < end;
1704 <
1705 < function TIBValidationService.GetLimboTransactionInfo(index: integer): TLimboTransactionInfo;
1706 < begin
1707 <  if index <= High(FLimboTransactionInfo) then
1708 <    result := FLimboTransactionInfo[index]
1709 <  else
1710 <    result := nil;
1711 < end;
1712 <
1713 < function TIBValidationService.GetLimboTransactionInfoCount: integer;
1714 < begin
1715 <  Result := High(FLimboTransactionInfo);
1716 < end;
1717 <
1718 < procedure TIBValidationService.SetDatabaseName(const Value: string);
1719 < begin
1720 <  FDatabaseName := Value;
1721 < end;
1722 <
1723 < procedure TIBValidationService.SetServiceStartOptions;
1724 < var
1725 <  param: Integer;
1726 < begin
1727 <  Action := isc_action_svc_repair;
1728 <  if FDatabaseName = '' then
1729 <    IBError(ibxeStartParamsError, [nil]);
1730 <  param := 0;
1731 <  if (SweepDB in Options) then
1732 <    param := param or isc_spb_rpr_sweep_db;
1733 <  if (ValidateDB in Options) then
1734 <    param := param or isc_spb_rpr_validate_db;
1735 <  ServiceStartParams  := Char(isc_action_svc_repair);
1736 <  ServiceStartAddParam (FDatabaseName, SPBConstantValues[isc_spb_dbname]);
1737 <  if param > 0 then
1738 <    ServiceStartAddParam (param, SPBConstantValues[isc_spb_options]);
1739 <  param := 0;
1740 <  if (LimboTransactions in Options) then
1741 <    param := param or isc_spb_rpr_list_limbo_trans;
1742 <  if (CheckDB in Options) then
1743 <    param := param or isc_spb_rpr_check_db;
1744 <  if (IgnoreChecksum in Options) then
1745 <    param := param or isc_spb_rpr_ignore_checksum;
1746 <  if (KillShadows in Options) then
1747 <    param := param or isc_spb_rpr_kill_shadows;
1748 <  if (MendDB in Options) then
1749 <    param := param or isc_spb_rpr_mend_db;
1750 <  if (ValidateFull in Options) then
1751 <  begin
1752 <     param := param or isc_spb_rpr_full;
1753 <     if not (MendDB in Options) then
1754 <       param := param or isc_spb_rpr_validate_db;
1755 <  end;
1756 <  if param > 0 then
1757 <    ServiceStartAddParam (param, SPBConstantValues[isc_spb_options]);
1758 < end;
1759 <
1760 < { TIBSecurityService }
1761 < constructor TIBSecurityService.Create(AOwner: TComponent);
1762 < begin
1763 <  inherited Create(AOwner);
1764 <  FModifyParams := [];
1765 < end;
1766 <
1767 < destructor TIBSecurityService.Destroy;
1768 < var
1769 <  i : Integer;
1770 < begin
1771 <  for i := 0 to High(FUserInfo) do
1772 <    FUserInfo[i].Free;
1773 <  FUserInfo := nil;
1774 <  inherited Destroy;
1775 < end;
1776 <
1777 < procedure TIBSecurityService.FetchUserInfo;
1778 < var
1779 <  i, RunLen: Integer;
1780 < begin
1781 <  ServiceQueryParams := Char(isc_info_svc_get_users);
1782 <  InternalServiceQuery;
1783 <  RunLen := 0;
1784 <  if (OutputBuffer[RunLen] <> Char(isc_info_svc_get_users)) then
1785 <    IBError(ibxeOutputParsingError, [nil]);
1786 <  Inc(RunLen);
1787 <  for i := 0 to High(FUserInfo) do
1788 <    FUserInfo[i].Free;
1789 <  FUserInfo := nil;
1790 <  i := 0;
1791 <  { Don't have any use for the combined length
1792 <   so increment past by 2 }
1793 <  Inc(RunLen, 2);
1794 <  while (OutputBuffer[RunLen] <> Char(isc_info_end)) do
1795 <  begin
1796 <    if (i >= Length(FUSerInfo)) then
1797 <      SetLength(FUserInfo, i + 10);
1798 <    if (OutputBuffer[RunLen] <> Char(isc_spb_sec_username)) then
1799 <      IBError(ibxeOutputParsingError, [nil]);
1800 <    Inc(RunLen);
1801 <    if FUserInfo[i] = nil then
1802 <      FUserInfo[i] := TUserInfo.Create;
1803 <    FUserInfo[i].UserName := ParseString(RunLen);
1804 <    if (OutputBuffer[RunLen] <> Char(isc_spb_sec_firstname)) then
1805 <      IBError(ibxeOutputParsingError, [nil]);
1806 <    Inc(RunLen);
1807 <    FUserInfo[i].FirstName := ParseString(RunLen);
1808 <    if (OutputBuffer[RunLen] <> Char(isc_spb_sec_middlename)) then
1809 <      IBError(ibxeOutputParsingError, [nil]);
1810 <    Inc(RunLen);
1811 <    FUserInfo[i].MiddleName := ParseString(RunLen);
1812 <    if (OutputBuffer[RunLen] <> Char(isc_spb_sec_lastname)) then
1813 <      IBError(ibxeOutputParsingError, [nil]);
1814 <    Inc(RunLen);
1815 <    FUserInfo[i].LastName := ParseString(RunLen);
1816 <    if (OutputBuffer[RunLen] <> Char(isc_spb_sec_userId)) then
1817 <      IBError(ibxeOutputParsingError, [nil]);
1818 <    Inc(RunLen);
1819 <    FUserInfo[i].UserId := ParseInteger(RunLen);
1820 <    if (OutputBuffer[RunLen] <> Char(isc_spb_sec_groupid)) then
1821 <      IBError(ibxeOutputParsingError, [nil]);
1822 <    Inc(RunLen);
1823 <    FUserInfo[i].GroupID := ParseInteger(RunLen);
1824 <    Inc (i);
1825 <  end;
1826 <  if (i > 0) then
1827 <    SetLength(FUserInfo, i+1);
1828 < end;
1829 <
1830 < function TIBSecurityService.GetUserInfo(Index: Integer): TUserInfo;
1831 < begin
1832 <  if Index <= High(FUSerInfo) then
1833 <    result := FUserInfo[Index]
1834 <  else
1835 <    result := nil;
1836 < end;
1837 <
1838 < function TIBSecurityService.GetUserInfoCount: Integer;
1839 < begin
1840 <  Result := Max(High(FUSerInfo),0);
1841 < end;
1842 <
1843 < procedure TIBSecurityService.AddUser;
1844 < begin
1845 <  SecurityAction := ActionAddUser;
1846 <  ServiceStart;
1847 < end;
1848 <
1849 < procedure TIBSecurityService.DeleteUser;
1850 < begin
1851 <  SecurityAction := ActionDeleteUser;
1852 <  ServiceStart;
1853 < end;
1854 <
1855 < procedure TIBSecurityService.DisplayUsers;
1856 < begin
1857 <  SecurityAction := ActionDisplayUser;
1858 <  ServiceStartParams  := Char(isc_action_svc_display_user);
1859 <  InternalServiceStart;
1860 <  FetchUserInfo;
1861 < end;
1862 <
1863 < procedure TIBSecurityService.DisplayUser(UserName: String);
1864 < begin
1865 <  SecurityAction := ActionDisplayUser;
1866 <  ServiceStartParams  := Char(isc_action_svc_display_user);
1867 <  ServiceStartAddParam (UserName, isc_spb_sec_username);
1868 <  InternalServiceStart;
1869 <  FetchUserInfo;
1870 < end;
1871 <
1872 < procedure TIBSecurityService.ModifyUser;
1873 < begin
1874 <  SecurityAction := ActionModifyUser;
1875 <  ServiceStart;
1876 < end;
1877 <
1878 < procedure TIBSecurityService.SetSecurityAction (Value: TSecurityAction);
1879 < begin
1880 <  FSecurityAction := Value;
1881 <  if Value = ActionDeleteUser then
1882 <    ClearParams;
1883 < end;
1884 <
1885 < procedure TIBSecurityService.ClearParams;
1886 < begin
1887 <  FModifyParams := [];
1888 <  FFirstName := '';
1889 <  FMiddleName := '';
1890 <  FLastName := '';
1891 <  FGroupID := 0;
1892 <  FUserID := 0;
1893 <  FPassword := '';
1894 < end;
1895 <
1896 < procedure TIBSecurityService.SetFirstName (Value: String);
1897 < begin
1898 <  FFirstName := Value;
1899 <  Include (FModifyParams, ModifyFirstName);
1900 < end;
1901 <
1902 < procedure TIBSecurityService.SetMiddleName (Value: String);
1903 < begin
1904 <  FMiddleName := Value;
1905 <  Include (FModifyParams, ModifyMiddleName);
1906 < end;
1907 <
1908 < procedure TIBSecurityService.SetLastName (Value: String);
1909 < begin
1910 <  FLastName := Value;
1911 <  Include (FModifyParams, ModifyLastName);
1912 < end;
1913 <
1914 < procedure TIBSecurityService.SetPassword (Value: String);
1915 < begin
1916 <  FPassword := Value;
1917 <  Include (FModifyParams, ModifyPassword);
1918 < end;
1919 <
1920 < procedure TIBSecurityService.SetUserId (Value: Integer);
1921 < begin
1922 <  FUserId := Value;
1923 <  Include (FModifyParams, ModifyUserId);
1924 < end;
1925 <
1926 < procedure TIBSecurityService.SetGroupId (Value: Integer);
1927 < begin
1928 <  FGroupId := Value;
1929 <  Include (FModifyParams, ModifyGroupId);
1930 < end;
1931 <
1932 < procedure TIBSecurityService.Loaded;
1933 < begin
1934 <  inherited Loaded;
1935 <  ClearParams;
1936 < end;
1937 <
1938 < procedure TIBSecurityService.SetServiceStartOptions;
1939 < var
1940 <  Len: UShort;
1941 <
1942 < begin
1943 <  case FSecurityAction of
1944 <    ActionAddUser:
1945 <    begin
1946 <      Action := isc_action_svc_add_user;
1947 <      if ( Pos(' ', FUserName) > 0 ) then
1948 <        IBError(ibxeStartParamsError, [nil]);
1949 <      Len := Length(FUserName);
1950 <      if (Len = 0) then
1951 <        IBError(ibxeStartParamsError, [nil]);
1952 <      ServiceStartParams  := Char(isc_action_svc_add_user);
1953 <      ServiceStartAddParam (FSQLRole, SPBConstantValues[isc_spb_sql_role_name]);
1954 <      ServiceStartAddParam (FUserName, isc_spb_sec_username);
1955 <      ServiceStartAddParam (FUserID, isc_spb_sec_userid);
1956 <      ServiceStartAddParam (FGroupID, isc_spb_sec_groupid);
1957 <      ServiceStartAddParam (FPassword, isc_spb_sec_password);
1958 <      ServiceStartAddParam (FFirstName, isc_spb_sec_firstname);
1959 <      ServiceStartAddParam (FMiddleName, isc_spb_sec_middlename);
1960 <      ServiceStartAddParam (FLastName, isc_spb_sec_lastname);
1961 <    end;
1962 <    ActionDeleteUser:
1963 <    begin
1964 <      Action := isc_action_svc_delete_user;
1965 <      Len := Length(FUserName);
1966 <      if (Len = 0) then
1967 <        IBError(ibxeStartParamsError, [nil]);
1968 <      ServiceStartParams  := Char(isc_action_svc_delete_user);
1969 <      ServiceStartAddParam (FSQLRole, SPBConstantValues[isc_spb_sql_role_name]);
1970 <      ServiceStartAddParam (FUserName, isc_spb_sec_username);
1971 <    end;
1972 <    ActionModifyUser:
1973 <    begin
1974 <      Action := isc_action_svc_modify_user;
1975 <      Len := Length(FUserName);
1976 <      if (Len = 0) then
1977 <        IBError(ibxeStartParamsError, [nil]);
1978 <      ServiceStartParams  := Char(isc_action_svc_modify_user);
1979 <      ServiceStartAddParam (FSQLRole, SPBConstantValues[isc_spb_sql_role_name]);
1980 <      ServiceStartAddParam (FUserName, isc_spb_sec_username);
1981 <      if (ModifyUserId in FModifyParams) then
1982 <        ServiceStartAddParam (FUserID, isc_spb_sec_userid);
1983 <      if (ModifyGroupId in FModifyParams) then
1984 <        ServiceStartAddParam (FGroupID, isc_spb_sec_groupid);
1985 <      if (ModifyPassword in FModifyParams) then
1986 <        ServiceStartAddParam (FPassword, isc_spb_sec_password);
1987 <      if (ModifyFirstName in FModifyParams) then
1988 <        ServiceStartAddParam (FFirstName, isc_spb_sec_firstname);
1989 <      if (ModifyMiddleName in FModifyParams) then
1990 <        ServiceStartAddParam (FMiddleName, isc_spb_sec_middlename);
1991 <      if (ModifyLastName in FModifyParams) then
1992 <        ServiceStartAddParam (FLastName, isc_spb_sec_lastname);
1993 <    end;
1994 <  end;
1995 <  ClearParams;
1996 < end;
1997 <
1998 < { TIBUnStructuredService }
1999 < constructor TIBControlAndQueryService.Create(AOwner: TComponent);
2000 < begin
2001 <  inherited Create(AOwner);
2002 <  FEof := False;
2003 <  FAction := 0;
2004 < end;
2005 <
2006 < procedure TIBControlAndQueryService.SetAction(Value: Integer);
2007 < begin
2008 <  FEof := False;
2009 <  FAction := Value;
2010 < end;
2011 <
2012 <
2013 < function TIBControlAndQueryService.GetNextChunk: String;
2014 < var
2015 <  Length: Integer;
2016 < begin
2017 <  if (FEof = True) then
2018 <  begin
2019 <    result := '';
2020 <    exit;
2021 <  end;
2022 <  if (FAction = 0) then
2023 <    IBError(ibxeQueryParamsError, [nil]);
2024 <  ServiceQueryParams := Char(isc_info_svc_to_eof);
2025 <  InternalServiceQuery;
2026 <  if (OutputBuffer[0] <> Char(isc_info_svc_to_eof)) then
2027 <    IBError(ibxeOutputParsingError, [nil]);
2028 <  Length := isc_vax_integer(OutputBuffer + 1, 2);
2029 <  if (OutputBuffer[3 + Length] = Char(isc_info_truncated)) then
2030 <    FEof := False
2031 <  else
2032 <    if (OutputBuffer[3 + Length] = Char(isc_info_end)) then
2033 <      FEof := True
2034 <    else
2035 <      IBError(ibxeOutputParsingError, [nil]);
2036 <  OutputBuffer[3 + Length] := #0;
2037 <  result := String(PChar(@OutputBuffer[3]));
2038 < end;
2039 <
2040 < function TIBControlAndQueryService.GetNextLine: String;
2041 < var
2042 <  Length: Integer;
2043 < begin
2044 <  if (FEof = True) then
2045 <  begin
2046 <    result := '';
2047 <    exit;
2048 <  end;
2049 <  if (FAction = 0) then
2050 <    IBError(ibxeQueryParamsError, [nil]);
2051 <  ServiceQueryParams := Char(isc_info_svc_line);
2052 <  InternalServiceQuery;
2053 <  if (OutputBuffer[0] <> Char(isc_info_svc_line)) then
2054 <    IBError(ibxeOutputParsingError, [nil]);
2055 <  Length := isc_vax_integer(OutputBuffer + 1, 2);
2056 <  if (OutputBuffer[3 + Length] <> Char(isc_info_end)) then
2057 <    IBError(ibxeOutputParsingError, [nil]);
2058 <  if (length <> 0) then
2059 <    FEof := False
2060 <  else
2061 <  begin
2062 <    result := '';
2063 <    FEof := True;
2064 <    exit;
2065 <  end;
2066 <  OutputBuffer[3 + Length] := #0;
2067 <  result := String(PChar(@OutputBuffer[3]));
2068 < end;
2069 <
2070 < { TIBLogService }
2071 <
2072 < procedure TIBLogService.SetServiceStartOptions;
2073 < begin
2074 <  Action := isc_action_svc_get_ib_log;
2075 <  ServiceStartParams  := Char(isc_action_svc_get_ib_log);
2076 < end;
2077 <
2078 < { TDatabaseInfo }
2079 <
2080 < constructor TDatabaseInfo.Create;
2081 < begin
2082 <  DbName := nil;
2083 < end;
2084 <
2085 < destructor TDatabaseInfo.Destroy;
2086 < begin
2087 <  DbName := nil;
2088 <  inherited Destroy;
2089 < end;
2090 <
2091 < { TLicenseInfo }
2092 <
2093 < constructor TLicenseInfo.Create;
2094 < begin
2095 <  Key := nil;
2096 <  Id := nil;
2097 <  Desc := nil;
2098 < end;
2099 <
2100 < destructor TLicenseInfo.Destroy;
2101 < begin
2102 <  Key := nil;
2103 <  Id := nil;
2104 <  Desc := nil;
2105 <  inherited Destroy;
2106 < end;
2107 <
2108 < { TConfigFileData }
2109 <
2110 < constructor TConfigFileData.Create;
2111 < begin
2112 <  ConfigFileValue := nil;
2113 <  ConfigFileKey := nil;
2114 < end;
2115 <
2116 < destructor TConfigFileData.Destroy;
2117 < begin
2118 <  ConfigFileValue := nil;
2119 <  ConfigFileKey := nil;
2120 <  inherited Destroy;
2121 < end;
2122 <
2123 < { TConfigParams }
2124 <
2125 < constructor TConfigParams.Create;
2126 < begin
2127 <  ConfigFileData := TConfigFileData.Create;
2128 <  ConfigFileParams := nil;
2129 < end;
2130 <
2131 < destructor TConfigParams.Destroy;
2132 < begin
2133 <  ConfigFileData.Free;
2134 <  ConfigFileParams := nil;
2135 <  inherited Destroy;
2136 < end;
2137 <
2138 < end.
1 > {************************************************************************}
2 > {                                                                        }
3 > {       Borland Delphi Visual Component Library                          }
4 > {       InterBase Express core components                                }
5 > {                                                                        }
6 > {       Copyright (c) 1998-2000 Inprise Corporation                      }
7 > {                                                                        }
8 > {    InterBase Express is based in part on the product                   }
9 > {    Free IB Components, written by Gregory H. Deatz for                 }
10 > {    Hoagland, Longo, Moran, Dunst & Doukas Company.                     }
11 > {    Free IB Components is used under license.                           }
12 > {                                                                        }
13 > {    The contents of this file are subject to the InterBase              }
14 > {    Public License Version 1.0 (the "License"); you may not             }
15 > {    use this file except in compliance with the License. You            }
16 > {    may obtain a copy of the License at http://www.Inprise.com/IPL.html }
17 > {    Software distributed under the License is distributed on            }
18 > {    an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either              }
19 > {    express or implied. See the License for the specific language       }
20 > {    governing rights and limitations under the License.                 }
21 > {    The Original Code was created by InterBase Software Corporation     }
22 > {       and its successors.                                              }
23 > {    Portions created by Inprise Corporation are Copyright (C) Inprise   }
24 > {       Corporation. All Rights Reserved.                                }
25 > {    Contributor(s): Jeff Overcash                                       }
26 > {                                                                        }
27 > {    IBX For Lazarus (Firebird Express)                                  }
28 > {    Contributor: Tony Whyman, MWA Software http://www.mwasoftware.co.uk }
29 > {    Portions created by MWA Software are copyright McCallum Whyman      }
30 > {    Associates Ltd 2011 - 2018                                                 }
31 > {                                                                        }
32 > {************************************************************************}
33 >
34 > {
35 >  InterBase Express provides component interfaces to
36 >  functions introduced in InterBase 6.0.  The Services
37 >  components (TIB*Service, TIBServerProperties)
38 >  function only if you have installed InterBase 6.0 or
39 >  later software, including Firebird
40 > }
41 >
42 > unit IBServices;
43 >
44 > {$Mode Delphi}
45 > {$codepage UTF8}
46 >
47 > interface
48 >
49 > uses
50 > {$IFDEF WINDOWS }
51 >  Windows,
52 > {$ELSE}
53 >  unix,
54 > {$ENDIF}
55 >  SysUtils, Classes, IB, IBExternals, CustApp, IBTypes;
56 >
57 > const
58 >  DefaultBufferSize = 32000;
59 >
60 >  SPBPrefix = 'isc_spb_';
61 >  isc_spb_last_spb_constant = 13;
62 >  SPBConstantNames: array[1..isc_spb_last_spb_constant] of String = (
63 >    'user_name',
64 >    'sys_user_name',
65 >    'sys_user_name_enc',
66 >    'password',
67 >    'password_enc',
68 >    'command_line',
69 >    'db_name',
70 >    'verbose',
71 >    'options',
72 >    'connect_timeout',
73 >    'dummy_packet_interval',
74 >    'sql_role_name',
75 >    'expected_db'
76 >  );
77 >
78 >  SPBConstantValues: array[1..isc_spb_last_spb_constant] of Integer = (
79 >    isc_spb_user_name,
80 >    isc_spb_sys_user_name,
81 >    isc_spb_sys_user_name_enc,
82 >    isc_spb_password,
83 >    isc_spb_password_enc,
84 >    isc_spb_command_line,
85 >    isc_spb_dbname,
86 >    isc_spb_verbose,
87 >    isc_spb_options,
88 >    isc_spb_connect_timeout,
89 >    isc_spb_dummy_packet_interval,
90 >    isc_spb_sql_role_name,
91 >    isc_spb_expected_db
92 >  );
93 >
94 > type
95 >  TOutputBufferOption = (ByLine, ByChunk);
96 >
97 >  TIBCustomService = class;
98 >
99 >  TLoginEvent = procedure(Service: TIBCustomService;
100 >    LoginParams: TStrings) of object;
101 >
102 >  { TIBCustomService }
103 >
104 >  TIBCustomService = class(TComponent)
105 >  private
106 >    FParamsChanged : Boolean;
107 >    FPortNo: string;
108 >    FSRB: ISRB;
109 >    FSQPB: ISQPB;
110 >    FTraceFlags: TTraceFlags;
111 >    FOnLogin: TLoginEvent;
112 >    FLoginPrompt: Boolean;
113 >    FServerName: string;
114 >    FService: IServiceManager;
115 >    FStreamedActive  : Boolean;
116 >    FOnAttach: TNotifyEvent;
117 >    FProtocol: TProtocol;
118 >    FParams: TStrings;
119 >    FServerVersionNo: array [1..4] of integer;
120 >    FServiceQueryResults: IServiceQueryResults;
121 >    function GetActive: Boolean;
122 >    function GetServiceParamBySPB(const Idx: Integer): String;
123 >    function GetSQPB: ISQPB;
124 >    function GetSRB: ISRB;
125 >    function GetServerVersionNo(index: integer): integer;
126 >    procedure SetActive(const Value: Boolean);
127 >    procedure SetParams(const Value: TStrings);
128 >    procedure SetServerName(const Value: string);
129 >    procedure SetProtocol(const Value: TProtocol);
130 >    procedure SetService(AValue: IServiceManager);
131 >    procedure SetServiceParamBySPB(const Idx: Integer;
132 >      const Value: String);
133 >    function IndexOfSPBConst(action: byte; List: TStrings): Integer;
134 >    function GetSPBConstName(action: byte): string;
135 >    procedure ParamsChange(Sender: TObject);
136 >    procedure ParamsChanging(Sender: TObject);
137 >    procedure CheckServerName;
138 >    function GenerateSPB(sl: TStrings): ISPB;
139 >
140 >  protected
141 >    procedure Loaded; override;
142 >    function Login(var aServerName: string; LOginParams: TStrings): Boolean;
143 >    procedure CheckActive;
144 >    procedure CheckInactive;
145 >    procedure HandleException(Sender: TObject);
146 >    procedure InternalServiceQuery;
147 >    property SRB: ISRB read GetSRB;
148 >    property SQPB: ISQPB read GetSQPB;
149 >    property ServiceQueryResults: IServiceQueryResults read FServiceQueryResults;
150 >
151 >  public
152 >    constructor Create(AOwner: TComponent); override;
153 >    destructor Destroy; override;
154 >    procedure Attach;
155 >    procedure Detach;
156 >    procedure Assign(Source: TPersistent); override;
157 >
158 >    {Copies database parameters as give in the DBParams to the Service
159 >      omitting any parameters not appropriate for TIBService. Typically, the
160 >      DBParams are TIBDatabase.Params}
161 >    procedure SetDBParams(DBParams: TStrings);
162 >
163 >    property ServiceIntf: IServiceManager read FService write SetService;
164 >    property ServiceParamBySPB[const Idx: Integer]: String read GetServiceParamBySPB
165 >                                                      write SetServiceParamBySPB;
166 >    property ServerVersionNo[index: integer]: integer read GetServerVersionNo;
167 >  published
168 >    property Active: Boolean read GetActive write SetActive default False;
169 >    property ServerName: string read FServerName write SetServerName;
170 >    property Protocol: TProtocol read FProtocol write SetProtocol default Local;
171 >    property PortNo: string read FPortNo write FPortNo;
172 >    property Params: TStrings read FParams write SetParams;
173 >    property LoginPrompt: Boolean read FLoginPrompt write FLoginPrompt default True;
174 >    property TraceFlags: TTraceFlags read FTraceFlags write FTraceFlags;
175 >    property OnAttach: TNotifyEvent read FOnAttach write FOnAttach;
176 >    property OnLogin: TLoginEvent read FOnLogin write FOnLogin;
177 >  end;
178 >
179 >  TDatabaseInfo = class
180 >  public
181 >    NoOfAttachments: Integer;
182 >    NoOfDatabases: Integer;
183 >    DbName: array of string;
184 >    constructor Create;
185 >    destructor Destroy; override;
186 >  end;
187 >
188 >  TLicenseInfo = class
189 >  public
190 >    Key: array of string;
191 >    Id: array of string;
192 >    Desc: array of string;
193 >    LicensedUsers: Integer;
194 >    constructor Create;
195 >    destructor Destroy; override;
196 >  end;
197 >
198 >  TLicenseMaskInfo = class
199 >  public
200 >    LicenseMask: Integer;
201 >    CapabilityMask: Integer;
202 >  end;
203 >
204 >  TConfigFileData = class
205 >  public
206 >    ConfigFileValue: array of integer;
207 >    ConfigFileKey: array of integer;
208 >    constructor Create;
209 >    destructor Destroy; override;
210 >  end;
211 >
212 >  TConfigParams = class
213 >  public
214 >    ConfigFileData: TConfigFileData;
215 >    ConfigFileParams: array of string;
216 >    BaseLocation: string;
217 >    LockFileLocation: string;
218 >    MessageFileLocation: string;
219 >    SecurityDatabaseLocation: string;
220 >    constructor Create;
221 >    destructor Destroy; override;
222 >  end;
223 >
224 >  TVersionInfo = class
225 >    ServerVersion: String;
226 >    ServerImplementation: string;
227 >    ServiceVersion: Integer;
228 >  end;
229 >
230 >  TPropertyOption = (Database, License, LicenseMask, ConfigParameters, Version);
231 >  TPropertyOptions = set of TPropertyOption;
232 >
233 >  TIBServerProperties = class(TIBCustomService)
234 >  private
235 >    FOptions: TPropertyOptions;
236 >    FDatabaseInfo: TDatabaseInfo;
237 >    FLicenseInfo: TLicenseInfo;
238 >    FLicenseMaskInfo: TLicenseMaskInfo;
239 >    FVersionInfo: TVersionInfo;
240 >    FConfigParams: TConfigParams;
241 >  public
242 >    constructor Create(AOwner: TComponent); override;
243 >    destructor Destroy; override;
244 >    procedure Fetch;
245 >    procedure FetchDatabaseInfo;
246 >    procedure FetchLicenseInfo;
247 >    procedure FetchLicenseMaskInfo;
248 >    procedure FetchConfigParams;
249 >    procedure FetchVersionInfo;
250 >    property DatabaseInfo: TDatabaseInfo read FDatabaseInfo;
251 >    property LicenseInfo: TLicenseInfo read FLicenseInfo;
252 >    property LicenseMaskInfo: TLicenseMaskInfo read FLicenseMaskInfo;
253 >    property VersionInfo: TVersionInfo read FVersionInfo;
254 >    property ConfigParams: TConfigParams read FConfigParams;
255 >  published
256 >    property Options : TPropertyOptions read FOptions write FOptions;
257 >  end;
258 >
259 >  { TIBControlService }
260 >
261 >  TIBControlService = class (TIBCustomService)
262 >  private
263 >    function GetIsServiceRunning: Boolean;
264 >  protected
265 >    procedure CheckServiceNotRunning;
266 >    procedure InternalServiceStart;
267 >    procedure SetServiceStartOptions; virtual;
268 >
269 >  public
270 >    constructor Create(AOwner: TComponent); override;
271 >    procedure ServiceStart; virtual;
272 >    property IsServiceRunning : Boolean read GetIsServiceRunning;
273 >  end;
274 >
275 >  { TIBControlAndQueryService }
276 >
277 >  TIBControlAndQueryService = class (TIBControlService)
278 >  private
279 >    FEof: Boolean;
280 >    FAction: Integer;
281 >    procedure SetAction(Value: Integer);
282 >  protected
283 >    property Action: Integer read FAction write SetAction;
284 >  public
285 >    constructor create (AOwner: TComponent); override;
286 >    function GetNextLine : String;
287 >    function GetNextChunk : String;
288 >    procedure ServiceStart; override;
289 >    function WriteNextChunk(stream: TStream): integer;
290 >    property Eof: boolean read FEof;
291 >  end;
292 >
293 >  TShutdownMode = (Forced, DenyTransaction, DenyAttachment);
294 >
295 >  { TIBConfigService }
296 >
297 >  TIBConfigService = class(TIBControlService)
298 >  private
299 >    FDatabaseName: string;
300 >    procedure SetDatabaseName(const Value: string);
301 >  protected
302 >
303 >  public
304 >    procedure ServiceStart; override;
305 >    procedure ShutdownDatabase (Options: TShutdownMode; Wait: Integer);
306 >    procedure SetSweepInterval (Value: Integer);
307 >    procedure SetDBSqlDialect (Value: Integer);
308 >    procedure SetPageBuffers (Value: Integer);
309 >    procedure ActivateShadow;
310 >    procedure BringDatabaseOnline;
311 >    procedure SetReserveSpace (Value: Boolean);
312 >    procedure SetAsyncMode (Value: Boolean);
313 >    procedure SetReadOnly (Value: Boolean);
314 >    procedure SetAutoAdmin(Value: Boolean);
315 >    procedure SetNoLinger;
316 >  published
317 >    property DatabaseName: string read FDatabaseName write SetDatabaseName;
318 >  end;
319 >
320 >  TIBLogService = class(TIBControlAndQueryService)
321 >  private
322 >
323 >  protected
324 >    procedure SetServiceStartOptions; override;
325 >  public
326 >  published
327 >  end;
328 >
329 >  TStatOption = (DataPages, {DbLog,} HeaderPages, IndexPages, SystemRelations);
330 >  TStatOptions = set of TStatOption;
331 >
332 >  TIBStatisticalService = class(TIBControlAndQueryService)
333 >  private
334 >    FDatabaseName: string;
335 >    FOptions: TStatOptions;
336 >    procedure SetDatabaseName(const Value: string);
337 >  protected
338 >    procedure SetServiceStartOptions; override;
339 >  public
340 >  published
341 >    property DatabaseName: string read FDatabaseName write SetDatabaseName;
342 >    property Options :  TStatOptions read FOptions write FOptions;
343 >  end;
344 >
345 >  TBackupLocation = (flServerSide,flClientSide);
346 >  TBackupStatsOption = (bsTotalTime,bsTimeDelta,bsPageReads,bsPageWrites);
347 >  TBackupStatsOptions = set of TBackupStatsOption;
348 >
349 >  { TIBBackupRestoreService }
350 >
351 >  TIBBackupRestoreService = class(TIBControlAndQueryService)
352 >  private
353 >    FBackupFileLocation: TBackupLocation;
354 >    FStatisticsRequested: TBackupStatsOptions;
355 >    FVerbose: Boolean;
356 >  protected
357 >    procedure SetServiceStartOptions; override;
358 >  public
359 >    constructor Create(AOwner: TComponent); override;
360 >  published
361 >    property Verbose : Boolean read FVerbose write FVerbose default False;
362 >    property StatisticsRequested: TBackupStatsOptions read FStatisticsRequested write FStatisticsRequested;
363 >    property BackupFileLocation: TBackupLocation read FBackupFileLocation
364 >                                                      write FBackupFileLocation default flServerSide;
365 >  end;
366 >
367 >  TBackupOption = (IgnoreChecksums, IgnoreLimbo, MetadataOnly, NoGarbageCollection,
368 >    OldMetadataDesc, NonTransportable, ConvertExtTables, NoDBTriggers);
369 >  TBackupOptions = set of TBackupOption;
370 >
371 >  TIBBackupService = class (TIBBackupRestoreService)
372 >  private
373 >    FDatabaseName: string;
374 >    FOptions: TBackupOptions;
375 >    FBackupFile: TStrings;
376 >    FBlockingFactor: Integer;
377 >    procedure SetBackupFile(const Value: TStrings);
378 >  protected
379 >    procedure SetServiceStartOptions; override;
380 >  public
381 >    constructor Create(AOwner: TComponent); override;
382 >    destructor Destroy; override;
383 >
384 >  published
385 >    { a name=value pair of filename and length }
386 >    property BackupFile: TStrings read FBackupFile write SetBackupFile;
387 >    property BlockingFactor: Integer read FBlockingFactor write FBlockingFactor;
388 >    property DatabaseName: string read FDatabaseName write FDatabaseName;
389 >    property Options : TBackupOptions read FOptions write FOptions;
390 >  end;
391 >
392 >  TRestoreOption = (DeactivateIndexes, NoShadow, NoValidityCheck, OneRelationAtATime,
393 >    Replace, CreateNewDB, UseAllSpace, RestoreMetaDataOnly);
394 >
395 >  TRestoreOptions = set of TRestoreOption;
396 >
397 >  { TIBRestoreService }
398 >
399 >  TIBRestoreService = class (TIBBackupRestoreService)
400 >  private
401 >    FDatabaseName: TStrings;
402 >    FBackupFile: TStrings;
403 >    FOptions: TRestoreOptions;
404 >    FPageSize: Integer;
405 >    FPageBuffers: Integer;
406 >    FSendBytes: integer;
407 >    procedure SetBackupFile(const Value: TStrings);
408 >    procedure SetDatabaseName(const Value: TStrings);
409 >  protected
410 >    procedure SetServiceStartOptions; override;
411 >  public
412 >    constructor Create(AOwner: TComponent); override;
413 >    destructor Destroy; override;
414 >    function SendNextChunk(stream: TStream; var line: String): integer;
415 >  published
416 >    { a name=value pair of filename and length }
417 >    property DatabaseName: TStrings read FDatabaseName write SetDatabaseName;
418 >    property BackupFile: TStrings read FBackupFile write SetBackupFile;
419 >    property PageSize: Integer read FPageSize write FPageSize;
420 >    property PageBuffers: Integer read FPageBuffers write FPageBuffers;
421 >    property Options : TRestoreOptions read FOptions write FOptions default [CreateNewDB];
422 >  end;
423 >
424 >  TValidateOption = (LimboTransactions, CheckDB, IgnoreChecksum, KillShadows, MendDB,
425 >    SweepDB, ValidateDB, ValidateFull);
426 >  TValidateOptions = set of TValidateOption;
427 >
428 >  TTransactionGlobalAction = (CommitGlobal, RollbackGlobal, RecoverTwoPhaseGlobal,
429 >                             NoGlobalAction);
430 >  TTransactionState = (LimboState, CommitState, RollbackState, UnknownState);
431 >  TTransactionAdvise = (CommitAdvise, RollbackAdvise, UnknownAdvise);
432 >  TTransactionAction = (CommitAction, RollbackAction);
433 >
434 >  TLimboTransactionInfo = class
435 >  public
436 >    MultiDatabase: Boolean;
437 >    ID: Integer;
438 >    HostSite: String;
439 >    RemoteSite: String;
440 >    RemoteDatabasePath: String;
441 >    State: TTransactionState;
442 >    Advise: TTransactionAdvise;
443 >    Action: TTransactionAction;
444 >  end;
445 >
446 >  TIBValidationService = class(TIBControlAndQueryService)
447 >  private
448 >    FDatabaseName: string;
449 >    FOptions: TValidateOptions;
450 >    FLimboTransactionInfo: array of TLimboTransactionInfo;
451 >    FGlobalAction: TTransactionGlobalAction;
452 >    procedure SetDatabaseName(const Value: string);
453 >    function GetLimboTransactionInfo(index: integer): TLimboTransactionInfo;
454 >    function GetLimboTransactionInfoCount: integer;
455 >
456 >  protected
457 >    procedure SetServiceStartOptions; override;
458 >  public
459 >    constructor Create(AOwner: TComponent); override;
460 >    destructor Destroy; override;
461 >    procedure FetchLimboTransactionInfo;
462 >    procedure FixLimboTransactionErrors;
463 >    property LimboTransactionInfo[Index: integer]: TLimboTransactionInfo read GetLimboTransactionInfo;
464 >    property LimboTransactionInfoCount: Integer read GetLimboTransactionInfoCount;
465 >
466 >  published
467 >    property DatabaseName: string read FDatabaseName write SetDatabaseName;
468 >    property Options: TValidateOptions read FOptions write FOptions;
469 >    property GlobalAction: TTransactionGlobalAction read FGlobalAction
470 >                                         write FGlobalAction;
471 >  end;
472 >
473 >  { TIBOnlineValidationService }
474 >
475 >  TIBOnlineValidationService = class(TIBControlAndQueryService)
476 >  private
477 >    FDatabaseName: string;
478 >    FExcludeIndexes: string;
479 >    FExcludeTables: string;
480 >    FIncludeIndexes: string;
481 >    FIncludeTables: string;
482 >    FLockTimeout: integer;
483 >    procedure SetDatabaseName(AValue: string);
484 >  protected
485 >    procedure SetServiceStartOptions; override;
486 >  public
487 >    constructor Create(AOwner: TComponent); override;
488 >    procedure ServiceStart; override;
489 >  published
490 >    property IncludeTables: string read FIncludeTables write FIncludeTables;
491 >    property ExcludeTables: string read FExcludeTables write FExcludeTables;
492 >    property IncludeIndexes: string read FIncludeIndexes write FIncludeIndexes;
493 >    property ExcludeIndexes: string read FExcludeIndexes write FExcludeIndexes;
494 >    property LockTimeout: integer read FLockTimeout write FLockTimeout default 10;
495 >    property DatabaseName: string read FDatabaseName write SetDatabaseName;
496 >  end;
497 >
498 >  TUserInfo = class
499 >  public
500 >    UserName: string;
501 >    FirstName: string;
502 >    MiddleName: string;
503 >    LastName: string;
504 >    GroupID: Integer;
505 >    UserID: Integer;
506 >    AdminRole: boolean;
507 >  end;
508 >
509 >  TSecurityAction = (ActionAddUser, ActionDeleteUser, ActionModifyUser, ActionDisplayUser);
510 >  TSecurityModifyParam = (ModifyFirstName, ModifyMiddleName, ModifyLastName, ModifyUserId,
511 >                         ModifyGroupId, ModifyPassword, ModifyAdminRole);
512 >  TSecurityModifyParams = set of TSecurityModifyParam;
513 >
514 >  { TIBSecurityService }
515 >
516 >  TIBSecurityService = class(TIBControlAndQueryService)
517 >  private
518 >    FAdminRole: boolean;
519 >    FUserID: Integer;
520 >    FGroupID: Integer;
521 >    FFirstName: string;
522 >    FUserName: string;
523 >    FPassword: string;
524 >    FSQLRole: string;
525 >    FLastName: string;
526 >    FMiddleName: string;
527 >    FUserInfo: array of TUserInfo;
528 >    FSecurityAction: TSecurityAction;
529 >    FModifyParams: TSecurityModifyParams;
530 >    procedure ClearParams;
531 >    procedure SetAdminRole(AValue: boolean);
532 >    procedure SetSecurityAction (Value: TSecurityAction);
533 >    procedure SetFirstName (Value: String);
534 >    procedure SetMiddleName (Value: String);
535 >    procedure SetLastName (Value: String);
536 >    procedure SetPassword (Value: String);
537 >    procedure SetUserId (Value: Integer);
538 >    procedure SetGroupId (Value: Integer);
539 >
540 >    procedure FetchUserInfo;
541 >    function GetUserInfo(Index: Integer): TUserInfo;
542 >    function GetUserInfoCount: Integer;
543 >
544 >  protected
545 >    procedure Loaded; override;
546 >    procedure SetServiceStartOptions; override;
547 >  public
548 >    constructor Create(AOwner: TComponent); override;
549 >    destructor Destroy; override;
550 >    procedure DisplayUsers;
551 >    procedure DisplayUser(UserName: string);
552 >    procedure AddUser;
553 >    procedure DeleteUser;
554 >    procedure ModifyUser;
555 >    function HasAdminRole: boolean;
556 >    property  UserInfo[Index: Integer]: TUserInfo read GetUserInfo;
557 >    property  UserInfoCount: Integer read GetUserInfoCount;
558 >
559 >  published
560 >    property SecurityAction: TSecurityAction read FSecurityAction
561 >                                             write SetSecurityAction;
562 >    property SQlRole : string read FSQLRole write FSQLrole;
563 >    property UserName : string read FUserName write FUserName;
564 >    property FirstName : string read FFirstName write SetFirstName;
565 >    property MiddleName : string read FMiddleName write SetMiddleName;
566 >    property LastName : string read FLastName write SetLastName;
567 >    property UserID : Integer read FUserID write SetUserID;
568 >    property GroupID : Integer read FGroupID write SetGroupID;
569 >    property Password : string read FPassword write setPassword;
570 >    property AdminRole: boolean read FAdminRole write SetAdminRole;
571 >  end;
572 >
573 >
574 > implementation
575 >
576 > uses
577 >  IBSQLMonitor, FBMessages, RegExpr;
578 >
579 > { TIBOnlineValidationService }
580 >
581 > procedure TIBOnlineValidationService.SetDatabaseName(AValue: string);
582 > begin
583 >  if FDatabaseName = AValue then Exit;
584 >  FDatabaseName := AValue;
585 > end;
586 >
587 > procedure TIBOnlineValidationService.SetServiceStartOptions;
588 > begin
589 >  inherited SetServiceStartOptions;
590 >  Action := isc_action_svc_validate;
591 >  if FDatabaseName = '' then
592 >    IBError(ibxeStartParamsError, [nil]);
593 >  SRB.Add(isc_action_svc_validate);
594 >  SRB.Add(isc_spb_dbname).AsString := FDatabaseName;
595 >  if IncludeTables <> '' then
596 >    SRB.Add(isc_spb_val_tab_incl).AsString := IncludeTables;
597 >  if ExcludeTables <> '' then
598 >    SRB.Add(isc_spb_val_tab_excl).AsString := ExcludeTables;
599 >  if IncludeIndexes <> '' then
600 >    SRB.Add(isc_spb_val_idx_incl).AsString := IncludeIndexes;
601 >  if ExcludeIndexes <> '' then
602 >    SRB.Add(isc_spb_val_idx_excl).AsString := ExcludeIndexes;
603 >  if LockTimeout <> 0 then
604 >    SRB.Add(isc_spb_val_lock_timeout).AsInteger := LockTimeout;
605 > end;
606 >
607 > constructor TIBOnlineValidationService.Create(AOwner: TComponent);
608 > begin
609 >  inherited Create(AOwner);
610 >  FLockTimeout := 10;
611 > end;
612 >
613 > procedure TIBOnlineValidationService.ServiceStart;
614 > begin
615 >  {Firebird 2.5 and later}
616 >  if (ServerVersionNo[1] < 2) or
617 >             ((ServerVersionNo[1] = 2) and (ServerVersionNo[2] < 5)) then
618 >    IBError(ibxeServiceUnavailable,[]);
619 >  inherited ServiceStart;
620 > end;
621 >
622 > { TIBBackupRestoreService }
623 >
624 > procedure TIBBackupRestoreService.SetServiceStartOptions;
625 > var options: string;
626 > begin
627 >  {Firebird 2.5 and later}
628 >  if (ServerVersionNo[1] < 2) or
629 >             ((ServerVersionNo[1] = 2) and (ServerVersionNo[2] < 5)) then Exit;
630 >
631 >  if StatisticsRequested <> [] then
632 >  begin
633 >    options := '';
634 >    if bsTotalTime in StatisticsRequested then
635 >      options += 'T';
636 >    if bsTimeDelta in StatisticsRequested then
637 >      options += 'D';
638 >    if bsPageReads in StatisticsRequested then
639 >      options += 'R';
640 >    if bsPageWrites in StatisticsRequested then
641 >      options += 'W';
642 >    SRB.Add(isc_spb_bkp_stat).AsString := options;
643 >  end;
644 > end;
645 >
646 > constructor TIBBackupRestoreService.Create(AOwner: TComponent);
647 > begin
648 >  inherited Create(AOwner);
649 >  FBackupFileLocation := flServerSide;
650 > end;
651 >
652 > { TIBCustomService }
653 >
654 > procedure TIBCustomService.Attach;
655 >
656 >  procedure GetServerVersionNo;
657 >  var Req: ISRB;
658 >      Results: IServiceQueryResults;
659 >      RegexObj: TRegExpr;
660 >      s: string;
661 >  begin
662 >    Req := FService.AllocateSRB;
663 >    Req.Add(isc_info_svc_server_version);
664 >    Results := FService.Query(nil,Req);
665 >    if (Results.Count = 1) and (Results[0].getItemType = isc_info_svc_server_version) then
666 >    RegexObj := TRegExpr.Create;
667 >    try
668 >      {extact database file spec}
669 >      RegexObj.ModifierG := false; {turn off greedy matches}
670 >      RegexObj.Expression := '[A-Z][A-Z]-V([0-9]+)\.([0-9]+)\.([0-9]+)\.([0-9]+) .*';
671 >      s := Results[0].AsString;
672 >      if RegexObj.Exec(s) then
673 >      begin
674 >        FServerVersionNo[1] := StrToInt(system.copy(s,RegexObj.MatchPos[1],RegexObj.MatchLen[1]));
675 >        FServerVersionNo[2] := StrToInt(system.copy(s,RegexObj.MatchPos[2],RegexObj.MatchLen[2]));
676 >        FServerVersionNo[3] := StrToInt(system.copy(s,RegexObj.MatchPos[3],RegexObj.MatchLen[3]));
677 >        FServerVersionNo[4] := StrToInt(system.copy(s,RegexObj.MatchPos[4],RegexObj.MatchLen[4]));
678 >      end;
679 >    finally
680 >      RegexObj.Free;
681 >    end;
682 >  end;
683 >
684 > var aServerName: string;
685 >    TempSvcParams: TStrings;
686 >    SPB: ISPB;
687 >    PW: ISPBItem;
688 > begin
689 >  CheckInactive;
690 >  CheckServerName;
691 >
692 >  aServerName := FServerName;
693 >
694 >  TempSvcParams := TStringList.Create;
695 >  try
696 >    TempSvcParams.Assign(FParams);
697 >    if FLoginPrompt and not Login(aServerName,TempSvcParams) then
698 >      IBError(ibxeOperationCancelled, [nil]);
699 >    SPB := GenerateSPB(TempSvcParams);
700 >  finally
701 >    TempSvcParams.Free;
702 >  end;
703 >
704 >  FService := FirebirdAPI.GetServiceManager(aServerName,PortNo,FProtocol,SPB);
705 >  PW := FService.getSPB.Find(isc_spb_password);
706 >  if PW <> nil then PW.AsString := 'xxxxxxxx'; {Hide password}
707 >
708 >  GetServerVersionNo;
709 >
710 >  if Assigned(FOnAttach) then
711 >    FOnAttach(Self);
712 >
713 >  MonitorHook.ServiceAttach(Self);
714 > end;
715 >
716 > procedure TIBCustomService.Loaded;
717 > begin
718 >  inherited Loaded;
719 >  try
720 >    if FStreamedActive and (not Active) then
721 >      Attach;
722 >  except
723 >    if csDesigning in ComponentState then
724 >       HandleException(self)
725 >    else
726 >      raise;
727 >  end;
728 > end;
729 >
730 > function TIBCustomService.Login(var aServerName: string; LoginParams: TStrings
731 >  ): Boolean;
732 > var
733 >  IndexOfUser, IndexOfPassword: Integer;
734 >  Username, Password: String;
735 >  ExtLoginParams: TStrings;
736 > begin
737 >  if Assigned(FOnLogin) then begin
738 >    result := True;
739 >    ExtLoginParams := TStringList.Create;
740 >    try
741 >      ExtLoginParams.Assign(Params);
742 >      FOnLogin(Self, ExtLoginParams);
743 >      LoginParams.Assign (ExtLoginParams);
744 >      aServerName := ServerName;
745 >    finally
746 >      ExtLoginParams.Free;
747 >    end;
748 >  end
749 >  else
750 >  if assigned(IBGUIInterface)  then
751 >  begin
752 >    IndexOfUser := LoginParams.IndexOfName(GetSPBConstName(isc_spb_user_name));
753 >    if IndexOfUser <> -1 then
754 >      Username := LoginParams.ValueFromIndex[IndexOfUser]
755 >    else
756 >      UserName := '';
757 >    IndexOfPassword :=LoginParams.IndexOfName(GetSPBConstName(isc_spb_password));
758 >    if IndexOfPassword <> -1 then
759 >      Password := LoginParams.ValueFromIndex[IndexOfPassword]
760 >    else
761 >      Password := '';
762 >
763 >    result := IBGUIInterface.ServerLoginDialog(aServerName, Username, Password);
764 >    if result then
765 >    begin
766 >      LoginParams.Values[GetSPBConstName(isc_spb_user_name)] := UserName;
767 >      LoginParams.Values[GetSPBConstName(isc_spb_password)] := Password;
768 >    end
769 >  end
770 >  else
771 >    IBError(ibxeNoLoginDialog,[]);
772 > end;
773 >
774 > procedure TIBCustomService.CheckActive;
775 > begin
776 >  if FStreamedActive and (not Active) then
777 >    Loaded;
778 >  if FService = nil then
779 >    IBError(ibxeServiceActive, [nil]);
780 > end;
781 >
782 > procedure TIBCustomService.CheckInactive;
783 > begin
784 >  if FService <> nil then
785 >    IBError(ibxeServiceInActive, [nil]);
786 > end;
787 >
788 > procedure TIBCustomService.HandleException(Sender: TObject);
789 > var aParent: TComponent;
790 > begin
791 >  aParent := Owner;
792 >  while aParent <> nil do
793 >  begin
794 >    if aParent is TCustomApplication then
795 >    begin
796 >      TCustomApplication(aParent).HandleException(Sender);
797 >      Exit;
798 >    end;
799 >    aParent := aParent.Owner;
800 >  end;
801 >  SysUtils.ShowException(ExceptObject,ExceptAddr);
802 > end;
803 >
804 > constructor TIBCustomService.Create(AOwner: TComponent);
805 > begin
806 >  inherited Create(AOwner);
807 >  FserverName := '';
808 >  FParams := TStringList.Create;
809 >  FParamsChanged := True;
810 >  TStringList(FParams).OnChange := ParamsChange;
811 >  TStringList(FParams).OnChanging := ParamsChanging;
812 >  FLoginPrompt := True;
813 >  FTraceFlags := [];
814 >  FService := nil;
815 >  FSRB := nil;
816 >  FServiceQueryResults := nil;
817 >  FProtocol := Local;
818 >  if (AOwner <> nil) and
819 >     (AOwner is TCustomApplication) and
820 >     TCustomApplication(AOwner).ConsoleApplication then
821 >    LoginPrompt := false;
822 > end;
823 >
824 > destructor TIBCustomService.Destroy;
825 > begin
826 >  if FService <> nil then
827 >      Detach;
828 >  FSRB := nil;
829 >  FParams.Free;
830 >  FServiceQueryResults := nil;
831 >  inherited Destroy;
832 > end;
833 >
834 > procedure TIBCustomService.Detach;
835 > begin
836 >  CheckActive;
837 >  FService := nil;
838 >  MonitorHook.ServiceDetach(Self);
839 > end;
840 >
841 > procedure TIBCustomService.Assign(Source: TPersistent);
842 > begin
843 >  if Source = self then Exit;
844 >  if Source is TIBCustomService then
845 >  with Source as TIBCustomService do
846 >  begin
847 >    self.FService := nil;  {Now appears inactive}
848 >    self.FServerName := FServerName;
849 >    self.Params.Assign(Params);
850 >    self.FServerVersionNo := FServerVersionNo;
851 >    self.FProtocol := FProtocol;
852 >    self.FLoginPrompt := FLoginPrompt;
853 >    self.FService := FService;
854 >  end
855 >  else
856 >    inherited Assign(Source);
857 > end;
858 >
859 > procedure TIBCustomService.SetDBParams(DBParams: TStrings);
860 > var i: integer;
861 >    j: integer;
862 >    k: integer;
863 >    ParamName: string;
864 > begin
865 >  Params.Clear;
866 >  for i := 0 to DBParams.Count - 1 do
867 >  begin
868 >    ParamName := DBParams[i];
869 >    k := Pos('=',ParamName);
870 >    if k > 0 then system.Delete(ParamName,k,Length(ParamName)-k+1);
871 >    for j := 1 to isc_spb_last_spb_constant do
872 >      if ParamName = SPBConstantNames[j] then
873 >      begin
874 >        Params.Add(DBParams[i]);
875 >        break;
876 >      end;
877 >  end;
878 > end;
879 >
880 > function TIBCustomService.GetActive: Boolean;
881 > begin
882 >  result := FService <> nil;
883 > end;
884 >
885 > function TIBCustomService.GetServiceParamBySPB(const Idx: Integer): String;
886 > var
887 >  ConstIdx, EqualsIdx: Integer;
888 > begin
889 >  if (Idx > 0) and (Idx <= isc_spb_last_spb_constant) then
890 >  begin
891 >    ConstIdx := IndexOfSPBConst(Idx,Params);
892 >    if ConstIdx = -1 then
893 >      result := ''
894 >    else
895 >    begin
896 >      result := Params[ConstIdx];
897 >      EqualsIdx := Pos('=', result); {mbcs ok}
898 >      if EqualsIdx = 0 then
899 >        result := ''
900 >      else
901 >        result := Copy(result, EqualsIdx + 1, Length(result));
902 >    end;
903 >  end
904 >  else
905 >    result := '';
906 > end;
907 >
908 > function TIBCustomService.GetSQPB: ISQPB;
909 > begin
910 >  CheckActive;
911 >  if FSQPB = nil then
912 >    FSQPB := FService.AllocateSQPB;
913 >  Result := FSQPB;
914 > end;
915 >
916 > function TIBCustomService.GetSRB: ISRB;
917 > begin
918 >  CheckActive;
919 >  if FSRB = nil then
920 >    FSRB := FService.AllocateSRB;
921 >  Result := FSRB;
922 > end;
923 >
924 > function TIBCustomService.GetServerVersionNo(index: integer): integer;
925 > begin
926 >  CheckActive;
927 >  if (index >= Low(FServerVersionNo)) and (index <= High(FServerVersionNo)) then
928 >    Result := FServerVersionNo[index]
929 >  else
930 >    IBError(ibxeInfoBufferIndexError,[index]);
931 > end;
932 >
933 > procedure TIBCustomService.InternalServiceQuery;
934 > begin
935 >  CheckActive;
936 >  try
937 >    FServiceQueryResults := FService.Query(FSQPB,FSRB);
938 >  finally
939 >    FSQPB := nil;
940 >    FSRB := nil;
941 >  end;
942 >  MonitorHook.ServiceQuery(Self);
943 > end;
944 >
945 > procedure TIBCustomService.SetActive(const Value: Boolean);
946 > begin
947 >  if csReading in ComponentState then
948 >    FStreamedActive := Value
949 >  else
950 >  if Value = Active then Exit;
951 >
952 >  if Value then
953 >    Attach
954 >  else
955 >    Detach;
956 > end;
957 >
958 > procedure TIBCustomService.SetParams(const Value: TStrings);
959 > begin
960 >  FParams.Assign(Value);
961 > end;
962 >
963 > procedure TIBCustomService.SetServerName(const Value: string);
964 > begin
965 >  if FServerName <> Value then
966 >  begin
967 >    CheckInactive;
968 >    FServerName := Value;
969 >  end;
970 > end;
971 >
972 > procedure TIBCustomService.SetProtocol(const Value: TProtocol);
973 > begin
974 >  if FProtocol <> Value then
975 >  begin
976 >    CheckInactive;
977 >    FProtocol := Value;
978 >    if (Value = Local) then
979 >      FServerName := '';
980 >  end;
981 > end;
982 >
983 > procedure TIBCustomService.SetService(AValue: IServiceManager);
984 > begin
985 >  if FService = AValue then Exit;
986 >  FService := AValue;
987 >  if AValue <> nil then
988 >    FServerName := FService.getServerName;
989 > end;
990 >
991 > procedure TIBCustomService.SetServiceParamBySPB(const Idx: Integer;
992 >  const Value: String);
993 > var
994 >  ConstIdx: Integer;
995 > begin
996 >  ConstIdx := IndexOfSPBConst(Idx,Params);
997 >  if (Value = '') then
998 >  begin
999 >    if ConstIdx <> -1 then
1000 >      Params.Delete(ConstIdx);
1001 >  end
1002 >  else
1003 >  begin
1004 >    if (ConstIdx = -1) then
1005 >      Params.Add(GetSPBConstName(Idx) + '=' + Value)
1006 >    else
1007 >      Params[ConstIdx] := GetSPBConstName(Idx) + '=' + Value;
1008 >  end;
1009 > end;
1010 >
1011 > function TIBCustomService.IndexOfSPBConst(action: byte; List: TStrings): Integer;
1012 > var
1013 >  i,  pos_of_str: Integer;
1014 >  st: string;
1015 > begin
1016 >  result := -1;
1017 >  st := GetSPBConstName(action);
1018 >  if st <> '' then
1019 >  for i := 0 to List.Count - 1 do
1020 >  begin
1021 >    pos_of_str := Pos(st, List[i]); {mbcs ok}
1022 >    if (pos_of_str = 1) or (pos_of_str = Length(SPBPrefix) + 1) then
1023 >    begin
1024 >      result := i;
1025 >      break;
1026 >    end;
1027 >  end;
1028 > end;
1029 >
1030 > function TIBCustomService.GetSPBConstName(action: byte): string;
1031 > var i: integer;
1032 > begin
1033 >  Result := '';
1034 >  for i := Low(SPBConstantValues) to High(SPBConstantValues) do
1035 >    if SPBConstantValues[i] = action then
1036 >    begin
1037 >      Result := SPBConstantNames[i];
1038 >      break;
1039 >    end;
1040 > end;
1041 >
1042 > procedure TIBCustomService.ParamsChange(Sender: TObject);
1043 > begin
1044 >  FParamsChanged := True;
1045 > end;
1046 >
1047 > procedure TIBCustomService.ParamsChanging(Sender: TObject);
1048 > begin
1049 >  CheckInactive;
1050 > end;
1051 >
1052 > procedure TIBCustomService.CheckServerName;
1053 > begin
1054 >  if (FServerName = '') and (FProtocol <> Local) then
1055 >    IBError(ibxeServerNameMissing, [nil]);
1056 > end;
1057 >
1058 > {
1059 > * GenerateSPB -
1060 > *  Given a string containing a textual representation
1061 > *  of the Service parameters, generate a service
1062 > *  parameter buffer, and return it .
1063 > }
1064 > function TIBCustomService.GenerateSPB(sl: TStrings): ISPB;
1065 > var
1066 >  i, j, SPBServerVal: UShort;
1067 >  param_name, param_value: String;
1068 > begin
1069 >  { The SPB is initially empty, with the exception that
1070 >   the SPB version must be the first byte of the string.
1071 >  }
1072 >  Result := FirebirdAPI.AllocateSPB;
1073 >
1074 >  { Iterate through the textual service parameters, constructing
1075 >   a SPB on-the-fly }
1076 >  if sl.Count > 0 then
1077 >  for i := 0 to sl.Count - 1 do
1078 >  begin
1079 >   { Get the parameter's name and value from the list,
1080 >     and make sure that the name is all lowercase with
1081 >     no leading 'isc_spb_' prefix }
1082 >    if (Trim(sl.Names[i]) = '') then continue;
1083 >    param_name := LowerCase(sl.Names[i]); {mbcs ok}
1084 >    param_value := Copy(sl[i], Pos('=', sl[i]) + 1, Length(sl[i])); {mbcs ok}
1085 >    if (Pos(SPBPrefix, param_name) = 1) then {mbcs ok}
1086 >      Delete(param_name, 1, Length(SPBPrefix));
1087 >    { We want to translate the parameter name to some integer
1088 >      value. We do this by scanning through a list of known
1089 >      service parameter names (SPBConstantNames, defined above). }
1090 >    SPBServerVal := 0;
1091 >    { Find the parameter }
1092 >    for j := 1 to isc_spb_last_spb_constant do
1093 >      if (param_name = SPBConstantNames[j]) then
1094 >      begin
1095 >        SPBServerVal := SPBConstantValues[j];
1096 >        break;
1097 >      end;
1098 >    case SPBServerVal of
1099 >      isc_spb_user_name,
1100 >      isc_spb_password,
1101 >      isc_spb_sql_role_name,
1102 >      isc_spb_expected_db:
1103 >        Result.Add(SPBServerVal).AsString := param_value;
1104 >      else
1105 >      begin
1106 >        if GetSPBConstName(SPBServerVal) <> '' then
1107 >          IBError(ibxeSPBConstantNotSupported,
1108 >                   [GetSPBConstName(SPBServerVal)])
1109 >        else
1110 >          IBError(ibxeSPBConstantUnknown, [SPBServerVal]);
1111 >      end;
1112 >    end;
1113 >  end;
1114 > end;
1115 >
1116 > { TIBServerProperties }
1117 > constructor TIBServerProperties.Create(AOwner: TComponent);
1118 > begin
1119 >  inherited Create(AOwner);
1120 >  FDatabaseInfo := TDatabaseInfo.Create;
1121 >  FLicenseInfo := TLicenseInfo.Create;
1122 >  FLicenseMaskInfo := TLicenseMaskInfo.Create;
1123 >  FVersionInfo := TVersionInfo.Create;
1124 >  FConfigParams := TConfigParams.Create;
1125 > end;
1126 >
1127 > destructor TIBServerProperties.Destroy;
1128 > begin
1129 >  FDatabaseInfo.Free;
1130 >  FLicenseInfo.Free;
1131 >  FLicenseMaskInfo.Free;
1132 >  FVersionInfo.Free;
1133 >  FConfigParams.Free;
1134 >  inherited Destroy;
1135 > end;
1136 >
1137 > procedure TIBServerProperties.Fetch;
1138 > begin
1139 >  if (Database in Options) then
1140 >    FetchDatabaseInfo;
1141 >  if (License in Options) then
1142 >    FetchLicenseInfo;
1143 >  if (LicenseMask in Options) then
1144 >    FetchLicenseMaskInfo;
1145 >  if (ConfigParameters in Options) then
1146 >    FetchConfigParams;
1147 >  if (Version in Options) then
1148 >    FetchVersionInfo;
1149 > end;
1150 >
1151 > procedure TIBServerProperties.FetchConfigParams;
1152 > var
1153 >  i, j: Integer;
1154 >
1155 > begin
1156 >  SRB.Add(isc_info_svc_get_config);
1157 >  SRB.Add(isc_info_svc_get_env);
1158 >  SRB.Add(isc_info_svc_get_env_lock);
1159 >  SRB.Add(isc_info_svc_get_env_msg);
1160 >  SRB.Add(isc_info_svc_user_dbpath);
1161 >
1162 >  InternalServiceQuery;
1163 >
1164 >  for i := 0 to FServiceQueryResults.Count - 1 do
1165 >  with FServiceQueryResults[i] do
1166 >  begin
1167 >    case getItemType of
1168 >      isc_info_svc_get_config:
1169 >      begin
1170 >        SetLength (FConfigParams.ConfigFileData.ConfigFileValue, Count);
1171 >        SetLength (FConfigParams.ConfigFileData.ConfigFileKey, Count);
1172 >
1173 >        for j := 0 to Count - 1 do
1174 >        begin
1175 >          FConfigParams.ConfigFileData.ConfigFileKey[j] := Items[j].getItemType;
1176 >          FConfigParams.ConfigFileData.ConfigFileValue[j] := Items[j].AsInteger;
1177 >        end;
1178 >      end;
1179 >
1180 >      isc_info_svc_get_env:
1181 >        FConfigParams.BaseLocation := AsString;
1182 >
1183 >      isc_info_svc_get_env_lock:
1184 >        FConfigParams.LockFileLocation := AsString;
1185 >
1186 >      isc_info_svc_get_env_msg:
1187 >        FConfigParams.MessageFileLocation := AsString;
1188 >
1189 >      isc_info_svc_user_dbpath:
1190 >        FConfigParams.SecurityDatabaseLocation := AsString;
1191 >
1192 >      else
1193 >        IBError(ibxeOutputParsingError, [getItemType]);
1194 >    end;
1195 >  end;
1196 > end;
1197 >
1198 > procedure TIBServerProperties.FetchDatabaseInfo;
1199 > var
1200 >  i,j: Integer;
1201 > begin
1202 >  SRB.Add(isc_info_svc_svr_db_info);
1203 >  InternalServiceQuery;
1204 >
1205 >  SetLength(FDatabaseInfo.DbName,0);
1206 >  for i := 0 to FServiceQueryResults.Count - 1 do
1207 >  with FServiceQueryResults[i] do
1208 >  begin
1209 >    case getItemType of
1210 >      isc_info_svc_svr_db_info:
1211 >        for j := 0 to FServiceQueryResults[i].Count - 1 do
1212 >        with FServiceQueryResults[i][j] do
1213 >        case getItemType of
1214 >        isc_spb_num_att:
1215 >          FDatabaseInfo.NoOfAttachments := AsInteger;
1216 >
1217 >        isc_spb_num_db:
1218 >          FDatabaseInfo.NoOfDatabases := AsInteger;
1219 >
1220 >        isc_spb_dbname:
1221 >          begin
1222 >            SetLength(FDatabaseInfo.DbName,length(FDatabaseInfo.DbName)+1);
1223 >            FDatabaseInfo.DbName[length(FDatabaseInfo.DbName)-1] := AsString;
1224 >          end;
1225 >        else
1226 >          IBError(ibxeOutputParsingError, [getItemType]);
1227 >        end;
1228 >      else
1229 >        IBError(ibxeOutputParsingError, [getItemType]);
1230 >    end;
1231 > end;
1232 > end;
1233 >
1234 > procedure TIBServerProperties.FetchLicenseInfo;
1235 > var
1236 >  i,j : Integer;
1237 > begin
1238 >  SRB.Add(isc_info_svc_get_license);
1239 >  SRB.Add(isc_info_svc_get_licensed_users);
1240 >  InternalServiceQuery;
1241 >
1242 >  SetLength(FLicenseInfo.key, 0);
1243 >  SetLength(FLicenseInfo.id, 0);
1244 >  SetLength(FLicenseInfo.desc, 0);
1245 >
1246 >  for i := 0 to FServiceQueryResults.Count - 1 do
1247 >  with FServiceQueryResults[i] do
1248 >  begin
1249 >    case getItemType of
1250 >      isc_info_svc_get_license:
1251 >        begin
1252 >          SetLength(FLicenseInfo.key, Count);
1253 >          SetLength(FLicenseInfo.id, Count);
1254 >          SetLength(FLicenseInfo.desc, Count);
1255 >
1256 >          for j := 0 to Count -1 do
1257 >          with Items[j] do
1258 >          case getItemType of
1259 >             isc_spb_lic_id:
1260 >                FLicenseInfo.id[j] := AsString;
1261 >
1262 >             isc_spb_lic_key:
1263 >                FLicenseInfo.key[j] := AsString;
1264 >
1265 >             isc_spb_lic_desc:
1266 >               FLicenseInfo.desc[j] := AsString;
1267 >          else
1268 >            IBError(ibxeOutputParsingError, [getItemType]);
1269 >          end;
1270 >        end;
1271 >      else
1272 >        IBError(ibxeOutputParsingError, [getItemType]);
1273 >    end;
1274 >  end;
1275 > end;
1276 >
1277 > procedure TIBServerProperties.FetchLicenseMaskInfo();
1278 > var
1279 >  i : Integer;
1280 > begin
1281 >  SRB.Add(isc_info_svc_get_license_mask);
1282 >  SRB.Add(isc_info_svc_capabilities);
1283 >  InternalServiceQuery;
1284 >
1285 >  for i := 0 to FServiceQueryResults.Count - 1 do
1286 >  with FServiceQueryResults[i] do
1287 >  begin
1288 >    case getItemType of
1289 >      isc_info_svc_get_license_mask:
1290 >        FLicenseMaskInfo.LicenseMask := AsInteger;
1291 >      isc_info_svc_capabilities:
1292 >        FLicenseMaskInfo.CapabilityMask := AsInteger;
1293 >      else
1294 >        IBError(ibxeOutputParsingError, [getItemType]);
1295 >    end;
1296 >  end;
1297 > end;
1298 >
1299 >
1300 > procedure TIBServerProperties.FetchVersionInfo;
1301 > var
1302 >  i : Integer;
1303 > begin
1304 >  SRB.Add(isc_info_svc_version);
1305 >  SRB.Add(isc_info_svc_server_version);
1306 >  SRB.Add(isc_info_svc_implementation);
1307 >  InternalServiceQuery;
1308 >
1309 >  for i := 0 to FServiceQueryResults.Count - 1 do
1310 >  with FServiceQueryResults[i] do
1311 >  begin
1312 >    case getItemType of
1313 >      isc_info_svc_version:
1314 >        FVersionInfo.ServiceVersion := AsInteger;
1315 >      isc_info_svc_server_version:
1316 >        FVersionInfo.ServerVersion := AsString;
1317 >      isc_info_svc_implementation:
1318 >        FVersionInfo.ServerImplementation := AsString;
1319 >      else
1320 >        IBError(ibxeOutputParsingError, [getItemType]);
1321 >    end;
1322 >  end;
1323 > end;
1324 >
1325 > { TIBControlService }
1326 >
1327 > procedure TIBControlService.SetServiceStartOptions;
1328 > begin
1329 >
1330 > end;
1331 >
1332 > function TIBControlService.GetIsServiceRunning: Boolean;
1333 > begin
1334 >  SRB.Add(isc_info_svc_running);
1335 >  InternalServiceQuery;
1336 >
1337 >  Result := (FServiceQueryResults.Count > 0) and
1338 >             (FServiceQueryResults[0].getItemType = isc_info_svc_running) and
1339 >              (FServiceQueryResults[0].AsInteger = 1);
1340 > end;
1341 >
1342 > procedure TIBControlService.CheckServiceNotRunning;
1343 > begin
1344 >  if IsServiceRunning then
1345 >    IBError(ibxeServiceRunning,[nil]);
1346 > end;
1347 >
1348 > constructor TIBControlService.Create(AOwner: TComponent);
1349 > begin
1350 >  inherited create(AOwner);
1351 >  FSRB := nil;
1352 > end;
1353 >
1354 > procedure TIBControlService.InternalServiceStart;
1355 > begin
1356 >  if SRB = nil then
1357 >    IBError(ibxeStartParamsError, [nil]);
1358 >
1359 >  try
1360 >    FService.Start(SRB);
1361 >  finally
1362 >    FSRB := nil;
1363 >  end;
1364 >  MonitorHook.ServiceStart(Self);
1365 > end;
1366 >
1367 > procedure TIBControlService.ServiceStart;
1368 > begin
1369 >  CheckActive;
1370 >  CheckServiceNotRunning;
1371 >  SetServiceStartOptions;
1372 >  InternalServiceStart;
1373 > end;
1374 >
1375 > { TIBConfigService }
1376 >
1377 > procedure TIBConfigService.ServiceStart;
1378 > begin
1379 >  IBError(ibxeUseSpecificProcedures, [nil]);
1380 > end;
1381 >
1382 > procedure TIBConfigService.ActivateShadow;
1383 > begin
1384 >  SRB.Add(isc_action_svc_properties);
1385 >  SRB.Add(isc_spb_dbname).AsString :=  FDatabaseName;
1386 >  SRB.Add(isc_spb_options).AsInteger := isc_spb_prp_activate;
1387 >  InternalServiceStart;
1388 > end;
1389 >
1390 > procedure TIBConfigService.BringDatabaseOnline;
1391 > begin
1392 >  SRB.Add(isc_action_svc_properties);
1393 >  SRB.Add(isc_spb_dbname).AsString :=  FDatabaseName;
1394 >  SRB.Add(isc_spb_options).AsInteger := isc_spb_prp_db_online;
1395 >  InternalServiceStart;
1396 > end;
1397 >
1398 > procedure TIBConfigService.SetAsyncMode(Value: Boolean);
1399 > begin
1400 >  SRB.Add(isc_action_svc_properties);
1401 >  SRB.Add(isc_spb_dbname).AsString :=  FDatabaseName;
1402 >  with SRB.Add(isc_spb_prp_write_mode) do
1403 >  if Value then
1404 >    AsByte := isc_spb_prp_wm_async
1405 >  else
1406 >    AsByte := isc_spb_prp_wm_sync;
1407 >  InternalServiceStart;
1408 > end;
1409 >
1410 > procedure TIBConfigService.SetDatabaseName(const Value: string);
1411 > begin
1412 >  FDatabaseName := Value;
1413 > end;
1414 >
1415 > procedure TIBConfigService.SetPageBuffers(Value: Integer);
1416 > begin
1417 >  SRB.Add(isc_action_svc_properties);
1418 >  SRB.Add(isc_spb_dbname).AsString :=  FDatabaseName;
1419 >  SRB.Add(isc_spb_prp_page_buffers).AsInteger := Value;
1420 >  InternalServiceStart;
1421 > end;
1422 >
1423 > procedure TIBConfigService.SetReadOnly(Value: Boolean);
1424 > begin
1425 >  SRB.Add(isc_action_svc_properties);
1426 >  SRB.Add(isc_spb_dbname).AsString :=  FDatabaseName;
1427 >  with SRB.Add(isc_spb_prp_access_mode) do
1428 >  if Value then
1429 >    AsByte := isc_spb_prp_am_readonly
1430 >  else
1431 >    AsByte := isc_spb_prp_am_readwrite;
1432 >  InternalServiceStart;
1433 > end;
1434 >
1435 > procedure TIBConfigService.SetAutoAdmin(Value: Boolean);
1436 > begin
1437 >  {only available for Firebird 2.5 and later}
1438 >  if (ServerVersionNo[1] < 2) or
1439 >             ((ServerVersionNo[1] = 2) and (ServerVersionNo[2] < 5)) then Exit;
1440 >  if Value then
1441 >    SRB.Add(isc_action_svc_set_mapping)
1442 >  else
1443 >    SRB.Add(isc_action_svc_drop_mapping);
1444 >  InternalServiceStart;
1445 > end;
1446 >
1447 > procedure TIBConfigService.SetNoLinger;
1448 > begin
1449 >  SRB.Add(isc_action_svc_properties);
1450 >  SRB.Add(isc_spb_dbname).AsString :=  FDatabaseName;
1451 >  SRB.Add(isc_spb_options).AsInteger := isc_spb_prp_nolinger;
1452 >  InternalServiceStart;
1453 > end;
1454 >
1455 > procedure TIBConfigService.SetReserveSpace(Value: Boolean);
1456 > begin
1457 >  SRB.Add(isc_action_svc_properties);
1458 >  SRB.Add(isc_spb_dbname).AsString :=  FDatabaseName;
1459 >  with SRB.Add(isc_spb_prp_reserve_space) do
1460 >  if Value then
1461 >    AsByte := isc_spb_prp_res
1462 >  else
1463 >    AsByte := isc_spb_prp_res_use_full;
1464 >  InternalServiceStart;
1465 > end;
1466 >
1467 > procedure TIBConfigService.SetSweepInterval(Value: Integer);
1468 > begin
1469 >  SRB.Add(isc_action_svc_properties);
1470 >  SRB.Add(isc_spb_dbname).AsString :=  FDatabaseName;
1471 >  SRB.Add(isc_spb_prp_sweep_interval).AsInteger := Value;
1472 >  InternalServiceStart;
1473 > end;
1474 >
1475 > procedure TIBConfigService.SetDBSqlDialect(Value: Integer);
1476 > begin
1477 >  SRB.Add(isc_action_svc_properties);
1478 >  SRB.Add(isc_spb_dbname).AsString :=  FDatabaseName;
1479 >  SRB.Add(isc_spb_prp_set_sql_dialect).AsInteger := Value;
1480 >  InternalServiceStart;
1481 > end;
1482 >
1483 > procedure TIBConfigService.ShutdownDatabase(Options: TShutdownMode;
1484 >  Wait: Integer);
1485 > begin
1486 >  SRB.Add(isc_action_svc_properties);
1487 >  SRB.Add(isc_spb_dbname).AsString :=  FDatabaseName;
1488 >  if (Options = Forced) then
1489 >  SRB.Add(isc_spb_prp_shutdown_db).AsInteger := Wait
1490 >  else if (Options = DenyTransaction) then
1491 >    SRB.Add(isc_spb_prp_deny_new_transactions).AsInteger := Wait
1492 >  else
1493 >    SRB.Add(isc_spb_prp_deny_new_attachments).AsInteger := Wait;
1494 >  InternalServiceStart;
1495 > end;
1496 >
1497 >
1498 > { TIBStatisticalService }
1499 >
1500 > procedure TIBStatisticalService.SetDatabaseName(const Value: string);
1501 > begin
1502 >  FDatabaseName := Value;
1503 > end;
1504 >
1505 > procedure TIBStatisticalService.SetServiceStartOptions;
1506 > var param: integer;
1507 > begin
1508 >  if FDatabaseName = '' then
1509 >    IBError(ibxeStartParamsError, [nil]);
1510 >
1511 >  param := 0;
1512 >  if (DataPages in Options) then
1513 >    param := param or isc_spb_sts_data_pages;
1514 > {  if (DbLog in Options) then
1515 >    param := param or isc_spb_sts_db_log; -- removed from Firebird 2}
1516 >  if (HeaderPages in Options) then
1517 >    param := param or isc_spb_sts_hdr_pages;
1518 >  if (IndexPages in Options) then
1519 >    param := param or isc_spb_sts_idx_pages;
1520 >  if (SystemRelations in Options) then
1521 >    param := param or isc_spb_sts_sys_relations;
1522 >  Action := isc_action_svc_db_stats;
1523 >  SRB.Add(isc_action_svc_db_stats);
1524 >  SRB.Add(isc_spb_dbname).AsString := FDatabaseName;
1525 >  SRB.Add(isc_spb_options).AsInteger := param;
1526 > end;
1527 >
1528 > { TIBBackupService }
1529 > procedure TIBBackupService.SetServiceStartOptions;
1530 > var
1531 >  param, i: Integer;
1532 >  value: String;
1533 > begin
1534 >  if FDatabaseName = '' then
1535 >    IBError(ibxeStartParamsError, [nil]);
1536 >  param := 0;
1537 >  if (IgnoreChecksums in Options) then
1538 >    param := param or isc_spb_bkp_ignore_checksums;
1539 >  if (IgnoreLimbo in Options) then
1540 >    param := param or isc_spb_bkp_ignore_limbo;
1541 >  if (MetadataOnly in Options) then
1542 >    param := param or isc_spb_bkp_metadata_only;
1543 >  if (NoGarbageCollection in Options) then
1544 >    param := param or isc_spb_bkp_no_garbage_collect;
1545 >  if (OldMetadataDesc in Options) then
1546 >    param := param or isc_spb_bkp_old_descriptions;
1547 >  if (NonTransportable in Options) then
1548 >    param := param or isc_spb_bkp_non_transportable;
1549 >  if (ConvertExtTables in Options) then
1550 >    param := param or isc_spb_bkp_convert;
1551 >  {Firebird 2.5 and later}
1552 >  if (ServerVersionNo[1] > 2) or
1553 >             ((ServerVersionNo[1] = 2) and (ServerVersionNo[2] = 5)) then
1554 >  begin
1555 >    if (NoDBTriggers in Options) then
1556 >      param := param or isc_spb_bkp_no_triggers;
1557 >  end;
1558 >  Action := isc_action_svc_backup;
1559 >  SRB.Add(isc_action_svc_backup);
1560 >  SRB.Add(isc_spb_dbname).AsString := FDatabaseName;
1561 >  SRB.Add(isc_spb_options).AsInteger := param;
1562 >  if Verbose  and (BackupFileLocation = flServerSide) then
1563 >  begin
1564 >    SRB.Add(isc_spb_verbose);
1565 >    inherited SetServiceStartOptions;
1566 >  end;
1567 >  if FBlockingFactor > 0 then
1568 >    SRB.Add(isc_spb_bkp_factor).AsInteger := FBlockingFactor;
1569 >  if BackupFileLocation = flServerSide then
1570 >  for i := 0 to FBackupFile.Count - 1 do
1571 >  begin
1572 >    if (Trim(FBackupFile[i]) = '') then
1573 >      continue;
1574 >    if (Pos('=', FBackupFile[i]) <> 0) then
1575 >    begin {mbcs ok}
1576 >      SRB.Add(isc_spb_bkp_file).AsString := FBackupFile.Names[i];
1577 >      value := Copy(FBackupFile[i], Pos('=', FBackupFile[i]) + 1, Length(FBackupFile.Names[i])); {mbcs ok}
1578 >      SRB.Add(isc_spb_bkp_length).AsInteger := StrToInt(value);;
1579 >    end
1580 >    else
1581 >      SRB.Add(isc_spb_bkp_file).AsString := FBackupFile[i];
1582 >  end
1583 >  else
1584 >  SRB.Add(isc_spb_bkp_file).AsString := 'stdout';
1585 > end;
1586 >
1587 > constructor TIBBackupService.Create(AOwner: TComponent);
1588 > begin
1589 >  inherited Create(AOwner);
1590 >  FBackupFile := TStringList.Create;
1591 > end;
1592 >
1593 > destructor TIBBackupService.Destroy;
1594 > begin
1595 >  FBackupFile.Free;
1596 >  inherited Destroy;
1597 > end;
1598 >
1599 > procedure TIBBackupService.SetBackupFile(const Value: TStrings);
1600 > begin
1601 >  FBackupFile.Assign(Value);
1602 > end;
1603 >
1604 > { TIBRestoreService }
1605 >
1606 > procedure TIBRestoreService.SetServiceStartOptions;
1607 > var
1608 >  param, i: Integer;
1609 >  value: String;
1610 > begin
1611 >  param := 0;
1612 >  if (DeactivateIndexes in Options) then
1613 >    param := param or isc_spb_res_deactivate_idx;
1614 >  if (NoShadow in Options) then
1615 >    param := param or isc_spb_res_no_shadow;
1616 >  if (NoValidityCheck in Options) then
1617 >    param := param or isc_spb_res_no_validity;
1618 >  if (OneRelationAtATime in Options) then
1619 >    param := param or isc_spb_res_one_at_a_time;
1620 >  if (Replace in Options) then
1621 >    param := param or isc_spb_res_replace;
1622 >  if (CreateNewDB in Options) then
1623 >    param := param or isc_spb_res_create;
1624 >  if (UseAllSpace in Options) then
1625 >    param := param or isc_spb_res_use_all_space;
1626 >  if (RestoreMetaDataOnly in Options) then
1627 >    param := param or isc_spb_res_metadata_only;
1628 >  Action := isc_action_svc_restore;
1629 >  SRB.Add(isc_action_svc_restore);
1630 >  SRB.Add(isc_spb_options).AsInteger := param;
1631 >  if Verbose then
1632 >  begin
1633 >    SRB.Add(isc_spb_verbose);
1634 >    inherited SetServiceStartOptions;
1635 >  end;
1636 >  if FPageSize > 0 then
1637 >    SRB.Add(isc_spb_res_page_size).AsInteger := FPageSize;
1638 >  if FPageBuffers > 0 then
1639 >    SRB.Add(isc_spb_res_buffers).AsInteger := FPageBuffers;
1640 >  if BackupFileLocation = flServerSide then
1641 >  for i := 0 to FBackupFile.Count - 1 do
1642 >  begin
1643 >    if (Trim(FBackupFile[i]) = '') then continue;
1644 >    if (Pos('=', FBackupFile[i]) <> 0) then  {mbcs ok}
1645 >    begin
1646 >      SRB.Add(isc_spb_bkp_file).AsString := FBackupFile.Names[i];
1647 >      value := Copy(FBackupFile[i], Pos('=', FBackupFile[i]) + 1, Length(FBackupFile.Names[i])); {mbcs ok}
1648 >      SRB.Add(isc_spb_bkp_length).AsInteger := StrToInt(value);;
1649 >    end
1650 >    else
1651 >      SRB.Add(isc_spb_bkp_file).AsString := FBackupFile[i];
1652 >  end
1653 >  else
1654 >    SRB.Add(isc_spb_bkp_file).AsString := 'stdin';
1655 >
1656 >  for i := 0 to FDatabaseName.Count - 1 do
1657 >  begin
1658 >    if (Trim(FDatabaseName[i]) = '') then continue;
1659 >    if (Pos('=', FDatabaseName[i]) <> 0) then {mbcs ok}
1660 >    begin
1661 >      SRB.Add(isc_spb_dbname).AsString := FDatabaseName.Names[i];
1662 >      value := Copy(FDatabaseName[i], Pos('=', FDatabaseName[i]) + 1, Length(FDatabaseName[i])); {mbcs ok}
1663 >      SRB.Add(isc_spb_res_length).AsInteger :=  StrToInt(value);
1664 >    end
1665 >    else
1666 >      SRB.Add(isc_spb_dbname).AsString := FDatabaseName[i];
1667 >  end;
1668 > end;
1669 >
1670 > constructor TIBRestoreService.Create(AOwner: TComponent);
1671 > begin
1672 >  inherited Create(AOwner);
1673 >  FDatabaseName := TStringList.Create;
1674 >  FBackupFile := TStringList.Create;
1675 >  Include (FOptions, CreateNewDB);
1676 > end;
1677 >
1678 > destructor TIBRestoreService.Destroy;
1679 > begin
1680 >  FDatabaseName.Free;
1681 >  FBackupFile.Free;
1682 >  inherited Destroy;
1683 > end;
1684 >
1685 > function TIBRestoreService.SendNextChunk(stream: TStream; var line: String
1686 >  ): integer;
1687 > var
1688 >  i: Integer;
1689 > begin
1690 >  Result := 0;
1691 >  line := '';
1692 >  if (FEof = True) then
1693 >    exit;
1694 >
1695 >  if (FAction = 0) then
1696 >    IBError(ibxeQueryParamsError, [nil]);
1697 >
1698 >  SRB.Add(isc_info_svc_line);
1699 >  SRB.Add(isc_info_svc_stdin);
1700 >
1701 >  SQPB.Add(isc_info_svc_timeout).AsInteger := 1;
1702 >  if FSendBytes > 0 then
1703 >    Result := SQPB.Add(isc_info_svc_line).CopyFrom(stream,FSendBytes);
1704 >  try
1705 >    InternalServiceQuery;
1706 >  except
1707 >    FSendBytes := 0;
1708 >    raise;
1709 >  end;
1710 >
1711 >  FSendBytes := 0;
1712 >  for i := 0 to FServiceQueryResults.Count - 1 do
1713 >  with FServiceQueryResults[i] do
1714 >  begin
1715 >    case getItemType of
1716 >      isc_info_svc_line:
1717 >         line := AsString;
1718 >
1719 >      isc_info_svc_stdin:
1720 >        FSendBytes := AsInteger;
1721 >
1722 >      isc_info_svc_timeout,
1723 >      isc_info_data_not_ready:
1724 >        {ignore};
1725 >    else
1726 >      IBError(ibxeOutputParsingError, [getItemType]);
1727 >    end;
1728 >  end;
1729 >  FEOF := (FSendBytes = 0) and (line = '');
1730 > end;
1731 >
1732 > procedure TIBRestoreService.SetBackupFile(const Value: TStrings);
1733 > begin
1734 >  FBackupFile.Assign(Value);
1735 > end;
1736 >
1737 > procedure TIBRestoreService.SetDatabaseName(const Value: TStrings);
1738 > begin
1739 >  FDatabaseName.Assign(Value);
1740 > end;
1741 >
1742 > { TIBValidationService }
1743 > constructor TIBValidationService.Create(AOwner: TComponent);
1744 > begin
1745 >  inherited Create(AOwner);
1746 > end;
1747 >
1748 > destructor TIBValidationService.Destroy;
1749 > var
1750 >  i : Integer;
1751 > begin
1752 >  for i := 0 to High(FLimboTransactionInfo) do
1753 >    FLimboTransactionInfo[i].Free;
1754 >  FLimboTransactionInfo := nil;
1755 >  inherited Destroy;
1756 > end;
1757 >
1758 > procedure TIBValidationService.FetchLimboTransactionInfo;
1759 >
1760 >  procedure NextLimboTransaction(index: integer);
1761 >  begin
1762 >    SetLength(FLimboTransactionInfo, index+1);
1763 >    FLimboTransactionInfo[index] := TLimboTransactionInfo.Create;
1764 >    { if no advice commit as default }
1765 >    FLimboTransactionInfo[index].Advise := UnknownAdvise;
1766 >    FLimboTransactionInfo[index].Action:= CommitAction;
1767 >  end;
1768 >
1769 > var
1770 >  i,j, k: Integer;
1771 > begin
1772 >  for i := 0 to High(FLimboTransactionInfo) do
1773 >    FLimboTransactionInfo[i].Free;
1774 >  SetLength(FLimboTransactionInfo,0);
1775 >
1776 >  SRB.Add(isc_info_svc_limbo_trans);
1777 >  InternalServiceQuery;
1778 >
1779 >  k := -1;
1780 >  for i := 0 to FServiceQueryResults.Count - 1 do
1781 >  with FServiceQueryResults[i] do
1782 >  case getItemType of
1783 >  isc_info_svc_limbo_trans:
1784 >    begin
1785 >      if FServiceQueryResults[i].Count = 0 then continue;
1786 >      NextLimboTransaction(0);
1787 >      for j := 0 to FServiceQueryResults[i].Count - 1 do
1788 >      begin
1789 >        with FServiceQueryResults[i][j] do
1790 >        begin
1791 >          case getItemType of
1792 >            isc_spb_single_tra_id:
1793 >            begin
1794 >              Inc(k);
1795 >              if k > 0 then
1796 >                NextLimboTransaction(k);
1797 >              FLimboTransactionInfo[k].MultiDatabase := False;
1798 >              FLimboTransactionInfo[k].ID := AsInteger;
1799 >            end;
1800 >
1801 >            isc_spb_multi_tra_id:
1802 >            begin
1803 >              Inc(k);
1804 >              if k > 0 then
1805 >                NextLimboTransaction(k);
1806 >              FLimboTransactionInfo[k].MultiDatabase := True;
1807 >              FLimboTransactionInfo[k].ID := AsInteger;
1808 >            end;
1809 >
1810 >            isc_spb_tra_host_site:
1811 >              FLimboTransactionInfo[k].HostSite := AsString;
1812 >
1813 >            isc_spb_tra_state:
1814 >              case AsByte of
1815 >                isc_spb_tra_state_limbo:
1816 >                  FLimboTransactionInfo[k].State := LimboState;
1817 >
1818 >                isc_spb_tra_state_commit:
1819 >                  FLimboTransactionInfo[k].State := CommitState;
1820 >
1821 >                isc_spb_tra_state_rollback:
1822 >                  FLimboTransactionInfo[k].State := RollbackState;
1823 >
1824 >                else
1825 >                  FLimboTransactionInfo[k].State := UnknownState;
1826 >              end;
1827 >
1828 >            isc_spb_tra_remote_site:
1829 >              FLimboTransactionInfo[k].RemoteSite := AsString;
1830 >
1831 >            isc_spb_tra_db_path:
1832 >              FLimboTransactionInfo[k].RemoteDatabasePath := AsString;
1833 >
1834 >            isc_spb_tra_advise:
1835 >            with FLimboTransactionInfo[k] do
1836 >            begin
1837 >              case (AsByte) of
1838 >              isc_spb_tra_advise_commit:
1839 >              begin
1840 >                Advise := CommitAdvise;
1841 >                Action:= CommitAction;
1842 >              end;
1843 >
1844 >              isc_spb_tra_advise_rollback:
1845 >              begin
1846 >                Advise := RollbackAdvise;
1847 >                Action := RollbackAction;
1848 >              end;
1849 >
1850 >              else
1851 >                Advise := UnknownAdvise;
1852 >              end;
1853 >            end;
1854 >
1855 >            else
1856 >              IBError(ibxeOutputParsingError, [getItemType]);
1857 >          end;
1858 >        end;
1859 >      end;
1860 >    end;
1861 >  else
1862 >    IBError(ibxeOutputParsingError, [getItemType]);
1863 >  end;
1864 > end;
1865 >
1866 > procedure TIBValidationService.FixLimboTransactionErrors;
1867 > var
1868 >  i: Integer;
1869 > begin
1870 >  SRB.Add(isc_action_svc_repair);
1871 >  SRB.Add(isc_spb_dbname).AsString := FDatabaseName;
1872 >  case FGlobalAction of
1873 >  NoGlobalAction:
1874 >    begin
1875 >      for i := 0 to LimboTransactionInfoCount - 1 do
1876 >      begin
1877 >        if (FLimboTransactionInfo[i].Action = CommitAction) then
1878 >          SRB.Add(isc_spb_rpr_commit_trans).AsInteger :=  FLimboTransactionInfo[i].ID
1879 >        else
1880 >          SRB.Add(isc_spb_rpr_rollback_trans).AsInteger :=  FLimboTransactionInfo[i].ID;
1881 >      end;
1882 >    end;
1883 >
1884 >  CommitGlobal:
1885 >    begin
1886 >      for i := 0 to LimboTransactionInfoCount - 1 do
1887 >        SRB.Add(isc_spb_rpr_commit_trans).AsInteger :=  FLimboTransactionInfo[i].ID;
1888 >    end;
1889 >
1890 >    RollbackGlobal:
1891 >      begin
1892 >        for i := 0 to LimboTransactionInfoCount - 1 do
1893 >          SRB.Add(isc_spb_rpr_rollback_trans).AsInteger :=  FLimboTransactionInfo[i].ID;
1894 >      end;
1895 >
1896 >    RecoverTwoPhaseGlobal:
1897 >    begin
1898 >      for i := 0 to LimboTransactionInfoCount - 1 do
1899 >        SRB.Add(isc_spb_rpr_recover_two_phase).AsInteger :=  FLimboTransactionInfo[i].ID;
1900 >    end;
1901 >  end;
1902 >  InternalServiceStart;
1903 > end;
1904 >
1905 > function TIBValidationService.GetLimboTransactionInfo(index: integer): TLimboTransactionInfo;
1906 > begin
1907 >  if index <= High(FLimboTransactionInfo) then
1908 >    result := FLimboTransactionInfo[index]
1909 >  else
1910 >    result := nil;
1911 > end;
1912 >
1913 > function TIBValidationService.GetLimboTransactionInfoCount: integer;
1914 > begin
1915 >  Result := Length(FLimboTransactionInfo);
1916 > end;
1917 >
1918 > procedure TIBValidationService.SetDatabaseName(const Value: string);
1919 > begin
1920 >  FDatabaseName := Value;
1921 > end;
1922 >
1923 > procedure TIBValidationService.SetServiceStartOptions;
1924 > var
1925 >  param: Integer;
1926 > begin
1927 >  Action := isc_action_svc_repair;
1928 >  if FDatabaseName = '' then
1929 >    IBError(ibxeStartParamsError, [nil]);
1930 >  SRB.Add(isc_action_svc_repair);
1931 >  SRB.Add(isc_spb_dbname).AsString := FDatabaseName;
1932 >  param := 0;
1933 >  if (SweepDB in Options) then
1934 >    param := param or isc_spb_rpr_sweep_db;
1935 >  if (ValidateDB in Options) then
1936 >    param := param or isc_spb_rpr_validate_db;
1937 >
1938 >  if (LimboTransactions in Options) then
1939 >    param := param or isc_spb_rpr_list_limbo_trans;
1940 >  if (CheckDB in Options) then
1941 >    param := param or isc_spb_rpr_check_db;
1942 >  if (IgnoreChecksum in Options) then
1943 >    param := param or isc_spb_rpr_ignore_checksum;
1944 >  if (KillShadows in Options) then
1945 >    param := param or isc_spb_rpr_kill_shadows;
1946 >  if (MendDB in Options) then
1947 >    param := param or isc_spb_rpr_mend_db;
1948 >  if (ValidateFull in Options) then
1949 >  begin
1950 >     param := param or isc_spb_rpr_full;
1951 >     if not (MendDB in Options) then
1952 >       param := param or isc_spb_rpr_validate_db;
1953 >  end;
1954 >  if param > 0 then
1955 >   SRB.Add(isc_spb_options).AsInteger := param;
1956 > end;
1957 >
1958 > { TIBSecurityService }
1959 > constructor TIBSecurityService.Create(AOwner: TComponent);
1960 > begin
1961 >  inherited Create(AOwner);
1962 >  FModifyParams := [];
1963 > end;
1964 >
1965 > destructor TIBSecurityService.Destroy;
1966 > var
1967 >  i : Integer;
1968 > begin
1969 >  for i := 0 to High(FUserInfo) do
1970 >    FUserInfo[i].Free;
1971 >  FUserInfo := nil;
1972 >  inherited Destroy;
1973 > end;
1974 >
1975 > procedure TIBSecurityService.FetchUserInfo;
1976 > var
1977 >  i, j, k: Integer;
1978 > begin
1979 >  SRB.Add(isc_info_svc_get_users);
1980 >  InternalServiceQuery;
1981 >
1982 >  for i := 0 to High(FUserInfo) do
1983 >    FUserInfo[i].Free;
1984 >  for i := 0 to FServiceQueryResults.Count - 1 do
1985 >  with FServiceQueryResults[i] do
1986 >  begin
1987 >    case getItemType of
1988 >    isc_info_svc_get_users:
1989 >      begin
1990 >        SetLength(FUserInfo,1);
1991 >        k := 0;
1992 >        FUserInfo[0] := TUserInfo.Create;
1993 >        FUserInfo[0].UserName := '';
1994 >        for j := 0 to FServiceQueryResults[i].Count - 1 do
1995 >        begin
1996 >          with FServiceQueryResults[i][j] do
1997 >          case getItemType of
1998 >          isc_spb_sec_username:
1999 >            begin
2000 >              if FUserInfo[k].UserName <> '' then
2001 >              begin
2002 >                Inc(k);
2003 >                SetLength(FUserInfo,k+1);
2004 >                if FUserInfo[k] = nil then
2005 >                  FUserInfo[k] := TUserInfo.Create;
2006 >              end;
2007 >              FUserInfo[k].UserName := AsString;
2008 >            end;
2009 >
2010 >          isc_spb_sec_firstname:
2011 >            FUserInfo[k].FirstName := AsString;
2012 >
2013 >          isc_spb_sec_middlename:
2014 >            FUserInfo[k].MiddleName := AsString;
2015 >
2016 >          isc_spb_sec_lastname:
2017 >            FUserInfo[k].LastName := AsString;
2018 >
2019 >          isc_spb_sec_userId:
2020 >            FUserInfo[k].UserId := AsInteger;
2021 >
2022 >          isc_spb_sec_groupid:
2023 >            FUserInfo[k].GroupID := AsInteger;
2024 >
2025 >          isc_spb_sec_admin:
2026 >            FUserInfo[k].AdminRole := AsInteger <> 0;
2027 >
2028 >          else
2029 >            IBError(ibxeOutputParsingError, [getItemType]);
2030 >          end;
2031 >        end;
2032 >      end;
2033 >    else
2034 >      IBError(ibxeOutputParsingError, [getItemType]);
2035 >    end;
2036 >  end;
2037 > end;
2038 >
2039 > function TIBSecurityService.GetUserInfo(Index: Integer): TUserInfo;
2040 > begin
2041 >  if Index <= High(FUSerInfo) then
2042 >    result := FUserInfo[Index]
2043 >  else
2044 >    result := nil;
2045 > end;
2046 >
2047 > function TIBSecurityService.GetUserInfoCount: Integer;
2048 > begin
2049 >  Result := Length(FUserInfo);
2050 > end;
2051 >
2052 > procedure TIBSecurityService.AddUser;
2053 > begin
2054 >  SecurityAction := ActionAddUser;
2055 >  ServiceStart;
2056 > end;
2057 >
2058 > procedure TIBSecurityService.DeleteUser;
2059 > begin
2060 >  SecurityAction := ActionDeleteUser;
2061 >  ServiceStart;
2062 > end;
2063 >
2064 > procedure TIBSecurityService.DisplayUsers;
2065 > begin
2066 >  SecurityAction := ActionDisplayUser;
2067 >  if HasAdminRole then
2068 >    SRB.Add(isc_action_svc_display_user_adm) {Firebird 2.5 and later only}
2069 >  else
2070 >    SRB.Add(isc_action_svc_display_user);
2071 >  InternalServiceStart;
2072 >  FetchUserInfo;
2073 > end;
2074 >
2075 > procedure TIBSecurityService.DisplayUser(UserName: string);
2076 > begin
2077 >  SecurityAction := ActionDisplayUser;
2078 >  if HasAdminRole then
2079 >     SRB.Add(isc_action_svc_display_user_adm) {Firebird 2.5 and later only}
2080 >  else
2081 >    SRB.Add(isc_action_svc_display_user);
2082 >  SRB.Add(isc_spb_sec_username).AsString := UserName;
2083 >  InternalServiceStart;
2084 >  FetchUserInfo;
2085 > end;
2086 >
2087 > procedure TIBSecurityService.ModifyUser;
2088 > begin
2089 >  SecurityAction := ActionModifyUser;
2090 >  ServiceStart;
2091 > end;
2092 >
2093 > function TIBSecurityService.HasAdminRole: boolean;
2094 > begin
2095 >  Result :=  (ServerVersionNo[1] > 2) or
2096 >             ((ServerVersionNo[1] = 2) and (ServerVersionNo[2] = 5));
2097 > end;
2098 >
2099 > procedure TIBSecurityService.SetSecurityAction (Value: TSecurityAction);
2100 > begin
2101 >  FSecurityAction := Value;
2102 >  if Value = ActionDeleteUser then
2103 >    ClearParams;
2104 > end;
2105 >
2106 > procedure TIBSecurityService.ClearParams;
2107 > begin
2108 >  FModifyParams := [];
2109 >  FFirstName := '';
2110 >  FMiddleName := '';
2111 >  FLastName := '';
2112 >  FGroupID := 0;
2113 >  FUserID := 0;
2114 >  FPassword := '';
2115 > end;
2116 >
2117 > procedure TIBSecurityService.SetAdminRole(AValue: boolean);
2118 > begin
2119 >  FAdminRole := AValue;
2120 >  Include (FModifyParams, ModifyAdminRole);
2121 > end;
2122 >
2123 > procedure TIBSecurityService.SetFirstName (Value: String);
2124 > begin
2125 >  FFirstName := Value;
2126 >  Include (FModifyParams, ModifyFirstName);
2127 > end;
2128 >
2129 > procedure TIBSecurityService.SetMiddleName (Value: String);
2130 > begin
2131 >  FMiddleName := Value;
2132 >  Include (FModifyParams, ModifyMiddleName);
2133 > end;
2134 >
2135 > procedure TIBSecurityService.SetLastName (Value: String);
2136 > begin
2137 >  FLastName := Value;
2138 >  Include (FModifyParams, ModifyLastName);
2139 > end;
2140 >
2141 > procedure TIBSecurityService.SetPassword (Value: String);
2142 > begin
2143 >  FPassword := Value;
2144 >  Include (FModifyParams, ModifyPassword);
2145 > end;
2146 >
2147 > procedure TIBSecurityService.SetUserId (Value: Integer);
2148 > begin
2149 >  FUserId := Value;
2150 >  Include (FModifyParams, ModifyUserId);
2151 > end;
2152 >
2153 > procedure TIBSecurityService.SetGroupId (Value: Integer);
2154 > begin
2155 >  FGroupId := Value;
2156 >  Include (FModifyParams, ModifyGroupId);
2157 > end;
2158 >
2159 > procedure TIBSecurityService.Loaded;
2160 > begin
2161 >  inherited Loaded;
2162 >  ClearParams;
2163 > end;
2164 >
2165 > procedure TIBSecurityService.SetServiceStartOptions;
2166 > var
2167 >  Len: UShort;
2168 >
2169 > begin
2170 >  case FSecurityAction of
2171 >    ActionAddUser:
2172 >    begin
2173 >      Action := isc_action_svc_add_user;
2174 >      if ( Pos(' ', FUserName) > 0 ) then
2175 >        IBError(ibxeStartParamsError, [nil]);
2176 >      Len := Length(FUserName);
2177 >      if (Len = 0) then
2178 >        IBError(ibxeStartParamsError, [nil]);
2179 >      SRB.Add(isc_action_svc_add_user);
2180 >      SRB.Add(isc_spb_sec_username).AsString := FUserName;
2181 >      if FSQLRole <> '' then
2182 >        SRB.Add(isc_spb_sql_role_name).AsString := FSQLRole;
2183 >      SRB.Add(isc_spb_sec_userid).AsInteger := FUserID;
2184 >      SRB.Add(isc_spb_sec_groupid).AsInteger := FGroupID;
2185 >      SRB.Add(isc_spb_sec_password).AsString := FPassword;
2186 >      SRB.Add(isc_spb_sec_firstname).AsString := FFirstName;
2187 >      SRB.Add(isc_spb_sec_middlename).AsString := FMiddleName;
2188 >      SRB.Add(isc_spb_sec_lastname).AsString := FLastName;
2189 >      if HasAdminRole then
2190 >        SRB.Add(isc_spb_sec_admin).AsInteger := ord(FAdminRole);
2191 >    end;
2192 >    ActionDeleteUser:
2193 >    begin
2194 >      Action := isc_action_svc_delete_user;
2195 >      Len := Length(FUserName);
2196 >      if (Len = 0) then
2197 >        IBError(ibxeStartParamsError, [nil]);
2198 >      SRB.Add(isc_action_svc_delete_user);
2199 >      SRB.Add(isc_spb_sec_username).AsString := FUserName;
2200 >      if FSQLRole <> '' then
2201 >        SRB.Add(isc_spb_sql_role_name).AsString := FSQLRole;
2202 >    end;
2203 >    ActionModifyUser:
2204 >    begin
2205 >      Action := isc_action_svc_modify_user;
2206 >      Len := Length(FUserName);
2207 >      if (Len = 0) then
2208 >        IBError(ibxeStartParamsError, [nil]);
2209 >      SRB.Add(isc_action_svc_modify_user);
2210 >      SRB.Add(isc_spb_sec_username).AsString := FUserName;
2211 >      if FSQLRole <> '' then
2212 >        SRB.Add(isc_spb_sql_role_name).AsString := FSQLRole;
2213 >      if (ModifyUserId in FModifyParams) then
2214 >        SRB.Add(isc_spb_sec_userid).AsInteger := FUserID;
2215 >      if (ModifyGroupId in FModifyParams) then
2216 >        SRB.Add(isc_spb_sec_groupid).AsInteger := FGroupID;
2217 >      if (ModifyPassword in FModifyParams) then
2218 >        SRB.Add(isc_spb_sec_password).AsString := FPassword;
2219 >      if (ModifyFirstName in FModifyParams) then
2220 >        SRB.Add(isc_spb_sec_firstname).AsString := FFirstName;
2221 >      if (ModifyMiddleName in FModifyParams) then
2222 >        SRB.Add(isc_spb_sec_middlename).AsString := FMiddleName;
2223 >      if (ModifyLastName in FModifyParams) then
2224 >        SRB.Add(isc_spb_sec_lastname).AsString := FLastName;
2225 >      if (ModifyAdminRole in FModifyParams) and HasAdminRole then
2226 >      begin
2227 >        if FAdminRole then
2228 >          SRB.Add(isc_spb_sec_admin).AsInteger := 1
2229 >        else
2230 >          SRB.Add(isc_spb_sec_admin).AsInteger := 0;
2231 >      end;
2232 >    end;
2233 >  end;
2234 >  ClearParams;
2235 > end;
2236 >
2237 > { TIBUnStructuredService }
2238 > constructor TIBControlAndQueryService.create(AOwner: TComponent);
2239 > begin
2240 >  inherited Create(AOwner);
2241 >  FEof := False;
2242 >  FAction := 0;
2243 > end;
2244 >
2245 > procedure TIBControlAndQueryService.SetAction(Value: Integer);
2246 > begin
2247 >  FEof := False;
2248 >  FAction := Value;
2249 > end;
2250 >
2251 >
2252 > function TIBControlAndQueryService.GetNextChunk: String;
2253 > var
2254 >  i: Integer;
2255 > begin
2256 >  if (FEof = True) then
2257 >  begin
2258 >    result := '';
2259 >    exit;
2260 >  end;
2261 >  if (FAction = 0) then
2262 >    IBError(ibxeQueryParamsError, [nil]);
2263 >
2264 >  SRB.Add(isc_info_svc_to_eof);
2265 >  InternalServiceQuery;
2266 >
2267 >  FEof := True;
2268 >  for i := 0 to FServiceQueryResults.Count - 1 do
2269 >  with FServiceQueryResults[i] do
2270 >  begin
2271 >    case getItemType of
2272 >      isc_info_svc_to_eof:
2273 >        Result := AsString;
2274 >
2275 >      isc_info_truncated:
2276 >        FEof := False;
2277 >    else
2278 >      IBError(ibxeOutputParsingError, [getItemType]);
2279 >    end;
2280 >  end;
2281 > end;
2282 >
2283 > procedure TIBControlAndQueryService.ServiceStart;
2284 > begin
2285 >  FEof := false;
2286 >  inherited ServiceStart;
2287 > end;
2288 >
2289 > function TIBControlAndQueryService.WriteNextChunk(stream: TStream): integer;
2290 > var
2291 >  i: Integer;
2292 >  TimeOut: boolean;
2293 > begin
2294 >  result := 0;
2295 >  TimeOut := false;
2296 >  if (FEof = True) then
2297 >    exit;
2298 >  if (FAction = 0) then
2299 >    IBError(ibxeQueryParamsError, [nil]);
2300 >
2301 >  SQPB.Add(isc_info_svc_timeout).AsInteger := 1;
2302 >  SRB.Add(isc_info_svc_to_eof);
2303 >  InternalServiceQuery;
2304 >
2305 >  FEof := True;
2306 >  for i := 0 to FServiceQueryResults.Count - 1 do
2307 >  with FServiceQueryResults[i] do
2308 >  begin
2309 >    case getItemType of
2310 >      isc_info_svc_to_eof:
2311 >      begin
2312 >        Result := CopyTo(stream,0);
2313 >        FEof := (Result = 0) and not TimeOut;
2314 >      end;
2315 >
2316 >      isc_info_truncated:
2317 >        FEof := False;
2318 >
2319 >      isc_info_svc_timeout:
2320 >        begin
2321 >          FEof := False;
2322 >          TimeOut := true;
2323 >        end
2324 >
2325 >    else
2326 >      IBError(ibxeOutputParsingError, [getItemType]);
2327 >    end;
2328 >  end;
2329 > end;
2330 >
2331 > function TIBControlAndQueryService.GetNextLine: String;
2332 > var
2333 >  i: Integer;
2334 > begin
2335 >  Result := '';
2336 >  if (FEof = True) then
2337 >    exit;
2338 >
2339 >  if (FAction = 0) then
2340 >    IBError(ibxeQueryParamsError, [nil]);
2341 >
2342 >  SRB.Add(isc_info_svc_line);
2343 >  InternalServiceQuery;
2344 >
2345 >  for i := 0 to FServiceQueryResults.Count - 1 do
2346 >  with FServiceQueryResults[i] do
2347 >  begin
2348 >    case getItemType of
2349 >      isc_info_svc_line:
2350 >         Result := AsString;
2351 >    else
2352 >      IBError(ibxeOutputParsingError, [getItemType]);
2353 >    end;
2354 >  end;
2355 >  FEOF := Result = '';
2356 > end;
2357 >
2358 > { TIBLogService }
2359 >
2360 > procedure TIBLogService.SetServiceStartOptions;
2361 > begin
2362 >  Action := isc_action_svc_get_ib_log;
2363 >  SRB.Add(isc_action_svc_get_ib_log);
2364 > end;
2365 >
2366 > { TDatabaseInfo }
2367 >
2368 > constructor TDatabaseInfo.Create;
2369 > begin
2370 >  DbName := nil;
2371 > end;
2372 >
2373 > destructor TDatabaseInfo.Destroy;
2374 > begin
2375 >  DbName := nil;
2376 >  inherited Destroy;
2377 > end;
2378 >
2379 > { TLicenseInfo }
2380 >
2381 > constructor TLicenseInfo.Create;
2382 > begin
2383 >  Key := nil;
2384 >  Id := nil;
2385 >  Desc := nil;
2386 > end;
2387 >
2388 > destructor TLicenseInfo.Destroy;
2389 > begin
2390 >  Key := nil;
2391 >  Id := nil;
2392 >  Desc := nil;
2393 >  inherited Destroy;
2394 > end;
2395 >
2396 > { TConfigFileData }
2397 >
2398 > constructor TConfigFileData.Create;
2399 > begin
2400 >  ConfigFileValue := nil;
2401 >  ConfigFileKey := nil;
2402 > end;
2403 >
2404 > destructor TConfigFileData.Destroy;
2405 > begin
2406 >  ConfigFileValue := nil;
2407 >  ConfigFileKey := nil;
2408 >  inherited Destroy;
2409 > end;
2410 >
2411 > { TConfigParams }
2412 >
2413 > constructor TConfigParams.Create;
2414 > begin
2415 >  ConfigFileData := TConfigFileData.Create;
2416 >  ConfigFileParams := nil;
2417 > end;
2418 >
2419 > destructor TConfigParams.Destroy;
2420 > begin
2421 >  ConfigFileData.Free;
2422 >  ConfigFileParams := nil;
2423 >  inherited Destroy;
2424 > end;
2425 >
2426 > end.

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines