Unit MainForm;

{
  Implementace grafickeho uzivatelskeho rozhrani aplikace
  Registrymon. Tato unita obsahuje kod obsluhujici udalosti
  hlavniho formulare.
}

Interface

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

Type
  TForm1 = Class (TForm)
    ListView1: TListView;
    MainMenu1: TMainMenu;
    Soubor1: TMenuItem;
    StartMonMenuItem: TMenuItem;
    StopMonMenuItem: TMenuItem;
    N1: TMenuItem;
    Konec1: TMenuItem;
    pravy1: TMenuItem;
    Vymazatvechnyzznamy1: TMenuItem;
    N3: TMenuItem;
    Uloit1: TMenuItem;
    SaveDialog1: TSaveDialog;
    Procedure StartMonMenuItemClick(Sender: TObject);
    Procedure FormClose(Sender: TObject; var Action: TCloseAction);
    Procedure FormCreate(Sender: TObject);
    Procedure Konec1Click(Sender: TObject);
    Procedure StopMonMenuItemClick(Sender: TObject);
    Procedure ListView1Data(Sender: TObject; Item: TListItem);
    Procedure Vymazatvechnyzznamy1Click(Sender: TObject);
    procedure Uloit1Click(Sender: TObject);
  Private
    FList : TList;
    FCollectThread : TCollectThread;
    FListFreeThread : TListFreeThread;
  Public
    Procedure AddEvents(AList:TList);
  end;

Var
  Form1: TForm1;

Implementation

{$R *.DFM}

Uses
  SCMDrivers, DriverCommands, RegEvents,
  Utils;

Procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
{
  Tato rutina je volana behem zavirani formulare. Zajisti odstraneni
  objektu, ktere za sveho zivota potreboval. Take dochazi k uvolneni
  ovladace registrymon.sys z pameti jadra a k jeho odinstalovani.
}
begin
If StopMonMenuItem.Enabled Then
  StopMonMenuItemClick(Nil);

ListView1.Items.Count := 0;
RegistrymonDriverFinit;
FListFreeThread.AddList(FList);
FListFreeThread.FinishWork;
FListFreeThread.WaitFor;
FListFreeThread.Free;
end;

Procedure TForm1.FormCreate(Sender: TObject);
{
  Tato rutina je volana tesne po vytovreni hlavniho formulare.
  Nainstaluje ovladac registrymon.sys a nacte jej do pameti
  jadra. Zajisti inicializaci vlakna, jehoz ukolem je uvolnovat
  pamet zabiranou seznamu udalosti (ktere mohou byt velmi dlouhe,
  a tudiz operace jejich odstraneni muze trvat dost dlouho).
}
begin
FCollectthread := Nil;
FListFreeThread := TListFreeThread.Create(False);
FList := TList.Create;
ListView1.Clear;
RegistrymonDriverInit;
StartMonMenuItem.Enabled := True;
StopMonMenuItem.Enabled := False;
end;

Procedure TForm1.Konec1Click(Sender: TObject);
{
  Reakce na stisknuti volby "Konec"
}
begin
Close;
end;

Procedure TForm1.ListView1Data(Sender: TObject; Item: TListItem);
{
  Zajisti vykresleni udalosti na dane pozici v seznamu udalosti.
  Tato pozice je urcena indexem polozky v prvku ListView.
}
Var
  U : PUM_EVENT;
  ST : SYSTEMTIME;
  OI : PREG_EVENT_GENERAL_INFO;
begin
If Item.Index < FList.Count Then
  begin
  U := FList[Item.Index];
  OI := RegEventGetGeneralInfo(U);
  FileTimeToSystemTime(FILETIME(u.EventTime), ST);
  With Item DO
    begin
    Caption := DateTimeToStr(SystemTimeToDateTime(ST));
    SubItems.Add(Format('%s (%d)', [GetProcessName(OI.PID), OI.PID]));
    SubItems.Add(Format('%d', [OI.TID]));
    SubItems.Add(Format('%s', [RegEventTypeToStr(U.EventType)]));
    SubItems.Add(Format('%x', [Cardinal(OI.ResultStatus)]));
    SubItems.Add(Format('%s', [RegEventToInfo(U)]));
    end;
  end;
end;

Procedure TForm1.StartMonMenuItemClick(Sender: TObject);
{
  Vykona se po kliknuti na volbu pro zahajeni monitorovani udalosti
  nad registrem. Rutina nacte ovladac registrymon.sys do pameti
  jadra, pripoji se k jeho zarizeni a vytvori vlakno, ktere bude
  z neho sbirat udalosti.
}
Var
  Ret : Boolean;
  TID : DWORD;
begin
Ret := RegistrymonDriverLoad;
If Ret Then
  begin
  FCollectThread := TCollectThread.Create(False);
  StartMonMenuItem.Enabled := Not Ret;
  StopMonMenuItem.Enabled := Ret;
  end Else Error(Format('Nepodarilo se spustit ovladac: %s', [SysErrorMessage(GetLastError)]));
end;

Procedure TForm1.StopMonMenuItemClick(Sender: TObject);
{
  Vykona se pri kliknuti na volbu zastaveni monitorovani. Uvolni
  ovladac z jadra a zastavi vlakno sbirajici udalosti.
}
begin
FCollectThread.Terminate;
FCollectThread.WaitFor;
FreeAndNil(FCollectThread);
RegistrymonDriverUnload;
StartMonMenuItem.Enabled := True;
StopMonMenuItem.Enabled := False;
end;

Procedure TForm1.Uloit1Click(Sender: TObject);
{
  Ulozi nasbirane udalosti do souboru .log.
}
Var
  LogFileName : WideString;
  S : TStringList;
  I : Integer;
  U : PUM_EVENT;
  ST : SYSTEMTIME;
  OI : PREG_EVENT_GENERAL_INFO;
begin
If SaveDialog1.Execute Then
  begin
  LogFileName := ChangeFileExt(SaveDialog1.FileName, '.log');
  S := TStringList.Create;
  For I := 0 To Flist.Count - 1 Do
    begin
    U := FList[I];
    OI := RegEventGetGeneralInfo(U);
    FileTimeToSystemTime(FILETIME(u.EventTime), ST);
    S.Add(Format('Cas: %s', [DateTimeToStr(SystemTimeToDateTime(ST))]));
    S.Add(Format('Proces: %s (%d)', [GetProcessName(OI.PID), OI.PID]));
    S.Add(Format('Vlakno: %d', [OI.TID]));
    S.Add(Format('Typ: %s', [RegEventTypeToStr(U.EventType)]));
    S.Add(Format('Vysledek: %x', [Cardinal(OI.ResultStatus)]));
    S.Add(Format('Info: %s', [RegEventToInfo(U)]));
    S.Add('');
    end;

  S.SaveToFile(LogFileName);
  S.Free;
  end;
end;

Procedure TForm1.Vymazatvechnyzznamy1Click(Sender: TObject);
{
  Vyprazdni seznam nasbiranych udalosti.
}
begin
ListView1.Items.Count := 0;
FListFreeThread.AddList(FList);
FList := TList.Create;
end;

Procedure TForm1.AddEvents(AList:TList);
{
  Prevede udalosti ze zadaneho seznamu do seznamu udalosti hlavniho
  formulare, ktere jsou nasledne zobrazovany do prvku ListView.
}
Var
  I : Integer;
begin
For I := 0 To AList.Count - 1 Do
  FList.Add(AList[I]);

ListView1.Items.Count := FList.Count;
end;

End.

