Unit MainForm;

{
  Implementace reakci na udalosti hlavniho formulare aplikace VAD.
}

Interface

Uses
  Windows, Messages, SysUtils, Variants, Classes,
  Graphics, Controls, Forms,
  Dialogs, ComCtrls, ExtCtrls, Menus;

Type
  TForm1 = Class (TForm)
    Panel1: TPanel;
    Panel2: TPanel;
    ListView1: TListView;
    ListView2: TListView;
    MainMenu1: TMainMenu;
    Akce1: TMenuItem;
    Vybratproces1: TMenuItem;
    N1: TMenuItem;
    Konec1: TMenuItem;
    Uloit1: TMenuItem;
    SaveDialog1: TSaveDialog;
    Aktualizovat1: TMenuItem;
    Procedure FormClose(Sender: TObject; var Action: TCloseAction);
    Procedure FormCreate(Sender: TObject);
    Procedure ListView1Data(Sender: TObject; Item: TListItem);
    Procedure Konec1Click(Sender: TObject);
    Procedure Vybratproces1Click(Sender: TObject);
    Procedure ListView1SelectItem(Sender: TObject; Item: TListItem;
      Selected: Boolean);
    Procedure Uloit1Click(Sender: TObject);
    Procedure ListView2Data(Sender: TObject; Item: TListItem);
    procedure Aktualizovat1Click(Sender: TObject);
  Private
    FVadList : TList;
    FSelectedVadInfo : TStringList;
    FProcessId : DWORD;
    Procedure ShowProcessVADS;
    Procedure ShowSelectedVADInfo(Item:TListItem);
  end;

Var
  Form1: TForm1;

Implementation

{$R *.DFM}

Uses
  Utils, VadLib, SelectProcessForm;

Procedure TForm1.ShowProcessVADS;
{
  Nacte seznam virtualnich deskriptoru procesu, jehoz PID je ulozeno
  v atributu FProcessId do seznamu TList ulozenem v promenne FVadList.

  Nasledne donuti ovladaci prvek ListView tyto polozky zobrazit.
}
begin
ListView1.Items.Count := 0;
FreeVadRecordList(FVadList, False);
If Not VadLibGetVadListForProcess(FProcessId, FVadList) Then
  begin
  Error('Nepodarilo se ziskat seznam VADu ciloveho procesu!');
  FreeVadRecordList(FVadList, False);
  end
Else ListView1.Items.Count := FVadList.Count
end;

Procedure TForm1.Vybratproces1Click(Sender: TObject);
{
  Zajisti zobrazeni formulare pro vyber procesu. PID tatko vybraneho
  procesu zapise do atributu FProcessId a zajisti zobrazeni jeho
  virtualnich deskriptoru.
}
begin
With TSelectProcess.Create(Application) Do
  begin
  ShowModal;
  If Not Canceled Then
    begin
    Form1.Caption := Format('VAD – %s (%d)', [ProcessName, ProcessId]);
    FProcessId := ProcessId;
    ShowProcessVADs;
    end;

  Free;
  end;
end;

Procedure TForm1.Aktualizovat1Click(Sender: TObject);
{
  Reakce na klik na polozku aktualizovat v menu.
  Znovu nacte seznam deskriptoru pro dany proces
  a zobrazi jej.
}
begin
ListView2.Items.Count := 0;
FSelectedVADInfo.Clear;
ShowProcessVADs;
end;

Procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
{
  Rutina je volana pri zavirani formulare. Zrusi seznam virtualnch
  deskriptoru a provede uklid knihovny pro praci s VADy.
}
begin
ListView2.Items.Count := 0;
FSelectedVADInfo.Free;
ListView1.Items.Count := 0;
FreeVadRecordList(FVadList);
VadLibFinit;
end;

Procedure TForm1.FormCreate(Sender: TObject);
{
  Rutina je volana tesne po vytvoreni formulare. Inicializuje knihovnu
  pro praci s VADy, naplni atribut FProcessId cislem aktualniho procesu,
  jehoz seznam VADu nasledne zobrazi v ovladacim prvku Listview.
}
Var
  Ret : Boolean;
begin
Ret := VadLibInit;
If Ret Then
  begin
  FVadList := TList.Create;
  FProcessId := GetCurrentProcessId;
  FSelectedVADInfo := TStringList.Create;
  FSelectedVadInfo.Delimiter := '=';
  Caption := Format('VAD – %s (%d)', [ExtractFileName(ParamStr(0)), FProcessId]);
  ShowProcessVADS;
  end
Else Error('Nepodarilo se nacist ovladac vad.sys!');
end;

Procedure TForm1.Konec1Click(Sender: TObject);
{
  Reakce na kliknuti na tlacitko "Konec" v hlavnim menu.
}
begin
Close;
end;

Function BooleanToStr(B:Boolean):WideString;
{
  Pomocna funkce prevadejici hodnotu typu Boolean na retezec
}
begin
If B Then
  Result := '1'
Else Result := '0';
end;

Procedure TForm1.ShowSelectedVADInfo(Item:TListItem);
{
  Zobrazi informace o prave oznacenem VADu do bocniho ovladaciho
  prvku ListView.

  POZOR: Rutina nekontroluje, o jaky VAD se jedna. Zobrazuje vzdy
  hodnoty vsech priznaku (i tech neplatnych v danem kontextu, ktere
  maji ale vzdy hodnotu 0).
}
Var
  VR : PVadRecord;
  I : Integer;
begin
VR := FVadList[Item.Index];
ListView2.Items.Count := 0;
FSelectedVadInfo.Clear;
FSelectedVadInfo.Add(Format('%s=%s', ['NoChange', BooleanToStr(VR.NoChange)]));
FSelectedVadInfo.Add(Format('%s=%s', ['MemCommit', BooleanToStr(VR.MemCommit)]));
FSelectedVadInfo.Add(Format('%s=%s', ['PrivateMemory', BooleanToStr(VR.PrivateMemory)]));
FSelectedVadInfo.Add(Format('%s=%x', ['Protection', VR.Protection]));
If (IsWindowsVista) Or (IsWindows7) Then
  begin
  FSelectedVadInfo.Add(Format('%s=%x', ['PreferredMode', VR.PreferredMode]));
  FSelectedVadInfo.Add(Format('%s=%s', ['Teb', BooleanToStr(VR.Teb)]));
  end;

If (VR.VadStructureType = vstNormal) Or
   (VR.VadStructureType = vstLong) Then
  begin
  FSelectedVadInfo.Add(Format('%s=%x', ['FileOffset', VR.FileOffset]));
  FSelectedVadInfo.Add(Format('%s=%s', ['SecNoChange', BooleanToStr(VR.SecNoChange)]));
  FSelectedVadInfo.Add(Format('%s=%s', ['OneSecured', BooleanToStr(VR.OneSecured)]));
  FSelectedVadInfo.Add(Format('%s=%s', ['MultipleSecured', BooleanToStr(VR.MultipleSecured)]));
  FSelectedVadInfo.Add(Format('%s=%s', ['ReadOnly', BooleanToStr(VR.ReadOnly)]));
  FSelectedVadInfo.Add(Format('%s=%s', ['LongVad', BooleanToStr(VR.LongVad)]));
  FSelectedVadInfo.Add(Format('%s=%s', ['Extendible', BooleanToStr(VR.Extendable)]));
  FSelectedVadInfo.Add(Format('%s=%s', ['Inherit', BooleanToStr(VR.Inherit)]));
  FSelectedVadInfo.Add(Format('%s=%s', ['CopyOnWrite', BooleanToStr(VR.CopyOnWrite)]));
  end;

If (VR.VadStructureType = vstLong) Then
  begin
  If VR.SecureEntryCount > 0 Then
    begin
    FSelectedVadInfo.Add(Format('%s=%d', ['Secured regions', VR.SecureEntryCount]));
    For I := 0 To VR.SecureEntryCount - 1 Do
      begin
      FSelectedVadInfo.Add(Format('%s=%x', ['RegionStart', VR.SecureEntries[I].StartingVpn]));
      FSelectedVadInfo.Add(Format('%s=%x', ['RegionEnd', VR.SecureEntries[I].EndingVpn]));
      FSelectedVadInfo.Add(Format('%s=%s', ['ReadOnly', BooleanToStr(VR.SecureEntries[I].ReadOnly)]));
      end;
    end;
  end;

ListView2.Items.Count := FSelectedVADInfo.Count;
end;


Procedure TForm1.Uloit1Click(Sender: TObject);
{
  Reakce na stisknuti tlacitka Ulozit. Ulozi
  seznam VADu aktualne vybraneho procesu a jejich
  vnitrni hodnoty do textoveho souboru.
}
Var
  S : TStringList;
  I, J : Integer;
  VR : PVadRecord;
begin
If SaveDialog1.Execute Then
  begin
  S := TStringList.Create;
  For I := 0 To FVadList.Count - 1 Do
    begin
    VR := FVadList[I];
    S.Add(Format('Start address: 0x%s', [IntToHex(VR.StartAddress, GetPointerLength * 2)]));
    S.Add(Format('End address: 0x%s', [IntToHex(VR.EndAddress, GetPointerLength * 2)]));
    S.Add(Format('VAD type: %s', [VadLibVadTypeToStr(VR.VadType)]));
    S.Add(Format('VAD structure type: %s', [VadLibVadStructureToStr(VR.VadStructureType)]));
    S.Add('Flags (the first group)');
    S.Add(Format('    Quota charge: 0x%s', [IntToHex(VR.CommitCharge, GetPointerLength * 2)]));
    S.Add(Format('    NoChange: %s', [BooleanToStr(VR.NoChange)]));
    S.Add(Format('    MemCommit: %s', [BooleanToStr(VR.MemCommit)]));
    S.Add(Format('    PrivateMemory: %s', [BooleanToStr(VR.PrivateMemory)]));
    S.Add(Format('    Protection: 0x%x', [VR.Protection]));
    If (VR.VadStructureType = vstNormal) Or
       (VR.VadStructureType = vstLong) Then
      begin
      S.Add('Flags (the second group))');
      S.Add(Format('    FileOffset: 0x%x B', [VR.FileOffset * 65536]));
      S.Add(Format('    SecNoChange: %s', [BooleanToStr(VR.SecNoChange)]));
      S.Add(Format('    OneSecured: %s', [BooleanToStr(VR.OneSecured)]));
      S.Add(Format('    MultipleSecured: %s', [BooleanToStr(VR.MultipleSecured)]));
      S.Add(Format('    ReadOnly: %s', [BooleanToStr(VR.ReadOnly)]));
      S.Add(Format('    LongVad: %s', [BooleanToStr(VR.LongVad)]));
      S.Add(Format('    Inherit: %s', [BooleanToStr(VR.Inherit)]));
      S.Add(Format('    Extensible: %s', [BooleanToStr(VR.Extendable)]));
      S.Add(Format('    CopyOnWrite: %s', [BooleanToStr(VR.CopyOnWrite)]));
      end;

    If (IsWindowsVista) Or (IsWindows7) Then
      begin
      S.Add('Flags (the third group)');
      S.Add(Format('    PreferredMode: 0x%x', [VR.PreferredMode]));
      S.Add(Format('    Teb: %s', [BooleanToStr(VR.Teb)]));
      end;

    If (VR.VadStructureType = vstLong) And
       (VR.SecureEntryCount > 0) Then
      begin
      S.Add('Secured regions');
      For J := 0 To VR.SecureEntryCount - 1 Do
        begin
        S.Add(Format('    Region start: 0x%s', [IntToHex(VR.SecureEntries[J].StartingVpn, GetPointerLength * 2)]));
        S.Add(Format('    Region end: 0x%s', [IntToHex(VR.SecureEntries[J].EndingVpn, GetPointerLength * 2)]));
        S.Add(Format('    ReadOnly: %s', [BooleanToStr(VR.SecureEntries[J].ReadOnly)]));
        S.Add('');
        end;
      end;

    S.Add('');
    end;

  Try
    S.SaveToFile(SaveDialog1.FileName);;
  Except
    Error('Data se nepodarilo ulozit do souboru');
    end;

  S.Free;
  end;
end;

Procedure TForm1.ListView1Data(Sender: TObject; Item: TListItem);
{
  Zobrazuje zakladni informace o VADu reprezentovanem
  polozkou Item. Tim zajistuje vykresleni spravnych udaju do
  hlavniho ovladaciho prvku ListView.
}
Var
  VR : PVadRecord;
begin
VR := FVadList[Item.Index];
Item.Caption := IntToHex(VR.StartAddress, GetPointerLength * 2);
Item.SubItems.Add(IntToHex(VR.EndAddress, GetPointerLength * 2));
Item.SubItems.Add(Format('0x%s B', [IntToHex(VR.CommitCharge, GetPointerLength * 2)]));
Item.SubItems.Add(Format('%s', [VadLibVadTypeToStr(VR.VadType)]));
Item.SubItems.Add(Format('%s', [VadLibVadStructureToStr(VR.VadStructureType)]));
end;

Procedure TForm1.ListView1SelectItem(Sender: TObject; Item: TListItem;
  Selected: Boolean);
begin
If Selected Then
  ShowSelectedVADInfo(Item);
end;

Procedure TForm1.ListView2Data(Sender: TObject; Item: TListItem);
begin
With Item Do
  begin
  Caption := FSelectedVADInfo.Names[Index];
  SubItems.Add(FSelectedVadInfo.ValueFromIndex[Index]);
  end;
end;

End.

