Unit DriverCommands;

{
  Tento soubor implementuje rutiny pracujici primo s ovladacem
  vad.sys. Jedna se o vrstvu kodu mezi knihovnou VadLib a jadrem
  operacniho systemu.
}

Interface

Uses
  Windows;

Const
  // Definice prvni skupiny priznaku virtualniho deskriptoru
  // (32bit OS)
  VAD_FLAGS1_COMMITCHARGE_X86 =     $7FFFF;
  VAD_FLAGS1_NOCHANGE_X86 =         $80000;
  VAD_FLAGS1_VADTYPE_X86 =          $700000;
  VAD_FLAGS1_MEMCOMMIT_X86 =        $800000;
  VAD_FLAGS1_PROTECTION_X86 =       $1f000000;
  VAD_FLAGS1_PROTECTION_SHIFT_X86 = $1000000;
  VAD_FLAGS1_SPARE_X86 =            $60000000;
  VAD_FLAGS1_PRIVATEMEMORY_X86 =    $80000000;

  // Definice prvni skupiny priznaku virtualniho deskriptoru
  // (64bit OS)
  VAD_FLAGS1_COMMITCHARGE_X64 =     $7FFFFFFFFFFFF;
  VAD_FLAGS1_NOCHANGE_X64 =         $8000000000000;
  VAD_FLAGS1_VADTYPE_X64 =          $70000000000000;
  VAD_FLAGS1_MEMCOMMIT_X64 =        $80000000000000;
  VAD_FLAGS1_PROTECTION_X64 =       $1f00000000000000;
  VAD_FLAGS1_PROTECTION_SHIFT_X64 = $100000000000000;
  VAD_FLAGS1_SPARE_X64 =            $6000000000000000;
  VAD_FLAGS1_PRIVATEMEMORY_X64 =    $8000000000000000;

  // Definice druhe skupiny priznaku virtualniho deskriptoru
  VAD_FLAGS2_FILEOFFSET =           $FFFFFF;
  VAD_FLAGS2_SECNOCHANGE =          $1000000;
  VAD_FLAGS2_ONESECURED =           $2000000;
  VAD_FLAGS2_MULTIPLESECURED =      $4000000;
  VAD_FLAGS2_READONLY =             $8000000;
  VAD_FLAGS2_LONGVAD =             $10000000;
  VAD_FLAGS2_EXTENDABLE =          $20000000;
  VAD_FLAGS2_INHERIT =             $40000000;
  VAD_FLAGS2_COPYONWRITE =         $80000000;

  // Definice treti skupiny priznaku virtualniho deskriptoru
  VAD_FLAGS3_PREFERREDMODE = $3f;
  VAD_FLAGS3_TEB = $40;
  VAD_FLAGS3_SPARE = $80;
  VAD_FLAGS3_SEQUENTIALACCESS = $100;

  // Konstanty pro urceni typu struktury VADu
  VAD_TYPE_UNKNOWN = 0;
  VAD_TYPE_SHORT = 1;
  VAD_TYPE_NORMAL = 2;
  VAD_TYPE_LONG = 3;
  VAD_TYPE_MAPPED = 4;

Type
  _VAD_SECURE_INFO_ENTRY = Record
    StartingVpn : Int64;
    EndingVpn : Int64;
    ReadOnly : Int64;
    end;
  VAD_SECURE_INFO_ENTRY = _VAD_SECURE_INFO_ENTRY;
  PVAD_SECURE_INFO_ENTRY = ^VAD_SECURE_INFO_ENTRY;

  _VAD_SECURE_INFO = Record
    EntryCount : Int64;
    Entries : Packed Array [0..1] Of VAD_SECURE_INFO_ENTRY;
    end;
  VAD_SECURE_INFO = _VAD_SECURE_INFO;
  PVAD_SECURE_INFO = ^VAD_SECURE_INFO;

  // Definice zaznamu UM_VAD_RECORD. Je plne kompatibilni s definici
  // v ovladaci vad.sys
  _UM_VAD_RECORD = Record
    Length : Int64;
    StartAddress : Int64;
    EndAddress : Int64;
    StructureType : DWORD;
    VadType : DWORD;
    Flags1 : Int64;
    Flags2 : Int64;
    Flags3 : Int64;
    SecureInfo : VAD_SECURE_INFO;
    end;
  UM_VAD_RECORD = _UM_VAD_RECORD;
  PUM_VAD_RECORD = ^UM_VAD_RECORD;

  // Definice vystupniho bufferu prikazu IOCTL_VAD_GET
  _VAD_LIST = Record
    Count : Int64;
    end;
  VAD_LIST = _VAD_LIST;
  PVAD_LIST = ^VAD_LIST;

Function VadDriverInit:Boolean;
Procedure VadDriverFinit;
Function VadDriverLoad:Boolean;
Procedure VadDriverUnload;
Function VadDriverGetVadList(ProcessId:DWORD; List:PVAD_LIST; ListLength:DWORD):Boolean;

Implementation

Uses
  Driver, SysUtils, Utils;

Const
  // Kod prikazu pro ziskani seznamu virtualnich deskriptoru
  // procesu
  IOCTL_VAD_GET = $c07fc004;


Function VadDriverInit:Boolean;
{
  Nainstaluje ovladac vad.sys jako sluzbu a nastavi jmeno jeho
  zarizeni a podporovane zpravy IOCTL.
}
begin
Result := DriverInit('vad', ExtractFilePath(ParamStr(0)) + 'vad.sys', 'vad', [IOCTL_VAD_GET]);
end;

Procedure VadDriverFinit;
{
  Odinstaluje ovladac vad.sys. Neuvolni jej vsak z pameti jadra,
  pokud tam ovladac je.
}
begin
DriverFinit;
end;

Function VadDriverLoad:Boolean;
{
  Nacte ovladac vad.sys do pameti jadra a pripoji se k jeho
  komunikacnimu zarizeni
}
begin
Result := DriverLoad;
If Result Then
  begin
  Result := DriverConnect;
  If Not Result Then
    DriverUnload;
  end;
end;

Procedure VadDriverUnload;
{
  Odpoji se od komunikacniho zarizeni ovladace vad.sys a samotny
  ovladac uvolni z pameti jadra.
}
begin
DriverDisconnect;
DriverUnload;
end;

Function VadDriverGetVadList(ProcessId:DWORD; List:PVAD_LIST; ListLength:DWORD):Boolean;
{
  Zjisti seznam VADu ciloveho procesu. Tyto informace ziska poslanim
  prikazu IOCTL_VAD_GET ovladaci vad.sys.

  Velikost vstupniho bufferu prikazu je zavisla na tom, zda aplikace
  bezi na 32bitovem OS ci pouze pod emulatorem WOW64 na 64bitovem OS.
}
Var
  PID : Int64;
begin
PID := ProcessId;
If GetOSType = ost32Bit Then
  Result := DriverIOCTL(0, @ProcessId, SizeOf(ProcessId), List, ListLength)
Else Result := DriverIOCTL(0, @PID, SizeOf(PID), List, ListLength);
end;

End.

