1
0
mirror of https://github.com/alliedmodders/metamod-source.git synced 2024-12-04 16:24:16 +01:00
HLMetaModOfficial/sourcehook/sourcehook_impl_cvfnptr.h
Pavol Marko b64eb781d8 Removed "trust the prototype" model which could lead to problems. Instead, every CVfnPtr now has a list of hook managers.
-> Removed CHookManagerContainer
Also removed listcat (unnecessary since "V2" interface)

--HG--
extra : convert_revision : svn%3Ac2935e3e-5518-0410-8daf-afa5dab7d4e3/trunk%40510
2007-10-14 11:59:13 +00:00

118 lines
2.7 KiB
C++

/* ======== SourceHook ========
* Copyright (C) 2004-2007 Metamod:Source Development Team
* No warranties of any kind
*
* License: zlib/libpng
*
* Author(s): Pavol "PM OnoTo" Marko
* ============================
*/
#ifndef __SOURCEHOOK_IMPL_CVFNPTR_H__
#define __SOURCEHOOK_IMPL_CVFNPTR_H__
#include "sh_list.h"
#include "sh_memory.h"
namespace SourceHook
{
namespace Impl
{
class CVfnPtr
{
// *** Data ***
void *m_Ptr;
void *m_OrigEntry;
List<CHookManager*> m_HookMans;
List<CIface> m_IfaceList;
public:
// *** Descriptor ***
typedef void* Descriptor;
// *** Interface ***
inline CVfnPtr(void *ptr);
inline ~CVfnPtr();
inline bool operator==(const Descriptor &other);
inline void *GetPtr() const;
inline void *GetOrigEntry() const;
inline List<CIface> &GetIfaceList();
inline const List<CIface> &GetIfaceList() const;
inline CIface *FindIface(void *iface);
CIface &GetIface(void *iface);
bool Patch(void *newValue);
inline bool Revert();
void AddHookMan(CHookManager *pHookMan);
// If this returns false, it means that there is no hook manager left
// to use and that this vfnptr should be removed.
bool HookManRemoved(CHookManager *pHookMan);
};
// *** Implementation ***
inline CVfnPtr::CVfnPtr(void *ptr)
: m_Ptr(ptr), m_OrigEntry(*reinterpret_cast<void**>(m_Ptr))
{
}
inline CVfnPtr::~CVfnPtr()
{
if (!m_HookMans.empty())
m_HookMans.front()->DecrRef(this);
}
inline bool CVfnPtr::operator==(const Descriptor &other)
{
return m_Ptr == other;
}
inline void *CVfnPtr::GetPtr() const
{
return m_Ptr;
}
inline void *CVfnPtr::GetOrigEntry() const
{
return m_OrigEntry;
}
inline List<CIface> &CVfnPtr::GetIfaceList()
{
return m_IfaceList;
}
inline const List<CIface> &CVfnPtr::GetIfaceList() const
{
return m_IfaceList;
}
inline bool CVfnPtr::Revert()
{
// Only patch the vfnptr back if the module is still in memory
// If it's not, do not remove stuff like we did before
// First off we did it wrong (shutdown the whole hookman, uh..) and secondly applications may be
// confused by RemoveHook returning false then (yeah, I know, I made this one up, no one checks for RemoveHook error)
if (ModuleInMemory(reinterpret_cast<char*>(m_Ptr), SH_PTRSIZE))
{
return Patch(m_OrigEntry);
}
else
{
return true;
}
}
inline CIface *CVfnPtr::FindIface(void *iface)
{
List<CIface>::iterator iter = m_IfaceList.find(iface);
if (iter == m_IfaceList.end())
return NULL;
else
return &(*iter);
}
}
}
#endif