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

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines