Unit MainForm;

{
  Toto je soubor obsluhujici graficke uzivatelske
  rozhrani programu intcount. Starta se o zobrazovani
  hodnot citacu preruseni a rozdilu za posledni vterinu.
}

Interface

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

Type
  TForm1 = Class (TForm)
    ListView1: TListView;
    MainMenu1: TMainMenu;
    Action1: TMenuItem;
    Startmonitoring1: TMenuItem;
    Stopmonitoring1: TMenuItem;
    N1: TMenuItem;
    Exit1: TMenuItem;
    Timer1: TTimer;
    Procedure FormCreate(Sender: TObject);
    Procedure Startmonitoring1Click(Sender: TObject);
    Procedure Stopmonitoring1Click(Sender: TObject);
    Procedure Timer1Timer(Sender: TObject);
    procedure Exit1Click(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
  Private
    CriticalSection : RTL_CRITICAL_SECTION;
    FOldCounters : Array [0..255] Of DWORD;
    FNewCounters : Array [0..255] Of DWORD;
    FDifferences : Array [0..255] Of DWORD;
    Procedure ZeroCounters;
    Procedure UpdateCounters;
    Procedure ShowCounters;
  end;

Var
  Form1: TForm1;

Implementation

{$R *.DFM}

Uses
  Driver, Utils;

Procedure TForm1.UpdateCounters;
{
  Z aktualnich a minulych hodnot pole citacu
  vypocita hodnoty v poli rozdilu. Zaroven nastavi
  aktuani hodnoty pole citacu i za hodnoty minule.
}
Var
  I : Integer;
begin
For I := 0 To 255 Do
  begin
  FDifferences[I] := FNewCounters[I] - FOldCounters[I];
  FOldCounters[I] := FNewCounters[I];
  end;

end;

Procedure TForm1.ZeroCounters;
{
  Vynuluje pole citacu a rozdilu.
}
begin
ZeroMemory(@FOldCounters, SizeOf(FOldCounters));
ZeroMemory(@FNewCounters, SizeOf(FNewCounters));
ZeroMemory(@FDifferences, SizeOf(FDifferences));
end;

Procedure TForm1.ShowCounters;
{
  Zobrazi aktualni stav pole citacu a rozdilu
  do pole ListView.
}
Var
  I : Integer;
  L : TListItem;
begin
ListView1.Items.BeginUpdate;
For I := 0 To 255 Do
  begin
  If I >= ListView1.Items.Count Then
    begin
    L := ListView1.Items.Add;
    L.Caption := Format('#%s', [IntToHex(I, 2)]);
    L.SubItems.Add('');
    L.SubItems.Add('');
    end Else L := Listview1.Items[I];

  L.SubItems[0] := Format('%d', [FOldCounters[I]]);
  L.SubItems[1] := Format('%d', [FDifferences[I]]);
  end;

ListView1.Items.EndUpdate;
end;

Procedure TForm1.Exit1Click(Sender: TObject);
begin
Close;
end;

Procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
{
  Tato rutina je volana pri zavirani hlavniho
  formulare grafickeho uzivatelskeho rozhrani.
  Pokud je monitorovani zapnuto, vypne jej. Dale
  odinstaluje ovladac intcount.sys.
}
begin
If DriverConnected Then
  begin
  DriverDisconnect;
  DriverUnload;
  end;

DriverFinit;
end;

Procedure TForm1.FormCreate(Sender: TObject);
{
  Tato rutina je volana behem vytvareni formulare
  grafickeho uzivatelskeho rozhrani. Nainsstaluje
  ovladac intcount.sys, nastavi viditelnost
  polozek v menu a inicializuje pole citacu a pole
  rozdilu.
}
Var
  Ret : Boolean;
  DriverFileName : WideString;
begin
DriverFileName := ExtractFilePath(ParamStr(0)) + 'intcount.sys';
Ret := DriverInit('intcount', DriverFileName, 'intcount', [$c07fc008]);
If Ret Then
  begin
  StartMonitoring1.Enabled := True;
  StopMonitoring1.Enabled := False;
  ZeroCounters;
  ShowCounters;
  end
Else begin
  Error(Format('Nepodarilo se inicializovat knihovnu pro praci s ovladaci', []));
  StartMonitoring1.Enabled := False;
  StopMonitoring1.Enabled := False;
  end;
end;

Procedure TForm1.Startmonitoring1Click(Sender: TObject);
{
  Zapne monitorovani vyskytu preruseni.
  Rutina nacte ovladace intcount.sys do jadra a
  pripoji se k jeho zarizeni. Dale zapne casovac,
  kterou kazdou sekundu zjistuje aktualni pocet
  vyskytu jednotlivych preruseni.
}
Var
  Ret : Boolean;
begin
Ret := DriverLoad;
If Ret Then
  begin
  Ret := DriverConnect;
  If Ret Then
    begin
    StartMonitoring1.Enabled := False;
    StopMonitoring1.Enabled := True;
    ZeroCounters;
    Timer1.Enabled := True;
    end
  Else begin
    DriverUnload;
    Error(Format('Nepodarilo se pripojit k ovladaci intcount.sys', []));
    end;
  end Else Error(Format('Nepodarilo se nacist ovladac intcount.sys', []));
end;

Procedure TForm1.Stopmonitoring1Click(Sender: TObject);
{
  Zastavi monitorovani vyskytu preruseni.
  Rutina se odpoji od zarizeni ovladace a samotny
  ovladac uvolni z pameti jadra. Take vypne casovac,
  ktery zajistuje zobrazovani vysledku jednou za sekundu.
}
Var
  Ret : Boolean;
begin
Ret := DriverDisconnect;
If Ret Then
  begin
  Timer1.Enabled := False;
  Ret := DriverUnload;
  If Ret Then
    begin
    StopMonitoring1.Enabled := False;
    StartMonitoring1.Enabled := True;
    end Else Error(Format('Nepodarilo se uvolnit ovladac intcount.sys', []));
  end Else Error(Format('Nepodarilo se odpojit od ovladace intcount.sys', []));
end;

Procedure TForm1.Timer1Timer(Sender: TObject);
{
  Tato rutina je volana jednou za vterinu. Z
  ovladace ziska aktualni hodnoty citacu jednotlivych
  preruseni, kterymi nasledne naplni pole citacu
  a pole rozdilu. Nova mereni zobrazi.
}
Var
  Ret : Boolean;
begin
Ret := DriverIOCTL(0, Nil, 0, @FNewCounters, SizeOf(FNewCounters), Nil);
If Ret Then
  begin
  UpdateCounters;
  ShowCounters;
  end;
end;

End.

