
/**
 * @file: ntssiDrivers.c
 *
 * Tento soubor implementuje metodu nacteni ovladace do jadra pomoci
 * nativni funkce NtSetSystemInformation. Tato metoda funguje pouze na
 * Windows XP a starsich verzich operacniho systemu.
 */

#include <stdio.h>
#include <windows.h>
#include "..\shared\common.h"
#include "ntssiDrivers.h"



// Uchovava adresu funkce NtSetSystemInformation
static NTSETSYSTEMINFORMATION _NtSetSystemInformation = NULL;



/** Pokusi se nacist ovladac do jadra pomoci nativni funkce
 *  NtSetSystemInformation.
 *
 *  Funkce pred jmeno souboru ovladace predradi prefix \??\. Jinak
 *  by rutina NtSetSystemInformation svoji praci odmitala provest.
 *
 *  @param DriverName Jmeno souboru ovladace.
 *
 *  @return Funkce vraci TRUE v pripade uspechu a FALSE v pripade neuspechu.
 */
BOOL ntssiLoadDriver(IN PWCHAR DriverName)
{
  BOOL ret = FALSE;
  UNICODE_STRING uFullName;
  NTSTATUS status = STATUS_UNSUCCESSFUL;
  DebugMsg(("ntssiDrivers.c: ntssiLoadDriver(DriverName=%S)\n", DriverName));

  ret = _PrepareFullName(DriverName, NTSSI_NAME_PREFIX, &uFullName);
  if (ret) {
    status = _NtSetSystemInformation(SystemExtendServiceTableInformation, &uFullName, sizeof(UNICODE_STRING));
    ret = status == STATUS_SUCCESS;
    if (!ret)
      DebugMsg(("ntssiDrivers.c: ntssiLoadDriver() failed. Status 0x%x\n", status));

    _FreeFullName(&uFullName);
  }

  DebugMsg(("ntssiDrivers.c: ntssiLoadDriver(-):%u\n", ret));
  return ret;
}


/** Inicializuje modul, ktery umoznuje nacitat ovladace do jadra pomoci
 *  nativni funkce NtSetSytemInformation.
 *
 *  Rutina najde adresu funkce NtSetSystemInformation v knihovne ntdll.dll.
 *  Rutina se take pokusi povolit opravneni pro nacitani ovladacu.
 *
 *  @return Funkce vraci TRUE v pripade uspechu a FALSE v pripade neuspechu.
 */
BOOL ntssiInit(VOID)
{
  HMODULE hntdll = NULL;
  BOOL ret = FALSE;
  DebugMsg(("ntssiDrivers.c: ntssiInit()\n"));
  
  ret = EnablePrivilege(LOAD_DRIVER_PRIVILEGE);
  if (ret) {
    hntdll = GetModuleHandleW(L"ntdll.dll");
    ret = hntdll != NULL;
    if (ret) {
      _NtSetSystemInformation = (NTSETSYSTEMINFORMATION)GetProcAddress(hntdll, "NtSetSystemInformation");
	  ret = _NtSetSystemInformation != NULL;
	  if (!ret)
        DebugMsg(("ntssiDrivers.c: ntssiInit(): failed to find NtSetSystemInformation export. Error %u\n", GetLastError()));
    } else DebugMsg(("ntssiDrivers.c: ntssiInit(): failed to find ntdll.dll error %u\n", GetLastError()));
  } else DebugMsg(("ntssiDrivers.c: ntssiInit(): failed to enable %S privilege\n", LOAD_DRIVER_PRIVILEGE));

  DebugMsg(("ntssiDrivers.c: ntssiInit(-):%u\n", ret));
  return ret;
}


/** Provede uklid po modulu podpory nacitani ovladacu do jadra pomoci
 *  rutiny NtSetSystemInformation.
 */
VOID ntssiFinit(VOID)
{
  DebugMsg(("ntssiDrivers.c: ntssiFinit()\n"));

  DebugMsg(("ntssiDrivers.c: ntssiFinit()\n"));
  return;
}
