Koushik Halder
Koushik Halder

Reputation: 455

Windows Directory Definition

I have an application that will work with the HOSTS file in the Windows\System32\drivers\etc folder. However, I don't want to hard code the path to C:\Windows\System32, because Windows might not be installed on drive C:.

I tried using %WinDir%\system32\drivers\etc\hosts, but this doesn't get expanded when it's used in the variable in my code.

How can I use %WinDir%\system32\drivers\etc\hosts as the path to the hosts file so I don't have to hard-code the path?

Another problem is that on successful compilation I have received one warning as

[DCC Warning] ApplicationWizard01.pas(67): W1002 Symbol 'TFileAttributes' is specific to a platform.

Code is shown in the answer here

Here is my new code :

unit KoushikHalder01;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.Buttons, Vcl.ExtCtrls,
  Vcl.ComCtrls;
type
  TForm01 = class(TForm)
    Label01: TLabel;
    Edit01: TEdit;
    Edit02: TEdit;
    BitBtn01: TBitBtn;
    BitBtn02: TBitBtn;
    procedure FormCreate(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    procedure FormShow(Sender: TObject);
    procedure FormHide(Sender: TObject);
    procedure BitBtn01MouseEnter(Sender: TObject);
    procedure BitBtn02MouseEnter(Sender: TObject);
    procedure BitBtn01MouseDown(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    procedure BitBtn02MouseDown(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    procedure BitBtn01MouseLeave(Sender: TObject);
    procedure BitBtn02MouseLeave(Sender: TObject);
    procedure BitBtn02Click(Sender: TObject);
    procedure BitBtn01Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form01: TForm01;

implementation

{$R *.dfm}

uses System.IOUtils;

procedure TForm01.BitBtn01Click(Sender: TObject);
function GetSysDir: string;
function IncludeTrailingPathDelimiter(const S: string): string;
var
  Attributes: TFileAttributes;
  SL: TStringList;
  Idx: Integer;
  Buffer: array[0..MAX_PATH] of Char;
  PathAndFileName : String;
begin
   GetSystemDirectory(Buffer, MAX_PATH - 1);
   SetLength(Result, StrLen(Buffer));
   Result := Buffer;
   PathAndFileName := CheckTrailingPathDelimiter(GetSysDir) + 'drivers\etc\hosts`;
   Attributes := [];
   TFile.SetAttributes('PathAndFileName', Attributes);
   SL := TStringList.Create;
   try
      SL.LoadFromFile('PathAndFileName');

     if
        SL.IndexOf('10.220.70.34    VIRTSDP25') <> -1
     then
        begin
        Edit02.Font.Color := clRed;
        Edit02.Text := 'Your Host File Has Already Been Modified Successfully.';
        end;
     if
        SL.IndexOf('10.220.70.34    VIRTSDP25') = -1
     then
        begin
        SL.Add('10.220.70.34    VIRTSDP25');
        Edit02.Font.Color := clGreen;
        Edit02.Text := 'Your Host File Has Been Modified Successfully.';
        end;
     if
        SL.IndexOf('10.220.70.32    BSNLESDP25A') = -1
     then
        SL.Add('10.220.70.32    BSNLESDP25A');
     if
        SL.IndexOf('10.220.70.33    BSNLESDP25B') = -1
     then
        SL.Add('10.220.70.33    BSNLESDP25B');
     if
        SL.IndexOf('10.220.70.34    VIRTBSNLESDP25') = -1
     then
        SL.Add('10.220.70.34    VIRTBSNLESDP25');
     if
        SL.IndexOf('10.220.70.34    KOSDPTwentyfive.bsnl.in.net') = -1
     then
        SL.Add('10.220.70.34    KOSDPTwentyfive.bsnl.in.net');
     if
        SL.IndexOf('10.220.70.34    KOSDPTwentyfive.bsnl.net.in') = -1
     then
        begin
           SL.Add('10.220.70.34 KOSDPTwentyfive.bsnl.net.in');
           SL.SaveToFile('PathAndFileName');
        end;
     finally
       SL.Free;
   end;
    Include(Attributes, TFileAttribute.faSystem);
    Include(Attributes, TFileAttribute.faReadOnly);
    TFile.SetAttributes('PathAndFileName', Attributes);
end;

Upvotes: 2

Views: 6586

Answers (2)

Eugene.LatDev
Eugene.LatDev

Reputation: 11

Simply :

function WindowsPath: string; begin SetLength(Result, MAX_PATH); SetLength(Result, GetWindowsDirectory(@Result[1], MAX_PATH)); end;

  1. set's result length to 255 bytes or 512 for widesting and fills whole buffer with null chars #0
  2. requests windows folder from OS to pointer of first char, and sets length of buffer to chars length, after this when string no more used cleaner will destroy string content to first null byte, then destroys string. Actualy first nullbyte is next char of string because first line fills everything with nullchars.

    ps: Everything in string after nullbyte ignored, nullbyte char including!

Upvotes: 0

Ken White
Ken White

Reputation: 125767

Don't use the %Windir%\System32. Use the Windows API's function designed specifically to find that folder, GetSystemDirectory. It's defined in the Windows unit; here's a quick wrapper (not tested on XE2, but works on XE):

Since you had problems with my previous answer, here's a fully-compiling copy of the code (I commented out your references to Edit02, so you'll need to uncomment them; everything else compiles just fine as is under XE2:

uses 
  System.IOUtils;

function GetSysDir: string;
var
  Buffer: array[0..MAX_PATH] of Char;
begin
   GetSystemDirectory(Buffer, MAX_PATH - 1);
   SetLength(Result, StrLen(Buffer));
   Result := Buffer;
end;

{$WARN SYMBOL_PLATFORM OFF}
procedure TForm2.Button1Click(Sender: TObject);
var
  Attributes: TFileAttributes;
  SL: TStringList;
  Idx: Integer;
  PathAndFileName : String;
begin
   PathAndFileName := IncludeTrailingPathDelimiter(GetSysDir) + 'drivers\etc\hosts';
   Attributes := [];
   TFile.SetAttributes(PathAndFileName, Attributes);
   SL := TStringList.Create;
   try
     SL.LoadFromFile(PathAndFileName);

     if SL.IndexOf('10.220.70.34    VIRTSDP25') <> -1 then
     begin
       //Edit02.Font.Color := clRed;
       //Edit02.Text := 'Your Host File Has Already Been Modified Successfully.';
     end;

     if SL.IndexOf('10.220.70.34    VIRTSDP25') = -1 then
     begin
       SL.Add('10.220.70.34    VIRTSDP25');
       //Edit02.Font.Color := clGreen;
       //Edit02.Text := 'Your Host File Has Been Modified Successfully.';
     end;

     if SL.IndexOf('10.220.70.32    BSNLESDP25A') = -1 then
       SL.Add('10.220.70.32    BSNLESDP25A');
     if SL.IndexOf('10.220.70.33    BSNLESDP25B') = -1 then
       SL.Add('10.220.70.33    BSNLESDP25B');
     if SL.IndexOf('10.220.70.34    VIRTBSNLESDP25') = -1 then
       SL.Add('10.220.70.34    VIRTBSNLESDP25');
     if SL.IndexOf('10.220.70.34    KOSDPTwentyfive.bsnl.in.net') = -1 then
       SL.Add('10.220.70.34    KOSDPTwentyfive.bsnl.in.net');
     if SL.IndexOf('10.220.70.34    KOSDPTwentyfive.bsnl.net.in') = -1 then
       SL.Add('10.220.70.34 KOSDPTwentyfive.bsnl.net.in');
     SL.SaveToFile(PathAndFileName);
   finally
       SL.Free;
   end;
    Include(Attributes, TFileAttribute.faSystem);
    Include(Attributes, TFileAttribute.faReadOnly);
    TFile.SetAttributes(PathAndFileName, Attributes);
end;
{$WARN SYMBOL_PLATFORM ON}

Upvotes: 6

Related Questions