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

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines