
/**
 * @file: hello.c
 *
 * Tento soubor obsahuje zdrojove kody ovladace hello.sys. Tento ovladac neprovadi
 * zadne operace v jadre systemu, slouzi pouze jako demostrace toho, jak architektura
 * kazdeho ovladace vypada. Dovoluje dynamicke nacitani a uvolnovani do/z pameti jadra
 * a vypisuje hlasky debuggeru jadra pomoci funkce DbgPrint.
 */

#include <ntddk.h>



/** Tato rutina je systemem volana behem uvolnovani ovladace z jadra.
 *
 * Ukolem teto rutiny je uklidit vsechno, co voladac behem sve cinnosti vytvoril, aby
 * po jeho uvolneni v jadre nezustalo nic navic. Protoze ovladac hello.sys krom hlasek
 * debuggeru nedela nic, rutina nedela nic podstatneho, pouze posle nekolik zprav
 * debuggeru.
 *
 * @param DriverObject Adresa struktury DRIVER_OBJECT, ktera reprezentuje ovladac
 * v jadre.
 */
VOID DriverUnload(PDRIVER_OBJECT DriverObject)
{
  DbgPrint("hello.c: DriverUnload(DriverObject=0x%p)\n", DriverObject);

  DbgPrint("Good Bye\n");

  DbgPrint("hello.c: DriverUnload(-)\n");
  return;
}


/** Toto je rutina volana tesne po namapovani ovladace do pameti.
 *
 * Jejim ukolem je inicializovat ovaldac tak, aby mohl normalne provadet svoji cinnost.
 * Obvykla prace teto rutiny spociva ve vytvoreni objektu zarizeni, skrz ktere s ovladacem
 * mohou komunikovat bezne aplikace.
 *
 * @param DriverObject Adresa struktury DRIVER_OBJECT, ktera reprezentuje ovladac
 * v jadra.
 * @param RegistryPath Nazev klice sluzby, ktera ovladac reprezentuje v SCM.
 *
 * @return Rutina vraci hodnotu NTSTATUS. Pokud nevrati STATUS_SUCCESS, ovladac je
 * ihned odmapovan z pameti jadra.
 */
NTSTATUS DriverEntry (PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)
{
  NTSTATUS Status = STATUS_UNSUCCESSFUL;
  DbgPrint ("hello.c: DriverEntry(DriverObject=0x%p; RegistryPath=\"%S\")\n", DriverObject, RegistryPath->Buffer);

  DbgPrint ("HELLO WORLD!\n");
  if (DriverObject != NULL)
    // Nastavi rutinu, kterou system bude volat v pripade uvolnovani ovladace z jadra.
    // Pokud by tato rutina nebyla nastavena, ovladac nelze dynamicky uvolnit z pameti.
    DriverObject->DriverUnload = DriverUnload;
  
  Status = STATUS_SUCCESS;

  DbgPrint ("hello.c: DriverEntry(-):0x%x\n", Status);
  return Status;
}
