
/**
 * @file: version.c
 *
 * Tento modul (soubor) implementuje rutiny umoznujici urceni a rozliseni
 * jednotlivych verzi operacniho systemu. Dovoluje rozlisit i mezi 
 * Checked a Free buildem.
 */

#include <ntddk.h>
#include "version.h"



// Majoritni cislo verze OS
static ULONG MajorVersion;
// Minoritni cislo verze OS
static ULONG MinorVersion;
// Cislo aktualniho sestaveni
static ULONG Build;
// TRUE - Checked Build, FALSE = Free Build
static BOOLEAN Checked;



/** Zjisti, zda je jadro aktualniho systemu prelozeno v rezimu Free Build
 *  nebo Checked Build.
 *
 * @return V pripade, ze je jadro systemu prelozeno v rezimu Checked Build,
 * funkce vraci TRUE. Jedna-li se o Free Build, rutina vrati FALSE.
 *
 */
BOOLEAN CheckedBuild(VOID)
{
  return Checked;
}



/** Zjisti, zda se ovladac prave nachazi na Windows XP. Funkce nerozlisuje
 *  32bit a 64bit verzi.
 *
 * @return Rutina vrati TRUE, pokud je verze systemu rovna 5.1.2600 (Windows XP 32bit)
 * nebo 5.2.3790 (Windows XP 64bit). V opacnem pripade predpoklada, ze
 * cilovy system neni XP a vraci FALSE.
 */
BOOLEAN WindowsXP(VOID)
{
  return (MajorVersion == 5 && MinorVersion == 1 && Build == 2600);
}


/** Rutina zjisti, zda aktualni system neni Windows 2000.
 *
 * @return Funkce vraci TRUE, pokud je verze systemu 5.0.x. 5.0 odpovida
 * Windows 2000. V opacnem pripade vraci FALSE.
 */
BOOLEAN Windows2000(VOID)
{
  return (MajorVersion == 5 && MinorVersion == 0);
}


/** Rutina zjisti, zda ovladac nebezi na Windows Server 2003.
 *
 * @return Windows Server 2003 ma cislo verze 5.2 a cislo sestaveni mensi
 * nez Windows XP x64 (3790). V takovem pripade rutina vrati TRUE. Jinak
 * vraci FALSE.
 */
BOOLEAN WindowsServer2003(VOID)
{
  return (MajorVersion == 5 && MinorVersion == 2 && Build <= 3790);
}


/** Funkce zjisti, zda aktualni verze systemu neodpovida Windows Vista.
 *  Nerozlisuje 32bitovou verzi a 64bitovou verzi OS.
 *
 * @return Funkce vrati TRUE, pokud verze systemu odpovida Windows Vista
 * (6.0). Jinak vraci FALSE.
 */
BOOLEAN WindowsVista(VOID)
{
  return (MajorVersion == 6 && MinorVersion == 0);
}


/** Rutina zjisti, zda aktualni verze OS neodpovida Windows 7. Rutina
 *  nerozlisuje mezi 32bit a 64bit verzi operacniho systemu.
 *
 * @return Rutina vrati TRUE, pokud je verze systemu 6.1.7600 nebo
 * 6.1.7601 (Windows 7 SP1). V opacnem pripade vraci FALSE.
 */
BOOLEAN Windows7(VOID)
{
  return (MajorVersion == 6 && MinorVersion == 1 && (Build == 7600 || Build == 7601));
}


/** Vraci hodnotu VERSION_XXX odpovidajici verzi operacniho systemu, na
 *  ktere volajici prave bezi.
 *
 *  @return
 *    @value VERSION_UNKNOWN Neznama verze operacniho systemu.
 *    @value VERSION_W2K Windows 2000
 *    @value VERSION_WXP Windows XP
 *    @value VERSION_W2K3 Windows Server 2003
 *    @value VERSION_VISTA Windows Vista
 *    @value VERSION_W7 Windows 7
 */
ULONG GetVersionCode(VOID)
{
  ULONG ret = VERSION_UNKNOWN;
  KdPrint(("version.c: GetVersionCode()\n"));

  if (Windows2000())
    ret = VERSION_W2K;
  else if (WindowsXP())
    ret = VERSION_WXP;
  else if (WindowsServer2003())
    ret = VERSION_W2K3;
  else if (WindowsVista())
    ret = VERSION_VISTA;
  else if (Windows7())
    ret = VERSION_W7;

  KdPrint(("version.c: GetVersionCode(-):%u\n", ret));
  return ret;
}



/** Tato rutina inicializuje modul slouzici pro zjistovani aktualni
 *  verze operacniho systemu.
 *
 *  Tento modul k tomuto ucelu interne pouziva funkci PsGetVersion().
 * 
 * @return Funkce vraci hodnotu NTSTATUS indikujici uspech operace.
 */
NTSTATUS VersionInit(VOID)
{
  NTSTATUS Status = STATUS_UNSUCCESSFUL;
  KdPrint(("version.c: VersionInit()\n"));

  Checked = PsGetVersion(&MajorVersion, &MinorVersion, &Build, NULL);
  Status = STATUS_SUCCESS;
  if (GetVersionCode() == VERSION_UNKNOWN)
    Status = STATUS_NOT_SUPPORTED;

  KdPrint(("version.c: VersionInit(-):0x%x\n", Status));
  return Status;
}


/** tato rutina je parova k VersionInit(). Provadi tedy uklid po modulu
 *  na zjistovani aktualni verze OS.
 *
 *  Protoze tento modul nijak nezasahuje do datovych struktur jadra, tato
 *  rutina ve skutecnosti neprovadi nic.
 */
VOID VersionFinit(VOID)
{
  KdPrint(("version.c: VersionFinit()\n"));

  KdPrint(("version.c: VersionFInit(-)\n"));
  return;
}
