
#ifndef __VAD_DEF_H_
#define __VAD_DEF_H_

/** 
 * @file vad-def.h
 *
 * Tento soubor obsahuje definice platne pro VADy na vsech verzich Windows. Bud
 * se jedna o definice struktur, ktere pouziva ovladac vad.sys pro ukladani informaci
 * o jednotlivych deskriptorech, nebo o struktury, ktere se od sveho vzniku nemenily
 * a ktere se vyplati pouzivat i obecne.
 */


// Delka struktury deskriptoru
typedef enum _VAD_STRUCTURE_TYPE {
  VadStructureUnknown = 0,     // Neznama. Toto znamena chybu
  VadStructureShort = 1,       // Kratky deskriptor
  VadStructureNormal = 2,      // Stredne dlouhy deskriptor
  VadStructureLong = 3,        // Dlouhy deskriptor
  VadStructureMapped = 4       // Tetno typ je odvozen z tagu "Vadm", ktery byl
                               // pozorovan na Windows Vista/7. Jeho existence
							   // nepotvrzena.
} VAD_STRUCTURE_TYPE;


// Typ deskriptoru (u prvni skupiny priznaku pro 2K3/Vista/7 se jedna o polozku
// VadType.
typedef enum _MI_VAD_TYPE {
  VadNone,                        // Asi obecny deskriptor. Nicim specialni.
  VadDevicePhysicalMemory,        // Pravdepodobne popisuje pamet, mapujici se primo
                                  // na fyzicke adresy, tudiz i nestrankovanou
  VadImageMap,                    // Pamet vyuzita k mapovani PE souboru
  VadAwe,                         // Asi pamet pro Address Windowing Extension
  VadWriteWatch,         
  VadLargePages,                  // Asi privatni pamet za pouziti vekych stranek
  VadRotatePhysical,           
  VadLargePageSection             // Mapovany soubor za pouziti velkych stranek
} MI_VAD_TYPE, *PMI_VAD_TYPE;

// Do teto struktury si ovladac vad.sys uklada informace dulezite pro prochazeni
// stromove struktury deksriptoru. Jadro tuto strukturu pouziva pro ukladani
// techto informaci od Windows Server 2003.
typedef struct _MMADDRESS_NODE {
  union {
	// 1, 0, -1. Dulezite pro vyvazovani AVL stromu
    LONG_PTR Balance : 2;
	// Odkaz na rodice
    struct _MMADDRESS_NODE *Parent;
  } u1;

  // Odkaz na leveho syna
  struct _MMADDRESS_NODE *LeftChild;
  // Odkaz na praveho syna
  struct _MMADDRESS_NODE *RightChild;
  // CIslo virtualni stranky, kterou region popisovany deskriptorem zacina
  ULONG_PTR StartingVPN;
  // Cislo virtualni stranky, kterou region popisovany deskriptorem konci
  ULONG_PTR EdningVPN;
} MMADDRESS_NODE, *PMMADDRESS_NODE;


#define COMMIT_SIZE                    ((sizeof(ULONG_PTR) * 8) - 13)


// Vlozeni definic specifickych pro urcite verze Windows
#include "vad-def-wxp.h"
#include "vad-def-w2k3.h"
#include "vad-def-vista.h"
#include "vad-def-w7.h"

// Obecna struktura pro ulozeni prvni skupiny priznaku.
// Odpovida strukture pouzivane systemem od Windows Server 2003
typedef struct _MMVAD_FLAGS {
  // Pravdepodobne pocet stranek, ktere bude treba odecist od kvoty procesu pri
  // alokaci daneho bloku. Ale vyznam muze byt v nekterych prikladech i odlisny,
  // byly pozorovany podivne hodnoty.
  ULONG_PTR CommitCharge : COMMIT_SIZE;
  // Pravdepodobne indikuje, zda se opravneni stranek popisovanych deskriptorem
  // od jeho vzniku zmenilo, ci nikoliv.
  ULONG_PTR NoChange : 1;
  // Typ deskriptoru. Na windows 2000 a Windows XP toto pole neni pritomno a 
  // nahrazuje jej skupina nekolika specialnich bitu. Ovladac vad.sys z jejich
  // hodnot dopocita hodnotu tohoto pole.
  ULONG_PTR VadType : 3;
  // 1 => pamet je alokovana, 0 => pamet je rezervovana
  ULONG_PTR MemCommit: 1;
  // Opravneni. Neodpovida maskam uzivanym pri alokaci virtualni pameti
  ULONG_PTR Protection : 5;
  ULONG_PTR Spare : 2;
  // 1 -> privatni pamet procesu, 0 -> pametove mapovany soubor
  ULONG_PTR PrivateMemory : 1; // used to tell VAD from VAD_SHORT
} MMVAD_FLAGS;

// Obecna struktura, do ktere si ovladac vad.sys uklada hodnoty treti skupiny
// priznaku. Vyznam techto priznaku je mi v podstate neznamy.
typedef struct _MMVAD_FLAGS3 {
  ULONG_PTR PreferredNode : 6;
  ULONG_PTR Teb : 1;
  ULONG_PTR Spare : 1;
  ULONG_PTR SequentialAccess : 1;
  ULONG_PTR LastSequentialTrim : 15;
  ULONG_PTR Spare2 : 8;
} MMVAD_FLAGS3;

// Obecna struktura pro uchovavani druhe skupiny priznaku. Tuto strukturu pouziva
// system od verze Windows Server 2003.
typedef struct _MMVAD_FLAGS2 {
  // Offset v souboru na disku, na kterem zacina mapovani (v 64K jednotkach)
  unsigned FileOffset : 24;
  // 1 -> pametove mapovany soubor vytvoren se SEC_NO_CHANGE priznakem
  unsigned SecNoChange : 1;     
  // Jeden region popisovany deskiptorem je zabezpecen pres MmSecureVirtualMemory
  unsigned OneSecured : 1;     
  // Nekolik regionu popisovanych deskriptorem je zabezpeceno pres MmSecureVirtualMemory
  unsigned MultipleSecured : 1;
  // Pamet je pouze pro cteni (ale nevidel jsem prilis casto pouzito)
  unsigned ReadOnly : 1;     
  // 1 -> jedna se o "dlouhy" VAD, 0 -> normalni VAD
  unsigned LongVad : 1;   
  // Pravdepodobne urcuje, zda pametove mapovany soubor muze zvetsovat velikost
  // prislusneho souboru na disku
  unsigned ExtendableFile : 1;
  // Urcuje, zda se da pametove mapovany soubor dedit
  unsigned Inherit : 1;          
  // 1 -> Copy On Write optimalizace
  unsigned CopyOnWrite : 1;
} MMVAD_FLAGS2;


// Struktura se vyskytuje od Windows Server 2003 pod polozkou VadRoot a PhysicalVadRoot
// ve strukturach EPROCESS. Odkazuje na koren AVL stromu deskriptoru.
typedef struct _MM_AVL_TABLE {
  MMADDRESS_NODE RootNode;
} MM_AVL_TABLE, *PMM_AVL_TABLE;

// Popis vyznamu jednotlivych metod naleznete v souboru vad-def.c v komentarcih
// u jejich implementace.

VOID VDFillAddressNode(PVOID Vad, PMMADDRESS_NODE Node);
MMVAD_FLAGS VDGetVadFlags(PVOID Vad);
MMVAD_FLAGS2 VDGetVadFlags2(PVOID Vad);
MMVAD_FLAGS3 VDGetVadFlags3(PVOID Vad);
MI_VAD_TYPE VDGetVadType(PVOID Vad);
VAD_STRUCTURE_TYPE VDGetVadStructureType(PVOID Vad);

NTSTATUS VDInit(VOID);
VOID VDFinit(VOID);

#endif
