
/**
 * @file: obinit_hooks.c
 *
 * Tento soubor obsahuje kod metod, kterymi objekty TypeHook nahradi 
 * originalni metody nekterych typu objektu (Process, Thread, Desktop,
 * Section a WindowStation).
 */

#include <ntddk.h>
#include "version.h"
#include "driver.h"
#include "object_initializer.h"
#include "object.h"
#include "typehook.h"
#include "events.h"
#include "obinit_events.h"
#include "obinit_hooks.h"

// Uchovava aktualni cislo verze operacniho systemu
static ULONG VersionCode = VERSION_UNKNOWN;

// Originalni adresy metod typu objektu, jejichz metody budou prepsany
static HOOK_PROCEDURES OriginalProcessMethods;
static HOOK_PROCEDURES OriginalThreadMethods;
static HOOK_PROCEDURES OriginalSectionMethods;
static HOOK_PROCEDURES OriginalDesktopMethods;
static HOOK_PROCEDURES OriginalWindowStationMethods;

// Adresy jednotlivych objektu TypeHook
static PVOID ProcessHookObject = NULL;
static PVOID ThreadHookObject = NULL;
static PVOID SectionHookObject = NULL;
static PVOID DesktopHookObject = NULL;
static PVOID WindowStationHookObject = NULL;

// Adresy typu objektu, ktere budou monitorovany
static POBJECT_TYPE ProcessObjectType = NULL;
static POBJECT_TYPE ThreadObjectType = NULL;
static POBJECT_TYPE SectionObjectType = NULL;
static POBJECT_TYPE DesktopObjectType = NULL;
static POBJECT_TYPE WindowStationObjectType = NULL;



/** Vrati adresy originalnich metod pro dany typ objektu.
 *
 * @param Object Adresa tela objektu, metody jehoz typu volajici chce
 * zjistit.
 *
 * @return Funkce vrati adresu objektu HOOK_PROCEDURES s adresami originalnimi
 * metodami. V pripade neuspechu vrati NULL.
 */
static PHOOK_PROCEDURES _GetTypeOriginalMethods(PVOID Object)
{
  POBJECT_TYPE ObjectType = NULL;
  PHOOK_PROCEDURES Ret = NULL;
  KdPrint(("obinit_hooks.c: _GetTypeOriginalMethods(Object=0x%p)\n", Object));

  ObjectType = OBGetObjectType(Object);
  if (ObjectType != NULL) {
    if (ObjectType == ProcessObjectType)
      Ret = &OriginalProcessMethods;
	else if (ObjectType == ThreadObjectType)
      Ret = &OriginalThreadMethods;
	else if (ObjectType == SectionObjectType)
      Ret = &OriginalSectionMethods;
	else if (ObjectType == DesktopObjectType)
      Ret = &OriginalDesktopMethods;
	else if (ObjectType == WindowStationObjectType)
      Ret = &OriginalWindowStationMethods;
	else KdPrint(("obinit_hooks.c: _GetTypeOriginalMethods(): ERROR: This type object is not of our interest (0x%p).\n", ObjectType));

	OBReleaseObjectPointer(ObjectType);
  } else KdPrint(("obinit_hooks.c: _GetTypeOriginalMethods(): ERROR: Failed to get type object for 0x%p\n", Object));

  KdPrint(("obinit_hooks.c: _GetTypeOriginalMethods(-):0x%p\n", Ret));
  return Ret;
}



/** Kod metody OpenProcedure pro systemy Windows 2000, Windows XP a 
 *  Windows Server 2003.
 *
 */
static NTSTATUS OpenMethodW2KWXPW2K3(OPEN_REASON OpenReason, PEPROCESS Process, PVOID Object, ACCESS_MASK GrantedAccess, ULONG32 HandleCount)
{
  ULONG LocalAccessMode = ACCESS_MODE_UNKNOWN;
  PEVENT Event = NULL;
  PHOOK_PROCEDURES OriginalMethods = NULL;
  NTSTATUS Status = STATUS_SUCCESS;
  KdPrint(("obinit_hooks.c: OpenMethodW2KWXPW2K3(OpenReason=%u; Process=0x%p; Object=0x%p; GrantedAccess=0x%x; HandleCount=%u)",
      OpenReason, Process, Object, GrantedAccess, HandleCount));

  OriginalMethods = _GetTypeOriginalMethods(Object);
  if (OriginalMethods != NULL && OriginalMethods->OpenProcedure != NULL)
    Status = ((OPEN_METHOD_W2K)OriginalMethods->OpenProcedure)(OpenReason, Process, Object, GrantedAccess, HandleCount);

  if (MonitorProcessId() != PsGetCurrentProcessId()) {
    Event = OpenEventCreate(OpenReason, Process, Object, GrantedAccess, LocalAccessMode, Status);
    if (Event != NULL)
      EventAddToListLock(Event);
  }

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


/** Kod metody OpenProcedure pro Windows Vista a Windows 7.
 *
 */
static NTSTATUS OpenMethodVistaW7(OPEN_REASON OpenReason, KPROCESSOR_MODE AccessMode, PEPROCESS Process, PVOID Object, ACCESS_MASK *GrantedAccess, ULONG32 HandleCount)
{
  ULONG LocalAccessMode = ACCESS_MODE_UNKNOWN;
  PEVENT Event = NULL;
  PHOOK_PROCEDURES OriginalMethods = NULL;
  NTSTATUS Status = STATUS_SUCCESS;
  KdPrint(("obinit_hooks.c: OpenMethodVistaW7(OpenReason=%u; AccessMode=%u; Process=0x%p; Object=0x%p; GrantedAccess=0x%p; HandleCount=%u)",
      OpenReason, AccessMode, Process, Object, GrantedAccess, HandleCount));

  OriginalMethods = _GetTypeOriginalMethods(Object);
  if (OriginalMethods != NULL && OriginalMethods->OpenProcedure != NULL)
    Status = ((OPEN_METHOD_VISTA)OriginalMethods->OpenProcedure)(OpenReason, AccessMode, Process, Object, GrantedAccess, HandleCount);

  if (MonitorProcessId() != PsGetCurrentProcessId()) {
    LocalAccessMode = (AccessMode == KernelMode) ? ACCESS_MODE_KERNEL : ACCESS_MODE_USER;
    Event = OpenEventCreate(OpenReason, Process, Object, *GrantedAccess, LocalAccessMode, Status);
    if (Event != NULL)
      EventAddToListLock(Event);
  }

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


/** Kod metody OkayToCloseProcedure pro operacni systemy Windows 2000.
 */
static BOOLEAN OkayToCloseMethodW2K(PEPROCESS Process, PVOID Object, HANDLE Handle)
{
  ULONG LocalAccessMode = ACCESS_MODE_UNKNOWN;
  BOOLEAN Ret = TRUE;
  PEVENT Event = NULL;
  PHOOK_PROCEDURES OriginalMethods = NULL;
  KdPrint(("obinit_hooks.c: OkayToCloseMethodW2K(Process=0x%p; Object=0x%p; Handle=0x%p)\n",
    Process, Object, Handle));

  OriginalMethods = _GetTypeOriginalMethods(Object);
  if (OriginalMethods != NULL && OriginalMethods->OkayToCloseProcedure != NULL)
    Ret = ((OKAYTOCLOSE_METHOD_W2K)OriginalMethods->OkayToCloseProcedure)(Process, Object, Handle);

  if (MonitorProcessId() != PsGetCurrentProcessId()) {
    Event = OkayToCloseEventCreate(Process, Object, Handle, LocalAccessMode, Ret);
    if (Event != NULL)
      EventAddToListLock(Event);
  }

  KdPrint(("obinit_hooks.c: OkayToCloseMethodW2K(-):%u\n", Ret));
  return Ret;
}


/** Metoda OkayToCloseProcedure pro operacni systemy Windows XP, Windows Server
 *  2003, Windows Vista, Windows 7.
 */
static BOOLEAN OkayToCloseMethodWXPW2K3VistaW7(PEPROCESS Process, PVOID Object, HANDLE Handle, KPROCESSOR_MODE PreviousMode)
{
  ULONG LocalAccessMode = ACCESS_MODE_UNKNOWN;
  BOOLEAN Ret = TRUE;
  PEVENT Event = NULL;
  PHOOK_PROCEDURES OriginalMethods = NULL;
  KdPrint(("obinit_hooks.c: OkayToCloseMethodWXPW2K3VistaW7(Process=0x%p; Object=0x%p; Handle=0x%p; PreviousMode=%u)\n",
    Process, Object, Handle, PreviousMode));

  OriginalMethods = _GetTypeOriginalMethods(Object);
  if (OriginalMethods != NULL && OriginalMethods->OkayToCloseProcedure != NULL)
    Ret = ((OKAYTOCLOSE_METHOD_WXP)OriginalMethods->OkayToCloseProcedure)(Process, Object, Handle, PreviousMode);

  if (MonitorProcessId() != PsGetCurrentProcessId()) {
    LocalAccessMode = (PreviousMode == KernelMode) ? ACCESS_MODE_KERNEL : ACCESS_MODE_USER;
    Event = OkayToCloseEventCreate(Process, Object, Handle, LocalAccessMode, Ret);
    if (Event != NULL)
      EventAddToListLock(Event);
  }

  KdPrint(("obinit_hooks.c: OkayToCloseMethodWXPW2K3VistaW7(-):%u\n", Ret));
  return Ret;
}


/** Metoda CloseProcedure pro operacni systemy Windows 2000, Windows XP,
 *  Windows Server 2003, Windows Vista.
 */
static VOID CloseMethodW2KWXPW2K3Vista(PEPROCESS Process, PVOID Object, ACCESS_MASK GrantedAccess, ULONG_PTR ProcessHandleCount, ULONG_PTR SystemHandleCount)
{
  ULONG LocalAccessMode = ACCESS_MODE_UNKNOWN;
  PEVENT Event = NULL;
  PHOOK_PROCEDURES OriginalMethods = NULL;
  KdPrint(("obinit_hooks.c: CloseMethodW2KWXPW2K3Vista(Process=0x%p; Object=0x%p; GrantedAccess=0x%x; ProcessHandleCount=%u; SystemHandleCount=%u)",
      Process, Object, GrantedAccess, ProcessHandleCount, SystemHandleCount));

  OriginalMethods = _GetTypeOriginalMethods(Object);
  if (OriginalMethods != NULL && OriginalMethods->CloseProcedure != NULL)
    ((CLOSE_METHOD_W2K)OriginalMethods->CloseProcedure)(Process, Object, GrantedAccess, ProcessHandleCount, SystemHandleCount);

  if (MonitorProcessId() != PsGetCurrentProcessId()) {
    Event = CloseEventCreate(Process, Object, LocalAccessMode, GrantedAccess);
    if (Event != NULL)
      EventAddToListLock(Event);
  }

  KdPrint(("obinit_hooks.c: CloseMethodW2KWXPW2K3Vista(-)\n"));
  return;
}


/** Metoda CloseProcedure pro operacni systemy Windows 7.
 */
static VOID CloseMethodW7(PEPROCESS Process, PVOID Object, ULONG_PTR ProcessHandleCount, ULONG_PTR SystemHandleCount)
{
  ULONG LocalAccessMode = ACCESS_MODE_UNKNOWN;
  PEVENT Event = NULL;
  PHOOK_PROCEDURES OriginalMethods = NULL;
  KdPrint(("obinit_hooks.c: CloseMethodW7(Process=0x%p; Object=0x%p; ProcessHandleCount=%u; SystemHandleCount=%u)",
      Process, Object, ProcessHandleCount, SystemHandleCount));

  OriginalMethods = _GetTypeOriginalMethods(Object);
  if (OriginalMethods != NULL && OriginalMethods->CloseProcedure != NULL)
    ((CLOSE_METHOD_W7)OriginalMethods->CloseProcedure)(Process, Object, ProcessHandleCount, SystemHandleCount);

  if (MonitorProcessId() != PsGetCurrentProcessId()) {
    Event = CloseEventCreate(Process, Object, LocalAccessMode, 0);
    if (Event != NULL)
      EventAddToListLock(Event);
  }

  KdPrint(("obinit_hooks.c: CloseMethodW7(-)\n"));
  return;
}


/** Metoda DeleteProcedure pro operacni systemy Windows 2000, Windows XP,
 *  Windows 2003, Windows Vista a Windows 7.
 */
static VOID DeleteMethodW2KWXPW2K3VistaW7(PVOID Object)
{
  PEVENT Event = NULL;
  PHOOK_PROCEDURES OriginalMethods = NULL;
  KdPrint(("obinit_hooks.c: DeleteMethodW2KWXPW2K3VistaW7(Object=0x%p)\n", Object));

  OriginalMethods = _GetTypeOriginalMethods(Object);
  if (OriginalMethods != NULL && OriginalMethods->DeleteProcedure != NULL)
    ((DELETE_METHOD_W2K)OriginalMethods->DeleteProcedure)(Object);

  if (MonitorProcessId() != PsGetCurrentProcessId()) {
    Event = DeleteEventCreate(Object);
    if (Event != NULL)
      EventAddToListLock(Event);
  }

  KdPrint(("obinit_hooks.c: DeleteMethodW2KWXPW2K3VistaW7(-)\n"));
  return;
}



/** Najde adresu objektu typu pro procesy, vlakna, mapovane soubory,
 *  desktopy a WindowStation.
 *
 *  @return Funkce vraci hodnotu NTSTATUS indikujici uspech ci neuspech
 *  operace.
 */
static NTSTATUS _FindObjectTypes(VOID)
{
  UNICODE_STRING uProcessTypeName;
  UNICODE_STRING uThreadTypeName;
  UNICODE_STRING uSectionTypeName;
  UNICODE_STRING uDesktopTypeName;
  UNICODE_STRING uWindowStationTypeName;
  NTSTATUS Status = STATUS_UNSUCCESSFUL;
  KdPrint(("obinit_hooks.c: _FindObjectTypes()\n"));

  RtlInitUnicodeString(&uProcessTypeName, L"\\ObjectTypes\\Process");
  ProcessObjectType = (POBJECT_TYPE)OBObjectNameToPointer(&uProcessTypeName);
  if (ProcessObjectType != NULL) {
    RtlInitUnicodeString(&uThreadTypeName, L"\\ObjectTypes\\Thread");
    ThreadObjectType = (POBJECT_TYPE)OBObjectNameToPointer(&uThreadTypeName);
    if (ThreadObjectType != NULL) {
      RtlInitUnicodeString(&uSectionTypeName, L"\\ObjectTypes\\Section");
      SectionObjectType = (POBJECT_TYPE)OBObjectNameToPointer(&uSectionTypeName);
      if (SectionObjectType != NULL) {
        RtlInitUnicodeString(&uDesktopTypeName, L"\\ObjectTypes\\Desktop");
        DesktopObjectType = (POBJECT_TYPE)OBObjectNameToPointer(&uDesktopTypeName);
		if (DesktopObjectType != NULL) {
          RtlInitUnicodeString(&uWindowStationTypeName, L"\\ObjectTypes\\WindowStation");
          WindowStationObjectType = (POBJECT_TYPE)OBObjectNameToPointer(&uWindowStationTypeName);
          if (WindowStationObjectType == NULL) {
            OBReleaseObjectPointer(DesktopObjectType);
            OBReleaseObjectPointer(SectionObjectType);
            OBReleaseObjectPointer(ThreadObjectType);
            OBReleaseObjectPointer(ProcessObjectType);
          } else Status = STATUS_SUCCESS;
		} else {
          OBReleaseObjectPointer(SectionObjectType);
          OBReleaseObjectPointer(ThreadObjectType);
          OBReleaseObjectPointer(ProcessObjectType);
        }
	  } else {
        OBReleaseObjectPointer(ThreadObjectType);
        OBReleaseObjectPointer(ProcessObjectType);
	  }
    } else OBReleaseObjectPointer(ProcessObjectType);
  }

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


/** Zmeni metody zadaneho objektu typu.
 *
 * @param ObjectType Adresa tela objektu typu, ktery si volajici preje
 * pomoci metody DKOH "zahakovat."
 * @param HookMethods Adresy novych metod.
 * @param OriginalMethods Adresa struktury HOOK_PROCEDURES, kam funkce v pripade
 * uspechu zapise puvodni adresy prepisovanych metod objektu typu.
 * @param HookObject Adresa promenne, kam funkce v pripade uspechu zapise
 * adresu objektu TypeHook zodpovedneho za dany objekt typu.
 *
 * @return Funkce vraci hodnotu NTSTATUS indikujici uspech ci neuspech
 * operace.
 */
static NTSTATUS _HookObjectType(POBJECT_TYPE ObjectType, PHOOK_PROCEDURES HookMethods, PHOOK_PROCEDURES OriginalMethods, PVOID *HookObject)
{
  PVOID LocalHookObject = NULL;
  HOOK_PROCEDURES LocalOriginalMethods;
  NTSTATUS Status = STATUS_UNSUCCESSFUL;
  KdPrint(("obinit_hooks.c: _HookObjectType(ObjectType=0x%p; HookMethods=0x%p; OriginalMethods=0x%p; HookObject=0x%p)\n", ObjectType, HookMethods, OriginalMethods, HookObject));

  Status = TypeHookObjectCreate(ObjectType, HookMethods, &LocalHookObject);
  if (NT_SUCCESS(Status)) {
    Status = TypeHookObjectActivate(LocalHookObject, &LocalOriginalMethods);
	if (NT_SUCCESS(Status)) {
      *HookObject = LocalHookObject;
      *OriginalMethods = LocalOriginalMethods;
	} else {
      KdPrint(("obinit_hook.c: _HookObjectType(): ERROR: Failed to activate TypeHook object 0x%p\n", LocalHookObject));
	  TypeHookObjectDestroy(LocalHookObject);
	}
  } else KdPrint(("obinit_hook.c: _HookObjectType(): ERROR: Failed to create TypeHook object.\n"));

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


/** Zmeni adresy metod zadaneho objektu typu na jejich puvodni hodnoty.
 *
 *  @param HookObject Adresa objektu TypeHook zodpovedneho za dany typ
 *  objektu.
 */
static VOID _UnhookObjectType(PVOID HookObject)
{
  KdPrint(("obinit_hooks.c: _UnhookObjectType(HookObject=0x%p)\n", HookObject));

  TypeHookObjectDeactivate(HookObject);
  TypeHookObjectDestroy(HookObject);

  KdPrint(("obinit_hooks.c: _UnhookObjectType(-)\n"));
  return;
}


/** Zmeni adresy metod na objektech typu Process, Thread, Section, 
 *  Desktop a WindowStation.
 *
 *  @return Funkce vraci hodnotu NTSTATUS indikujici uspech ci neuspech
 *  operace.
 */
static NTSTATUS _HookObjectTypes(VOID)
{
  HOOK_PROCEDURES HookMethods;
  NTSTATUS Status = STATUS_UNSUCCESSFUL;
  KdPrint(("obinit_hooks.c: _HookObjectTypes()\n"));

  Status = STATUS_SUCCESS;
  HookMethods.DeleteProcedure = DeleteMethodW2KWXPW2K3VistaW7;
  if (VersionCode == VERSION_W2K || VersionCode == VERSION_WXP || VersionCode == VERSION_W2K3)
	HookMethods.OpenProcedure = OpenMethodW2KWXPW2K3;
  else if (VersionCode == VERSION_VISTA || VersionCode == VERSION_W7)
	HookMethods.OpenProcedure = OpenMethodVistaW7;
  else {
    KdPrint(("obinit_hooks.c: _HookObjectTypes(): ERROR: Failed to find proper OpenProcedure hook function.\n"));
    Status = STATUS_NOT_SUPPORTED;
  }

  if (NT_SUCCESS(Status)) {
    if (VersionCode == VERSION_W2K)
      HookMethods.OkayToCloseProcedure = OkayToCloseMethodW2K;
    else if (VersionCode == VERSION_WXP || VersionCode == VERSION_W2K3 || VersionCode == VERSION_VISTA || VersionCode == VERSION_W7)
      HookMethods.OkayToCloseProcedure = OkayToCloseMethodWXPW2K3VistaW7;
    else {
      KdPrint(("obinit_hooks.c: _HookObjectTypes(): ERROR: Failed to find proper OkayToCloseProcedure hook function.\n"));
      Status = STATUS_NOT_SUPPORTED;
    }

    if (NT_SUCCESS(Status)) {
      if (VersionCode == VERSION_W2K || VersionCode == VERSION_WXP || VersionCode == VERSION_W2K3 || VersionCode == VERSION_VISTA)
        HookMethods.CloseProcedure = CloseMethodW2KWXPW2K3Vista;
      else if (VersionCode == VERSION_W7)
        HookMethods.CloseProcedure = CloseMethodW7;
      else {
        KdPrint(("obinit_hooks.c: _HookObjectTypes(): ERROR: Failed to find proper CloseProcedure hook function.\n"));
        Status = STATUS_NOT_SUPPORTED;
      }
    }
  }

  if (NT_SUCCESS(Status)) {
    Status = _HookObjectType(ProcessObjectType, &HookMethods, &OriginalProcessMethods, &ProcessHookObject);
	if (NT_SUCCESS(Status)) {
	  Status = _HookObjectType(ThreadObjectType, &HookMethods, &OriginalThreadMethods, &ThreadHookObject);
	  if (NT_SUCCESS(Status)) {
	    Status = _HookObjectType(SectionObjectType, &HookMethods, &OriginalSectionMethods, &SectionHookObject);
		if (NT_SUCCESS(Status)) {
		  Status = _HookObjectType(DesktopObjectType, &HookMethods, &OriginalDesktopMethods, &DesktopHookObject);
		  if (NT_SUCCESS(Status)) {
		    Status = _HookObjectType(WindowStationObjectType, &HookMethods, &OriginalWindowStationMethods, &WindowStationHookObject);
            if (!NT_SUCCESS(Status)) {
              _UnhookObjectType(DesktopHookObject);
              _UnhookObjectType(SectionHookObject);
              _UnhookObjectType(ThreadHookObject);
              _UnhookObjectType(ProcessHookObject);
			}
		  } else {
            _UnhookObjectType(SectionHookObject);
            _UnhookObjectType(ThreadHookObject);
            _UnhookObjectType(ProcessHookObject);
		  }
		} else {
          _UnhookObjectType(ThreadHookObject);
		  _UnhookObjectType(ProcessHookObject);
		}
	  } else _UnhookObjectType(ProcessHookObject);
	}
  }

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


/** Provede reverzni operaci k rutine _HookObjectTypes.
 */
static VOID _UnhookObjectTypes(VOID)
{
  KdPrint(("obinit_hooks.c: _UnhookObjectTypes()\n"));
  
  _UnhookObjectType(WindowStationHookObject);
  _UnhookObjectType(DesktopHookObject);
  _UnhookObjectType(SectionHookObject);
  _UnhookObjectType(ThreadHookObject);
  _UnhookObjectType(ProcessHookObject);

  KdPrint(("obinit_hooks.c: _UnhookObjectTypes(-)\n"));
  return;
}


/** Snizi pocet referenci na vsechny monitorovane objekty typu o jednicku.
 *  Rutina provadi reverzni operaci k _FindObjectTypes.
 */
static VOID _ReleaseObjectTypes(VOID)
{
  KdPrint(("obinit_hooks.c: _ReleaseObjectTypes()\n"));
  
  OBReleaseObjectPointer(WindowStationObjectType);
  OBReleaseObjectPointer(DesktopObjectType);
  OBReleaseObjectPointer(SectionObjectType);
  OBReleaseObjectPointer(ThreadObjectType);
  OBReleaseObjectPointer(ProcessObjectType);

  KdPrint(("obinit_hooks.c: _ReleaseObjectTypes(-)\n"));
  return;
}



/** Inicializuje modul zodpovedny za prime monitorovani objektu typu
 *  Process, Thread, Section, Desktop a WindowStation.
 *
 *  Rutina zajisti pouziti metody DKOH na vsechny vyse jmenovane typy
 *  objektu.
 *
 * @return Funkce vraci hodnotu NTSTATUS indikujici uspech ci neuspech
 * operace.
 */
NTSTATUS ObinitHooksInit(VOID)
{
  NTSTATUS Status = STATUS_UNSUCCESSFUL;
  KdPrint(("obinit_hooks.c: ObinitHooksInit()\n"));

  VersionCode = GetVersionCode();
  if (VersionCode != VERSION_UNKNOWN) {
    Status = _FindObjectTypes();
	if (NT_SUCCESS(Status)) {
      Status = _HookObjectTypes();
    } else _ReleaseObjectTypes();
  } else Status = STATUS_NOT_SUPPORTED;

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


/** Provede uklid po modulu zodpovedneho za prime monitorovani objektu
 *  typu Process, Thread, Section, Desktop a WindowStation. 
 *
 *  Rutina nahradi adresy metod u prislusnych objektu typu jejich puvodnimi
 *  hodnotami.
 */
VOID ObinitHooksFinit(VOID)
{
  KdPrint(("obinit_hooks.c: ObinitHooksFinit()\n"));

  _UnhookObjectTypes();
  _ReleaseObjectTypes();

  KdPrint(("obinit_hooks.c: ObinitHooksFinit(-)\n"));
  return;
}
