Inno Setup: Ord Function or eqivalent? - encryption

I'm using inno setup to "crypt" a password:
function XORcrypt(Value,Key: string): string;
var
p,k,pl,kl: integer;
begin
{very basic encryption, using bitwise XOR}
result:=Value;
pl:=Length(Value);
kl:=Length(Key);
if (pl>0) and (kl>0) then
begin
p:=1; k:=1;
while (p<=pl) do
begin
Result[p]:=Char(Ord(Value[p]) XOR Ord(Key[k]));
if k=kl then k:=1 else k:=k+1;
p:=p+1
end; {while}
end; {if}
end; {XORcrypt}
inno seems not to know the pascal function Ord which returns the ASCII value of a requested character (67 for 'C')
Any solutions?

The problem is not Ord() it's Char() you need to use Chr() instead.
function XORcrypt(Value,Key: String): String;
var
p,k,pl,kl: integer;
begin
{very basic encryption, using bitwise XOR}
result:=Value;
pl:=Length(Value);
kl:=Length(Key);
if (pl>0) and (kl>0) then
begin
p:=1; k:=1;
while (p<=pl) do
begin
Result[p]:=Chr(Ord(Value[p]) XOR Ord(Key[k]));
if k=kl then k:=1 else k:=k+1;
p:=p+1
end; {while}
end; {if}
end; {XORcrypt}

Related

Solving sudoku in Ada

This is mostly solved now thank you
procedure Sudoku is
-- Set Array Types
type arr is array(1..9,1..9) of integer;
type solutions is array(integer range <>)of integer;
-- Declare Variable Types
infp : File_Type;
fileName : string(1..50);
fromFile : string(1..9);
last: natural;
num : arr;
j : integer;
--
--Function to check if board is full
--
function isTrue(board : arr) return boolean is
--Variable Declaration
numCheck : integer;
begin
for x in 1..9 loop
for y in 1..9 loop
if board(x,y) /= 0 then
numCheck := board(x,y);
for k in 1..9 loop
if numCheck = board(x,k) and k /= y then
put_line("Unsolvable Puzzle");
return false;
end if;
if numCheck = board(k,y) and k /= x then
put(x);
put(y);
put_line("Unsolvable Puzzle");
return false;
end if;
end loop;
end if;
end loop;
end loop;
return true;
end isTrue;
A procedure looks like
procedure Proc (params) is
{declarations}
begin
{statements}
end Proc;
which is a pattern you use without problem in the nested procedures; but it applies just the same to the outer sudoku procedures. Note that {declarations} can include nested subprograms.
At line 43 you end the first sudoku, which began at line 5, without any
begin
{statements}
and at line 44 you start a second sudoku, which you end at line 124, again without any
begin
{statements}
So that makes two outer-level procedures in the same file, which is something that GNAT does not support out of the box.
In any case, I think you probably only want one sudoku procedure, so you need to merge the two declarative regions and write a body that calls the nested procedures as appropriate (something I can’t help you with).

Delphi: Setting timestamp of file wrong by one hour for some files

I want to correct the last-access time of some files.
Doing that programmatically fails - by one hour - for some files.
Mysterious, as I do correct the date according to the timezone.
Here is an example, tested for Delphi2010 (that's where I would need code for) and Delphi10.3
function GetTempDir : string;
var path : array[0..MAX_PATH] of char;
PathStr : string;
begin
GetTempPath(MAX_PATH, path);
PathStr:=path;
result:=IncludeTrailingPathDelimiter(PathStr);
end;
function UTCDateTimeFromLocalDateTime(const LocalDateTime: TDateTime): TDateTime;
var
LocalSystemTime: TSystemTime;
UTCSystemTime: TSystemTime;
LocalFileTime: TFileTime;
UTCFileTime: TFileTime;
begin
DateTimeToSystemTime(LocalDateTime, UTCSystemTime);
SystemTimeToFileTime(UTCSystemTime, UTCFileTime);
if LocalFileTimeToFileTime(UTCFileTime, LocalFileTime)
and FileTimeToSystemTime(LocalFileTime, LocalSystemTime) then begin
Result := SystemTimeToDateTime(LocalSystemTime);
end else begin
Result := LocalDateTime;
end;
end;
function SetFileTimesHelper(const FileName: string; DateTime: TDateTime): Boolean;
var
Handle: THandle;
FileTime: TFileTime;
SystemTime: TSystemTime;
begin
Result := False;
Handle := CreateFile(PChar(FileName), GENERIC_WRITE, FILE_SHARE_READ, nil,
OPEN_EXISTING, 0, 0);
if Handle <> INVALID_HANDLE_VALUE then
try
DateTime:=UTCDateTimeFromLocalDateTime(DateTime);
DateTimeToSystemTime(DateTime, SystemTime);
FileTime.dwLowDateTime := 0;
FileTime.dwHighDateTime := 0;
if SystemTimeToFileTime(SystemTime, FileTime) then
begin
Result := SetFileTime(Handle, nil, nil, #FileTime);
end;
finally
CloseHandle(Handle);
end;
end;
procedure TForm1.CreateDateFile(Dat : TDateTime);
var FileName : string;
begin
FileName:=GetTempDir+FormatDateTime('yyyymmdd hhnnss', Dat)+'.txt';
Memo1.Lines.Add(FileName);
with TStringList.Create do
begin
text:='1';
SaveToFile(FileName);
Free;
end;
SetFileTimesHelper(FileName, Dat);
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
CreateDateFile(StrToDateTime('23.02.2013 11:11:11'));
CreateDateFile(StrToDateTime('06.05.2014 22:22:22')); // file dated 23:22:22
end;
The first file is correctly dated, the 2nd is displayed in the windows explorer with 23:22:22.
What do I miss?
Thanks brian for the comment.
Digging that way I found a solution:
GetTimeZoneInformation(tz);
SystemTimeToTzSpecificLocalTime(#tz, UTCSystemTime, LtSystemTime);
I didn't find the inverse function of SystemTimeToTzSpecificLocalTime, but I used this function and then see the resulting offset. Then I invert the offset and the time is properly corrected.

using TfrxRect and GetRealBounds in a script

i am tying to use the script
procedure BarCodeResize(Bc : TfrxBarCodeView);
var
r : TfrxRect;
begin
bc.Text := '1234567890 test 1234567890 asdf 1234567890';
r := bc.GetRealBounds;
bc.Zoom := bc.Width/(r.Right - r.Left);
frxReport1.ShowReport();
end;
but it shows me an error at line 'r : TfrxRect;'
Explanation:
If I understand your question correctly, you may consider the following:
If you want to use a type, you need to call AddType() method of TfsScript class.
In FastScript, only published methods of added classes are implemented. If you want to use public method (GetRealBounds for example), you need to use AddMethod() method of TfsScript.
The problem with your script (even if you add type TfrxRect) is, that TfrxRect is packed record, and FastScript do not support records. So, you may define your own TfrxBarCodeView class with appropriate methods.
Тхе example белов demonstrates one possible way to solve your problem (it uses Delphi, but I was able to reproduce and solve your error).
Delphi part:
unit FMainBarcode;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, frxClass, fs_iinterpreter, frxBarcode;
type
TForm1 = class(TForm)
Button1: TButton;
frxReport1: TfrxReport;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
type
TfrxMyBarCodeView = class(TfrxBarCodeView)
public
constructor Create(AOwner: TComponent); override;
function GetRealBoundsRight: double;
function GetRealBoundsLeft: double;
end;
type
TFunctions = class(TfsRTTIModule)
private
function CallMethod(Instance: TObject; ClassType: TClass; const MethodName: String; Caller: TfsMethodHelper): Variant;
public
constructor Create(AScript: TfsScript); override;
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
begin
// Show report
frxReport1.ShowReport;
end;
{ TMyfrxBarCodeView }
constructor TfrxMyBarCodeView.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
end;
function TfrxMyBarCodeView.GetRealBoundsLeft: double;
begin
Result := GetRealBounds.Left;
end;
function TfrxMyBarCodeView.GetRealBoundsRight: double;
begin
Result := GetRealBounds.Right;
end;
{ TFunctions }
constructor TFunctions.Create(AScript: TfsScript);
begin
inherited Create(AScript);
// Add type
AScript.AddType('TfrxRect', fvtVariant);
// Add public method
with AScript.FindClass('TfrxBarCodeView') do begin
AddMethod('function GetRealBounds: TfrxRect', CallMethod);
end{with};
// Add class and public methods
with AScript.AddClass(TfrxMyBarCodeView, 'TfrxBarCodeView') do begin
AddMethod('function GetRealBoundsRight: double', CallMethod);
AddMethod('function GetRealBoundsLeft: double', CallMethod);
end{with};
end;
function TFunctions.CallMethod(Instance: TObject; ClassType: TClass; const MethodName: String; Caller: TfsMethodHelper): Variant;
begin
Result := 0;
if (ClassType = TfrxBarCodeView) and (MethodName = 'GETREALBOUNDS') then begin
//Result := TfrxBarCodeView(Instance).GetRealBounds;
end{if};
if (ClassType = TfrxMyBarCodeView) and (MethodName = 'GETREALBOUNDSRIGHT') then begin
Result := TfrxMyBarCodeView(Instance).GetRealBoundsRight;
end{if};
if (ClassType = TfrxMyBarCodeView) and (MethodName = 'GETREALBOUNDSLEFT') then begin
Result := TfrxMyBarCodeView(Instance).GetRealBoundsLeft;
end{if};
end;
initialization
fsRTTIModules.Add(TFunctions);
end.
Fast report code:
procedure BarCodeResize(Bc : TfrxMyBarCodeView);
var
R, L : double;
begin
Bc.Text := '1234567890 test 1234567890 asdf 1234567890';
R := Bc.GetRealBoundsRight * fr1CharX / fr01cm;
L := Bc.GetRealBoundsLeft * fr1CharX / fr01cm;
Bc.Zoom := Bc.Width / (R - L);
ShowMessage('Right: ' + FloatToStr(R) + ', Left: ' + FloatToStr(L));
end;
procedure Page1OnBeforePrint(Sender: TfrxComponent);
begin
BarCodeResize(TfrxMyBarCodeView(BarCode1));
end;
begin
end.
Notes:
Tested with Delphi 7, FastReport 4.7, FastScript 1.7.

what is the best approach to make an http request

what is the best method to do this: i have a txt file filled with web addresses, i have to check all of them using idHTTP component,only a simple check from a web server, downloading the html and finding a match, i want it to to be fast, there is different types of threads and i am not sure what is the best to use, a TParallel for or Task threads or regular threads?
i tried before TParallel for and i got stuck at AV, also i've tried Task threads but its not fast, the http request becomes slower by time, i tried also the regular threads and i didnt know how to use it because its complicated to use.
note: Please do NOT downvote i just need advice from the experts. Thank you
First advice: do not use Indy. Use THTTPClient (unit System.Net.HttpClient) -- native for Delphi XE?+
I am still using old TThreads. I could make suggestion only with TThread.
Workflow:
Main thread -- reading your TXT file line by line.
After line was readed, you create NEW thread, which are downloading information from WWW.
Sample of application:
unit ufmMain;
interface
uses
Winapi.Windows, Winapi.Messages,
System.SysUtils, System.Variants,
{ TThread }
System.Classes,
Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls;
type
TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
TLoad = class(TThread)
protected
FURL,
FOutputFileName: String;
procedure Execute; override;
public
constructor Create(const AURL, AOutputFileName: String); overload;
end;
HTTP = class
public
class procedure Get(const AURL: String; out AOutputStream: TMemoryStream);
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
uses
{ THTTPClient }
System.Net.HttpClient;
procedure TForm1.Button1Click(Sender: TObject);
var
LLoad: TLoad;
LFile: TextFile;
LCycle: Integer;
LUrl: String;
begin
LCycle := 0;
AssignFile(LFile, 'urls.txt');
try
Reset(LFile);
while not Eof(LFile) do
begin
{ Using for generate file name. All file names must be unique }
Inc(LCycle);
{ Read next URL }
ReadLn(LFile, LUrl);
{ Create new thread }
LLoad := TLoad.Create(LUrl, 'Output file No ' + LCycle.ToString + '.htm');
LLoad.FreeOnTerminate := True;
LLoad.Start;
end;
finally
CloseFile(LFile);
end;
end;
{ TLoad }
constructor TLoad.Create(const AURL, AOutputFileName: String);
begin
inherited Create(True);
FURL := AURL;
FOutputFileName := AOutputFileName;
end;
procedure TLoad.Execute;
var
LResponse: TMemoryStream;
begin
inherited;
LResponse := TStringStream.Create;
try
HTTP.Get(FURL, LResponse);
{ Save result to file }
LResponse.SaveToFile(GetCurrentDir + PathDelim + FOutputFileName);
finally
LResponse.Free;
end;
end;
{ HTTP }
class procedure HTTP.Get(const AURL: String; out AOutputStream: TMemoryStream);
var
LStream: TStream;
LHTTPClient: THTTPClient;
begin
LHTTPClient := THTTPClient.Create;
try
LStream := LHTTPClient.Get(AURL).ContentStream;
AOutputStream.CopyFrom(LStream, LStream.Size);
finally
LHTTPClient.Free;
end;
end;
end.
Why I against Indy:
1) THTTPClient do not required additional DLL for works with SSL protocol
2) THTTPClient is modern from Delphi XE8
3) My subjective opinion: THTTPClient works much more smoothly (with less issues) then Indy library. I used Indy for last 10 years, but now all my supported project moved to THTTPClient.
You can use TTask and Indy (TIdHTTP). Example:
function GetUrl(const aUrl: string): ITask;
begin
Result := TTask.Run(
procedure
var
FOutput: string;
FHTTP: TIdHTTP;
begin
FHTTP:=TIdHTTP.Create(nil);
try
try
FOutput:=FHTTP.Get(aUrl);
except
// handle errors
end;
finally
FHTTP.Free;
end;
TThread.Synchronize(nil,
procedure
begin
ProcessOutput(FOutput); // send your output/result to main thread
end);
end );
end;
procedure TForm1.Button1Click(Sender: TObject);
var
i: Integer;
list: TStringList;
begin
list:=TStringList.Create;
try
list.LoadFromFile('yourfile.txt');
// get all your urls
// you should control how many threads run at the same time
for i := 0 to list.Count-1 do
GetUrl(list[i]);
finally
list.Free;
end;
end;

Using Registry Values in ICON Section

I am trying to use a registry value for the location of an EXE file in the ICONS section, the value is not located in the normal \microsoft\windows\exe\ registry. I have the following code that is not retuning the value, the ICON is created with the word "computer" for the target.
function GetACADexe (Param: string): string;
var VerKey: String;
var ExeKey: String;
begin
if RegQueryStringValue(HKCU, 'Software\Classes\AutoCAD.Drawing', 'CurVer', VerKey) and
RegQueryStringValue(HKCU, 'Software\Classes\' + VerKey + '\Protocol\StdFileEditing', 'Server', ExeKey) then
Result := ExpandConstant ('{ExeKey}')
end;
Here is the resultant working answer;
function GetHKCU() : Integer;
begin
if IsWin64 then
begin
Result := HKCU64;
end
else
begin
Result := HKEY_CURRENT_USER;
end;
end;
function GetACADexe(Value: String): string;
var
VerKey: string;
ExeKey: string;
begin
// result should be initialized for case when ACAD is not installed
Result := '';
if RegQueryStringValue(GetHKCU(), 'Software\Classes\AutoCAD.Drawing\CurVer', '', VerKey) and
RegQueryStringValue(GetHKCU(), 'Software\Classes\' + VerKey + '\Protocol\StdFileEditing\Server', '', ExeKey)
then
Result := ExeKey;
end;
Along with checking for 32 or 64 bit systems, I also ran into the issue that the registry values where the "(Default)" values, that's why the empty '' for the key name. Works great now.... Thanks TLAMA.

Resources