Program create;
{$APPTYPE CONSOLE}
uses
Sysutils,Firebird,Windows;
var
st : IStatus;
master : IMaster;
util : IUtil;
dpb : IXpbBuilder;
prov : IProvider;
att : IAttachment;
tra : ITransaction;
procedure PrintError(s : IStatus);
var
maxMessage : Integer;
outMessage : PAnsiChar;
begin
maxMessage := 256;
outMessage := PAnsiChar(StrAlloc(maxMessage));
util.formatStatus(outMessage, maxMessage, s);
writeln(outMessage);
StrDispose(outMessage);
end;
type
IKeyCallback = class(ICryptKeyCallbackImpl)
function callback(dataLength: Cardinal; data: Pointer; bufferLength: Cardinal; buffer: Pointer): Cardinal; override;
end;
function IKeyCallback.callback(dataLength: Cardinal; data: Pointer; bufferLength: Cardinal; buffer: Pointer): Cardinal;
var Key: PAnsiChar;
KeyLength:Integer;
begin
KeyLength := 0;
If (bufferLength > 0) and (buffer <> nil) then
begin
WriteLn('Sending key');
Key := '0123456789';
KeyLength := Length(Key);
WriteLn('got key request: ', PAnsiChar(Data):dataLength);
Move(Key^, buffer^, KeyLength);
end;
Result := KeyLength;
end;
var param1:String;
begin
if ParamCount>0 then
begin
param1 := ParamStr(1);
end;
if param1<>'open' then
param1 := 'create';
WriteLn('starting...('+param1+')');
master := fb_get_master_interface;
if master = nil then
begin
WriteLn('master is nil');
Exit;
end;
Write('getting util interface...');
util := master.getUtilInterface;
WriteLn('done.');
Write('getting status and dispatcher...');
st := master.getStatus;
prov := master.getDispatcher;
WriteLn('done.');
if (util = nil) or (st = nil) or (prov = nil) then
begin
WriteLn('null pointers');
Exit;
end;
try
prov.setDbCryptCallback(st, IKeyCallback.create);
Write('Generating DPB...');
//create DPB
dpb := util.getXpbBuilder(st, IXpbBuilder.DPB, nil, 0);
Write('page size...');
dpb.insertInt(st, isc_dpb_page_size, 4 * 1024);
Write('user name...');
dpb.insertString(st, isc_dpb_user_name, 'sysdba');
Write('password...');
dpb.insertString(st, isc_dpb_password, 'masterkey');
WriteLn('done.');
//create empty database
if param1='create' then
begin
att := prov.createDatabase(st, 'fbtests.fdb', dpb.getBufferLength(st), dpb.getBuffer(st));
writeln ('Database fbtests.fdb created');
//start transaction
tra := att.startTransaction(st, 0, nil);
//Encrypt database
att.execute(st, tra, 0, 'alter database encrypt with aes128', 3,
nil, nil, nil, nil); // Input parameters and output data not used
//commit transaction (will close interface)
tra.commit(st);
tra := nil;
WriteLn('Press Enter to continue');
ReadLn;
//detach from database
att.detach(st);
att := nil;
//remove unneeded tag from DPB
if dpb.findFirst(st, isc_dpb_page_size)
then dpb.removeCurrent(st);
//attach once again
att := prov.attachDatabase(st, 'fbtests.fdb', dpb.getBufferLength(st), dpb.getBuffer(st));
writeln ('Re-attached database fbtests.fdb');
//start transaction
tra := att.startTransaction(st, 0, nil);
//create table
att.execute(st, tra, 0, 'create table dates_table (d1 date)', 3,
nil, nil, nil, nil); // Input parameters and output data not used
//commit transaction retaining
tra.commitRetaining(st);
writeln ('Table dates_table created');
//insert a record into dates_table
att.execute(st, tra, 0, 'insert into dates_table values (CURRENT_DATE)', 3,
nil, nil, nil, nil); // Input parameters and output data not used
//commit transaction (will close interface)
tra.commit(st);
tra := nil;
writeln ('Record inserted into dates_table');
end
//open database
else if param1='open' then
begin
att := prov.attachDatabase(st, 'fbtests.fdb', dpb.getBufferLength(st), dpb.getBuffer(st));
writeln ('Database fbtests.fdb Opened');
exit;
end;
//detach from the database (will close interface)
att.detach(st);
att := nil;
dpb.dispose;
dpb := nil;
except
on e: FbException do PrintError(e.getStatus);
end;
prov.release;
end.