Unit MaonForm;

{
  Tento soubor se stara o graficke uzivatelske rozhrani aplikace.
  Zajistuje vykreslovani jednotlivych udalosti zaznamenanych
  ovladacem obinit.sys na plochu ovladaciho prvku ListView a dovoluje
  uzivateli nacitat a uvolnovat ovladac jadra.
}

interface

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

Type
  TForm1 = Class (TForm)
    ListView1: TListView;
    Timer1: TTimer;
    Procedure Timer1Timer(Sender: TObject);
    Procedure FormClose(Sender: TObject; var Action: TCloseAction);
    Procedure FormCreate(Sender: TObject);
  private
    Procedure PrintEventGeneralInfo(ListItem:TListItem; Event:PUM_EVENT);
    Procedure PrintEventSpecificInfo(ListItem:TListItem; Event:PUM_EVENT);
  end;

var
  Form1: TForm1;

Implementation

{$R *.dfm}

Uses
  Utils;

Procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
{
  Tato rutina je volana tesne pred zavrenim hlavniho formulare
  grafickeho uzivatelskeho rozhrani. Zajisti uvolneni ovladace
  obinit.sys z pameti jadra a odinstalovani jeho sluzby.
}
begin
ObinitDriverUnload;
ObinitDriverFinit;
end;

Procedure TForm1.FormCreate(Sender: TObject);
{
  Tato rutina je volana tesne po vytvoreni formulare. Zajisti
  instalaci sluzby pro ovladac obinit.sys a nacte jej do jadra.
  Dale zapne i casovac, ktery kazdou vterinu z ovladace
  sbira udalosti o operacich nad sledovanymi typy objektu.
}
Var
  Ret : Boolean;
begin
ObinitDriverInit;
Ret := ObinitDriverLoad;
Timer1.Enabled := Ret;
If Not Ret Then
  Error('Nepodarilo se nacist ovladac obinit.sys');
end;

Procedure TForm1.PrintEventGeneralInfo(ListItem:TListItem; Event:PUM_EVENT);
{
  Vytiskne informace spolecne pro vsechny udalosti
}
Var
  Ret : Boolean;
  SysTime : SYSTEMTIME;
  ObjectName : WideString;
  ObjectTypeName : WideString;
  PID : DWORD;
  TID : DWORD;
  Obj : Pointer;
  ProcessId : DWORD;
  OperationType : TObjectOperationType;
  AccessMode : TAccessMode;
  AccessModeString : WideString;
  ActionString : WideString;
begin
FileTimeToSystemTime(FILETIME(Event.Time), SysTime);
GetLocalTime(SysTime);
Ret := ObinitDriverEventGetNames(Event, ObjectName, ObjectTypeName);
If Ret Then
  begin
  Ret := ObinitDriverEventGetContext(Event, TID, PID, Obj, ProcessId, AccessMode);
  If Ret Then
    begin
    OperationType := ObinitDriverEventGetOperationType(Event);
    ListItem.Caption := Format('%u. %u. %u %u:%u:%u', [SysTime.wDay, SysTime.wMonth, SysTime.wYear, SysTime.wHour, SysTime.wMinute, SysTime.wSecond]);
    ListItem.SubItems.Add(Format('%s (%d)', [GetProcessName(PID), PID]));
    ListItem.SubItems.Add(IntToStr(Int64(TID)));
    ListItem.SubItems.Add(Format('%s (%d)', [GetProcessName(ProcessId), ProcessId]));

    Case AccessMode Of
      amUknown : AccessModeString := 'Neznámý';
      amKernel : AccessModeString := 'Kernel';
      amUser : AccessModeString := 'User';
      Else AccessModeString := '<chyba>';
      end;

    ListItem.SubItems.Add(AccessModeString);
    Case OperationType Of
      ootUnknown : ActionString := '!Neznámá!';
      ootCreateHandle : ActionString := 'Vytvořen';
      ootOpenHandle : ActionString := 'Otevřen';
      ootDuplicateHandle : ActionString := 'Duplikace handle';
      ootInheritHandle : ActionString := 'Dědění handle';
      ootCloseHandle : ActionString := 'Zrušení handle';
      ootOkayToClose : ActionString := 'Zrušení handle povoleno?';
      ootDelete : ActionString := 'Odstranění';
      Else ActionString := '!<chyba>';
      end;

    ListItem.SubItems.Add(ActionString);
    ListItem.SubItems.Add(Format('%s (%s)', [ObjectName, ObjectTypeName]));
    end
  Else Error('Nepodarilo se ziskat obsah udalosti!');
  end
Else Error('Nepodarilo se ziskat jmena objektu!');
end;

Procedure TForm1.PrintEventSpecificInfo(ListItem:TListItem; Event:PUM_EVENT);
{
  Zobrazi informace specificke pro dany typ udalosti.
}
Var
  OpenEvent : PEVENT_OPEN;
  CloseEvent : PEVENT_CLOSE;
  OkayToCloseEvent : PEVENT_OKAYTOCLOSE;
  DeleteEvent : PEVENT_DELETE;
  DisplayString : WideString;
begin
OpenEvent := Nil;
CloseEvent := Nil;
OkayToCloseEvent := Nil;
DeleteEvent := Nil;
DisplayString := '';
Case Event.EventType Of
  etOpen : begin
    OpenEvent := PEVENT_OPEN(PByte(Event) + SizeOf(UM_EVENT));
    DisplayString := Format('Získaný přístup: 0x%x, Návratový kód: 0x%x', [Int64(OpenEvent.GrantedAccess), Int64(OpenEvent.Status)]);
    end;

  etClose : begin
    CloseEvent := PEVENT_CLOSE(PByte(Event) + SizeOf(UM_EVENT));
    DisplayString := Format('Přístup handle: 0x%x', [Int64(CloseEvent.GrantedAccess)]);
    end;

  etOkayToClose : begin
    OkayToCloseEvent := PEVENT_OKAYTOCLOSE(PByte(Event) + SizeOf(UM_EVENT));
    DisplayString := Format('Handle: 0x%x, zrušení povoleno: %d', [Int64(OkayToCloseEvent.Handle), Integer(OkayToCloseEvent.CloseAllowed)]);
    end;

  etDelete : begin
    DeleteEvent := PEVENT_DELETE(PByte(Event) + SizeOf(UM_EVENT));
    DisplayString := '-';
    end;
  end;

ListItem.SubItems.Add(DisplayString);
end;

Procedure TForm1.Timer1Timer(Sender: TObject);
{
  Tato rutina je volana jednou za periodu casovace (1 sekunda).
  Zajistuje sesbirani udalosti o operacich nad sledovanymi typy
  objektu z ovladace obinit.sys a neprimo zpusobi jejich zobrazeni
  v poli ovladaciho prvku ListView.
}
Var
  Event : PUM_EVENT;
  Ret : Boolean;
  L : TListItem;
begin
Ret := True;
ListView1.Items.BeginUpdate;
While Ret Do
  begin
  Ret := ObinitDriverGetEvent(Event);
  If Ret Then
    begin
    L := ListView1.Items.Add;
    PrintEventGeneralInfo(L, Event);
    PrintEventSpecificInfo(L, Event);
    HeapFree(GetProcessHeap, 0, Event);
    end;
  end;

ListView1.Items.EndUpdate;
end;

end.

