Unit MainForm;

{
  Tento soubor implementuje obsluhu udalosti hlavniho formulare
  grafickeho uzivatelskeho rozhrani.
}

Interface

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

Type
  TForm1 = Class (TForm)
    ListView1: TListView;
    MainMenu1: TMainMenu;
    Akce1: TMenuItem;
    Start1: TMenuItem;
    Stop1: TMenuItem;
    N1: TMenuItem;
    Konec1: TMenuItem;
    pravy1: TMenuItem;
    Vymazatobrazovku1: TMenuItem;
    Procedure Konec1Click(Sender: TObject);
    Procedure FormClose(Sender: TObject; var Action: TCloseAction);
    Procedure FormCreate(Sender: TObject);
    Procedure Start1Click(Sender: TObject);
    Procedure Stop1Click(Sender: TObject);
    Procedure ListView1Data(Sender: TObject; Item: TListItem);
    Procedure Vymazatobrazovku1Click(Sender: TObject);
  Private
    FRecords : TList;
    FServiceList : TStringList;
    Procedure StartMonitoring;
    Procedure StopMonitoring;
  Public
    Property Records : TList Read FRecords;
  end;

Var
  Form1: TForm1;

Implementation

Uses
  scmDrivers, Utils, CollectThread,
  DriverCommands;

{$R *.DFM}

Var
  FCollectThread : TCollectThread;


Procedure TForm1.Start1Click(Sender: TObject);
begin
StartMonitoring;
end;

Procedure TForm1.StartMonitoring;
{
  Zahaji sbirani dat o systemovych volanich.
  Rutina vytvori sbiraci vlakno a upravi zabarveni
  a funkcnost polozek v menu.
}
Var
  Ret : Boolean;
begin
FCollectThread := TCollectThread.Create(True);
Ret := SyscallmonDriverStart;
If Not Ret Then
  Error(Format('Nepodarilo se zahajit monitorovani: %s (%d)', [SysErrorMessage(GetLastError), GetLastError]));

Start1.Enabled := Not Ret;
Stop1.Enabled := Ret;
If Ret Then
  FCollectThread.Resume
Else FreeAndNil(FCollectThread);
end;

Procedure TForm1.Stop1Click(Sender: TObject);
begin
StopMonitoring;
end;

Procedure TForm1.StopMonitoring;
{
  Zastavi zaznamenavani systemovych volani. Rutina
  take resi obarveni a funkcnost polozek v menu a
  ukonci sbiraci vlakno.
}
Var
  Ret : Boolean;
begin
Ret := SyscallmonDriverStop;
Start1.Enabled := Ret;
Stop1.Enabled := Not Ret;
If Ret Then
  begin
  if Assigned(FCollectThread) Then
    begin
    FCollectThread.Terminate;
    FCollectThread.WaitFor;
    FreeAndNil(FCollectThread);
    end;
  end;
end;

Procedure TForm1.Vymazatobrazovku1Click(Sender: TObject);
{
  Vymaze zaznamy v seznamu hlavniho formulare. Tim dojde k vymazani
  vsech zaznamu zobrazenych na obrazovce.
}
Var
  I : Integer;
begin
ListView1.Items.Count := 0;
For I := 0 To FRecords.Count - 1 Do
  HeapFree(GetProcessHeap, 0, FRecords[I]);

FRecords.Clear;
end;

Procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
{
  Tato rutina je volana tesne pred zavrenim hlavniho formulare.
  Zastavi zaznamenavani systemovych volani, odstrani zaznamy ze seznamu
  hlavniho formulare, uvolni a odinstaluje ovladac syscallmon.sys.
}
Var
  I : Integer;
begin
StopMonitoring;
If Assigned(FRecords) Then
  begin
  For I := 0 To FRecords.Count - 1 Do
    HeapFree(GetProcessHeap, 0, FRecords[I]);

  FreeAndNil(FRecords);
  end;

If Assigned(FServiceList) Then
  FreeAndNil(FServiceList);

SyscallmonDriverFinit;
end;

Procedure TForm1.FormCreate(Sender: TObject);
{
  Tato rutina je volana tesne po vytvoreni hlavniho formulare.
  Nainstaluje ovladac syscallmon.sys, nacte do pameti tabulku nazvu
  systemovych sluzeb pro dany operacni system a nacte ovladac do
  pameti.
}
Var
  Ret : Boolean;
  FileName : WideString;
  Major, Minor, Build : DWORD;
begin
FRecords := Nil;
Stop1.Enabled := False;
Start1.Enabled := False;
Ret := SyscallmonDriverInit;
If Ret Then
  begin
  GetOSVersion(Major, Minor, Build);
  FileName := Format('%s\ssdt-%d-%d-%d.dat', [ExtractFilePath(ParamStr(0)), Major, Minor, Build]);
  FServiceList := TStringList.Create;
  Try
    FServiceList.LoadFromFile(FileName);
    Ret := True;
  Except
    Ret := False;
    end;

  If Ret Then
    begin
    Ret := SyscallmonDriverLoad;
    If Ret Then
      begin
      FRecords := TList.Create;
      Start1.Enabled := True;
      end
    Else begin
      FServiceList.Clear;
      SyscallmonDriverFinit;
      Error(Format('Nepodařilo se nacist ovladac. %s', [SysErrorMessage(GetLastError)]));
      end;
    end
  Else begin
    FServiceList.Free;
    SyscallmonDriverFinit;
    Error('Nepodarilo se nacist jmena systemovych sluzeb');
    end;
  end
Else Error(Format('Služba ovladače není nainstalována, nebo se ji nainstalovat nepodařilo. %s', [SysErrorMessage(GetLastError)]));
end;

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

Procedure TForm1.ListView1Data(Sender: TObject; Item: TListItem);
{
  Zobrazi udaje o systemovych volanich. Zobrazuje pouze zaznamy,
  ktere je treba prekreslit.
}
Var
  SR : PSYSCALL_RECORD;
  SysTime : SYSTEMTIME;
  D : TDateTime;
begin
SR := FRecords[Item.Index];
FileTimeToSystemTime(SR.Time, SysTime);
D := SystemTimeToDateTime(SysTime);
With Item Do
  begin
  Caption := DateTimeToStr(D);
  SubItems.Add(Format('%s (%d)', [GetProcessName(SR.PID), SR.PID]));
  SubItems.Add(IntToStr(SR.TID));
  SubItems.Add(FServiceList[SR.ServiceIndex]);
  SubItems.Add(Format('%x', [SR.Status]));
  end;
end;

End.

