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

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines