1
0
mirror of https://github.com/alliedmodders/metamod-source.git synced 2025-02-20 13:54:14 +01:00

Added code for proper handling of thisptr adjustors, added new test, version info, more options for GetFuncInfo

--HG--
extra : convert_revision : svn%3Ac2935e3e-5518-0410-8daf-afa5dab7d4e3/trunk%4059
This commit is contained in:
Pavol Marko 2005-05-05 10:40:47 +00:00
parent 18a4184ede
commit 4dc4ed7a2b
12 changed files with 1463 additions and 484 deletions

View File

@ -4,6 +4,7 @@
shworker iter %1 sourcehook.hxx sourcehook.h
shworker iter %1 sh_memfuncinfo.hxx sh_memfuncinfo.h
shworker hopter %1 FastDelegate.hxx FastDelegate.h
copy *.h ..

View File

@ -0,0 +1,311 @@
/* ======== SourceHook ========
* Copyright (C) 2004-2005 Metamod:Source Development Team
* No warranties of any kind
*
* License: zlib/libpng
*
* Author(s): Pavol "PM OnoTo" Marko
* ============================
*/
/**
* @brief This file provides a way for getting information about a member function.
* @file sh_memfuncinfo.h
*/
#ifndef __SHINT_MEMFUNC_INFO_H__
#define __SHINT_MEMFUNC_INFO_H__
namespace SourceHook
{
// Don Clugston:
// implicit_cast< >
// I believe this was originally going to be in the C++ standard but
// was left out by accident. It's even milder than static_cast.
// I use it instead of static_cast<> to emphasize that I'm not doing
// anything nasty.
// Usage is identical to static_cast<>
template <class OutputClass, class InputClass>
inline OutputClass implicit_cast(InputClass input){
return input;
}
struct MemFuncInfo
{
bool isVirtual; // Is the function virtual?
int thisptroffs; // The this pointer the function expects to be called with
// If -1, you need to call the GetFuncInfo_GetThisPtr function
int vtblindex; // The function's index in the vtable (0-based, 1=second entry, 2=third entry, ...)
int vtbloffs; // The vtable pointer
};
// Ideas by Don Clugston.
// Check out his excellent paper: http://www.codeproject.com/cpp/FastDelegate.asp
template<int N> struct MFI_Impl
{
template<class MFP> static inline void GetFuncInfo(MFP *mfp, MemFuncInfo &out)
{
static char weird_memfunc_pointer_exclamation_mark_arrow_error[N-1000];
}
};
# if SH_COMP == SH_COMP_GCC
template<> struct MFI_Impl<8> // All of these have size==8
{
struct GCC_MemFunPtr
{
union
{
void *funcadr; // always even
int vtable_index_plus1; // = vindex+1, always odd
};
int delta;
};
template<class MFP> static inline void GetFuncInfo(MFP mfp, MemFuncInfo &out)
{
GCC_MemFunPtr *mfp_detail = (GCC_MemFunPtr*)&mfp;
out.thisptroffs = mfp_detail->delta;
if (mfp_detail->vtable_index_plus1 & 1)
{
out.vtblindex = (mfp_detail->vtable_index_plus1 - 1) / 4;
out.vtbloffs = 0;
out.isVirtual = true;
}
else
out.isVirtual = false;
}
};
# elif SH_COMP == SH_COMP_MSVC
namespace
{
int MFI_GetVtblOffset(void *mfp)
{
unsigned char *addr = (unsigned char*)mfp;
if (*addr == 0xE9) // Jmp
{
// May or may not be!
// Check where it'd jump
addr += 5 /*size of the instruction*/ + *(unsigned long*)(addr + 1);
}
// Check whether it's a virtual function call
// They look like this:
// 004125A0 8B 01 mov eax,dword ptr [ecx]
// 004125A2 FF 60 04 jmp dword ptr [eax+4]
// ==OR==
// 00411B80 8B 01 mov eax,dword ptr [ecx]
// 00411B82 FF A0 18 03 00 00 jmp dword ptr [eax+318h]
// However, for vararg functions, they look like this:
// 0048F0B0 8B 44 24 04 mov eax,dword ptr [esp+4]
// 0048F0B4 8B 00 mov eax,dword ptr [eax]
// 0048F0B6 FF 60 08 jmp dword ptr [eax+8]
// ==OR==
// 0048F0B0 8B 44 24 04 mov eax,dword ptr [esp+4]
// 0048F0B4 8B 00 mov eax,dword ptr [eax]
// 00411B82 FF A0 18 03 00 00 jmp dword ptr [eax+318h]
// With varargs, the this pointer is passed as if it was the first argument
bool ok = false;
if (addr[0] == 0x8B && addr[1] == 0x44 && addr[2] == 0x24 && addr[3] == 0x04 &&
addr[4] == 0x8B && addr[5] == 0x00)
{
addr += 6;
ok = true;
}
else if (addr[0] == 0x8B && addr[1] == 0x01)
{
addr += 2;
ok = true;
}
if (!ok)
return -1;
if (*addr++ == 0xFF)
{
if (*addr == 0x60)
{
return *++addr / 4;
}
else if (*addr == 0xA0)
{
return *((unsigned int*)++addr) / 4;
}
else if (*addr == 0x20)
return 0;
else
return -1;
}
return -1;
}
}
template<> struct MFI_Impl<4> // simple ones
{
template<class MFP> static inline void GetFuncInfo(MFP mfp, MemFuncInfo &out)
{
out.vtblindex = MFI_GetVtblOffset(*(void**)&mfp);
out.isVirtual = out.vtblindex >= 0 ? true : false;
out.thisptroffs = 0;
out.vtbloffs = 0;
}
};
template<> struct MFI_Impl<8> // more complicated ones!
{
struct MSVC_MemFunPtr2
{
void *funcadr;
int delta;
};
template<class MFP> static inline void GetFuncInfo(MFP mfp, MemFuncInfo &out)
{
out.vtblindex = MFI_GetVtblOffset(*(void**)&mfp);
out.isVirtual = out.vtblindex >= 0 ? true : false;
out.thisptroffs = reinterpret_cast<MSVC_MemFunPtr2*>(&mfp)->delta;
out.vtbloffs = 0;
}
};
// By Don Clugston, adapted
template<> struct MFI_Impl<12> // WOW IT"S GETTING BIGGER OMGOMOGMG
{
class __single_inheritance GenericClass;
class GenericClass {};
struct MicrosoftVirtualMFP {
void (GenericClass::*codeptr)(); // points to the actual member function
int delta; // #bytes to be added to the 'this' pointer
int vtable_index; // or 0 if no virtual inheritance
};
struct GenericVirtualClass : virtual public GenericClass
{
typedef GenericVirtualClass * (GenericVirtualClass::*ProbePtrType)();
GenericVirtualClass * GetThis() { return this; }
};
template<class MFP> static inline void GetFuncInfo(MFP mfp, MemFuncInfo &out)
{
out.vtblindex = MFI_GetVtblOffset(*(void**)&mfp);
out.isVirtual = out.vtblindex >= 0 ? true : false;
// This pointer
/*
union {
MFP func;
GenericClass* (T::*ProbeFunc)();
MicrosoftVirtualMFP s;
} u;
u.func = mfp;
union {
GenericVirtualClass::ProbePtrType virtfunc;
MicrosoftVirtualMFP s;
} u2;
// Check that the horrible_cast<>s will work
typedef int ERROR_CantUsehorrible_cast[sizeof(mfp)==sizeof(u.s)
&& sizeof(mfp)==sizeof(u.ProbeFunc)
&& sizeof(u2.virtfunc)==sizeof(u2.s) ? 1 : -1];
// Unfortunately, taking the address of a MF prevents it from being inlined, so
// this next line can't be completely optimised away by the compiler.
u2.virtfunc = &GenericVirtualClass::GetThis;
u.s.codeptr = u2.s.codeptr;
out.thisptroffs = (reinterpret_cast<T*>(NULL)->*u.ProbeFunc)();
*/
out.thisptroffs = -1;
out.vtbloffs = 0;
}
};
// Don: Nasty hack for Microsoft and Intel (IA32 and Itanium)
// unknown_inheritance classes go here
// This is probably the ugliest bit of code I've ever written. Look at the casts!
// There is a compiler bug in MSVC6 which prevents it from using this code.
template<> struct MFI_Impl<16> // THE BIGGEST ONE!!!1GABEN
{
template<class MFP> static inline void GetFuncInfo(MFP mfp, MemFuncInfo &out)
{
out.vtblindex = MFI_GetVtblOffset(*(void**)&mfp);
out.isVirtual = out.vtblindex >= 0 ? true : false;
// The member function pointer is 16 bytes long. We can't use a normal cast, but
// we can use a union to do the conversion.
union {
MFP func;
// In VC++ and ICL, an unknown_inheritance member pointer
// is internally defined as:
struct {
void *m_funcaddress; // points to the actual member function
int delta; // #bytes to be added to the 'this' pointer
int vtordisp; // #bytes to add to 'this' to find the vtable
int vtable_index; // or 0 if no virtual inheritance
} s;
} u;
// Check that the horrible_cast will work
typedef int ERROR_CantUsehorrible_cast[sizeof(u.func)==sizeof(u.s)? 1 : -1];
u.func = mfp;
int virtual_delta = 0;
if (u.s.vtable_index) { // Virtual inheritance is used
/*
// First, get to the vtable.
// It is 'vtordisp' bytes from the start of the class.
int * vtable = *reinterpret_cast<int **>(
reinterpret_cast<char *>(thisptr) + u.s.vtordisp );
// 'vtable_index' tells us where in the table we should be looking.
virtual_delta = u.s.vtordisp + *reinterpret_cast<const int *>(
reinterpret_cast<const char *>(vtable) + u.s.vtable_index);
// The int at 'virtual_delta' gives us the amount to add to 'this'.
// Finally we can add the three components together. Phew!
out.thisptr = reinterpret_cast<void *>(
reinterpret_cast<char *>(thisptr) + u.s.delta + virtual_delta);
*/
out.vtbloffs = u.s.vtordisp;
out.thisptroffs = -1;
}
else
{
out.vtbloffs = out.vtblindex < 0 ? 0 : u.s.delta;
out.thisptroffs = u.s.delta;
}
};
};
# else
# error Unsupported compiler
# endif
// This version does not take a this pointer
// Useful for hookdecls, as they ensure that mfp is correct through a static_cast
template<class X> inline void GetFuncInfo(X mfp, MemFuncInfo &out)
{
MFI_Impl<sizeof(mfp)>::GetFuncInfo(mfp, out);
}
// Versions which do take a this
@VARARGS@
template<class X, class Y, class RetType@, @@class Param%%|, @>
inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(@Param%%|, @), MemFuncInfo &out)
{
RetType(Y::*mfp2)(@Param%%|, @) = mfp;
MFI_Impl<sizeof(mfp2)>::GetFuncInfo(mfp2, out);
}
template<class X, class Y, class RetType@, @@class Param%%|, @>
inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(@Param%%|, @) const, MemFuncInfo &out)
{
RetType(Y::*mfp2)(@Param%%|, @) const = mfp;
MFI_Impl<sizeof(mfp2)>::GetFuncInfo(mfp2, out);
}
@ENDARGS@
}
#endif

View File

@ -1,6 +1,10 @@
/* ======== SourceHook ========
* By PM
* Copyright (C) 2004-2005 Metamod:Source Development Team
* No warranties of any kind
*
* License: zlib/libpng
*
* Author(s): Pavol "PM OnoTo" Marko
* ============================
*/
@ -12,6 +16,9 @@
#ifndef __SOURCEHOOK_H__
#define __SOURCEHOOK_H__
#define SH_IFACE_VERSION 1
#define SH_IMPL_VERSION 1
#ifndef SH_GLOB_SHPTR
#define SH_GLOB_SHPTR g_SHPtr
#endif
@ -88,6 +95,15 @@ namespace SourceHook
{
};
/**
* @brief Implicit cast.
*/
template <class In, class Out>
inline Out implicit_cast(In input)
{
return input;
}
/**
* @brief A plugin typedef
*
@ -164,6 +180,7 @@ namespace SourceHook
ISHDelegate *handler; //!< Pointer to the handler
bool paused; //!< If true, the hook should not be executed
Plugin plug; //!< The owner plugin
int thisptr_offs; //!< This pointer offset
};
void *ptr; //!< Pointer to the interface instance
std::list<Hook> hooks_pre; //!< A list of pre-hooks
@ -205,8 +222,9 @@ namespace SourceHook
template<class B> struct CallClass
{
B *ptr;
OrigVTables vt;
B *ptr; //!< Pointer to the actual object
size_t objsize; //!< Size of the instance
OrigVTables vt; //!< Info about vtables & functions
};
typedef CallClass<void> GenericCallClass;
@ -217,6 +235,16 @@ namespace SourceHook
class ISourceHook
{
public:
/**
* @brief Return interface version
*/
virtual int GetIfaceVersion() = 0;
/**
* @brief Return implementation version
*/
virtual int GetImplVersion() = 0;
/**
* @brief Add a hook.
*
@ -255,9 +283,9 @@ namespace SourceHook
* @brief Return a pointer to a callclass. Generate a new one if required.
*
* @param iface The interface pointer
* @param size Size of the class
* @param size Size of the class instance
*/
virtual GenericCallClass *GetCallClass(void *iface) = 0;
virtual GenericCallClass *GetCallClass(void *iface, size_t size) = 0;
/**
* @brief Release a callclass
@ -274,12 +302,12 @@ namespace SourceHook
virtual void *GetIfacePtr() = 0; //!< Gets the interface pointer
//////////////////////////////////////////////////////////////////////////
// For hook managers
virtual META_RES &GetCurResRef() = 0; //!< Gets the pointer to the current meta result
virtual META_RES &GetPrevResRef() = 0; //!< Gets the pointer to the previous meta result
virtual META_RES &GetStatusRef() = 0; //!< Gets the pointer to the status variable
virtual META_RES &GetCurResRef() = 0; //!< Gets the reference to the current meta result
virtual META_RES &GetPrevResRef() = 0; //!< Gets the reference to the previous meta result
virtual META_RES &GetStatusRef() = 0; //!< Gets the reference to the status variable
virtual void* &GetIfacePtrRef() = 0; //!< Gets the reference to the interface this pointer
virtual void SetOrigRet(const void *ptr) = 0; //!< Sets the original return pointer
virtual void SetOverrideRet(const void *ptr) = 0; //!< Sets the override result pointer
virtual void SetIfacePtr(void *ptr) = 0; //!< Sets the interface this pointer
};
}
@ -306,7 +334,7 @@ template<class ifacetype>
inline SourceHook::CallClass<ifacetype> *SH_GET_CALLCLASS_R(SourceHook::ISourceHook *shptr, ifacetype *ptr)
{
return reinterpret_cast<SourceHook::CallClass<ifacetype>*>(
shptr->GetCallClass(reinterpret_cast<void*>(ptr)));
shptr->GetCallClass(reinterpret_cast<void*>(ptr), sizeof(ifacetype)));
}
template<class ifacetype>
@ -319,14 +347,16 @@ inline void SH_RELEASE_CALLCLASS_R(SourceHook::ISourceHook *shptr, SourceHook::C
#define SH_RELEASE_CALLCLASS(ptr) SH_RELEASE_CALLCLASS_R(SH_GLOB_SHPTR, ptr)
#define SH_ADD_HOOK(ifacetype, ifacefunc, ifaceptr, handler, post) \
__SourceHook_FHAdd##ifacetype##ifacefunc((void*)ifaceptr, post, handler)
__SourceHook_FHAdd##ifacetype##ifacefunc((void*)SourceHook::implicit_cast<ifacetype*>(ifaceptr), \
post, handler)
#define SH_ADD_HOOK_STATICFUNC(ifacetype, ifacefunc, ifaceptr, handler, post) \
SH_ADD_HOOK(ifacetype, ifacefunc, ifaceptr, fastdelegate::MakeDelegate(handler), post)
#define SH_ADD_HOOK_MEMFUNC(ifacetype, ifacefunc, ifaceptr, handler_inst, handler_func, post) \
SH_ADD_HOOK(ifacetype, ifacefunc, ifaceptr, fastdelegate::MakeDelegate(handler_inst, handler_func), post)
#define SH_REMOVE_HOOK(ifacetype, ifacefunc, ifaceptr, handler, post) \
__SourceHook_FHRemove##ifacetype##ifacefunc((void*)ifaceptr, post, handler)
__SourceHook_FHRemove##ifacetype##ifacefunc((void*)SourceHook::implicit_cast<ifacetype*>(ifaceptr), \
post, handler)
#define SH_REMOVE_HOOK_STATICFUNC(ifacetype, ifacefunc, ifaceptr, handler, post) \
SH_REMOVE_HOOK(ifacetype, ifacefunc, ifaceptr, fastdelegate::MakeDelegate(handler), post)
#define SH_REMOVE_HOOK_MEMFUNC(ifacetype, ifacefunc, ifaceptr, handler_inst, handler_func, post) \
@ -355,6 +385,10 @@ inline void SH_RELEASE_CALLCLASS_R(SourceHook::ISourceHook *shptr, SourceHook::C
static int HookManPubFunc(::SourceHook::HookManagerAction action, ::SourceHook::HookManagerInfo *param) \
{ \
using namespace ::SourceHook; \
/* Verify interface version */ \
if (SH_GLOB_SHPTR->GetIfaceVersion() != SH_IFACE_VERSION) \
return 1; \
\
if (action == ::SourceHook::HA_GetInfo) \
{ \
param->proto = ms_Proto; \
@ -458,8 +492,8 @@ inline void SH_RELEASE_CALLCLASS_R(SourceHook::ISourceHook *shptr, SourceHook::C
META_RES &cur_res = SH_GLOB_SHPTR->GetCurResRef(); \
META_RES &prev_res = SH_GLOB_SHPTR->GetPrevResRef(); \
META_RES &status = SH_GLOB_SHPTR->GetStatusRef(); \
void* &ifptr = SH_GLOB_SHPTR->GetIfacePtrRef(); \
status = MRES_IGNORED; \
SH_GLOB_SHPTR->SetIfacePtr(this); \
SH_GLOB_SHPTR->SetOrigRet(reinterpret_cast<void*>(&orig_ret)); \
SH_GLOB_SHPTR->SetOverrideRet(NULL);
@ -469,6 +503,7 @@ inline void SH_RELEASE_CALLCLASS_R(SourceHook::ISourceHook *shptr, SourceHook::C
{ \
if (hiter->paused) continue; \
cur_res = MRES_IGNORED; \
ifptr = reinterpret_cast<void*>(reinterpret_cast<char*>(this) - hiter->thisptr_offs); \
plugin_ret = reinterpret_cast<CSHDelegate<FD>*>(hiter->handler)->GetDeleg() params; \
prev_res = cur_res; \
if (cur_res > status) \
@ -532,8 +567,8 @@ inline void SH_RELEASE_CALLCLASS_R(SourceHook::ISourceHook *shptr, SourceHook::C
META_RES &cur_res = SH_GLOB_SHPTR->GetCurResRef(); \
META_RES &prev_res = SH_GLOB_SHPTR->GetPrevResRef(); \
META_RES &status = SH_GLOB_SHPTR->GetStatusRef(); \
void* &ifptr = SH_GLOB_SHPTR->GetIfacePtrRef(); \
status = MRES_IGNORED; \
SH_GLOB_SHPTR->SetIfacePtr(this); \
SH_GLOB_SHPTR->SetOverrideRet(NULL);
#define SH_CALL_HOOKS_void(post, params) \
@ -542,6 +577,7 @@ inline void SH_RELEASE_CALLCLASS_R(SourceHook::ISourceHook *shptr, SourceHook::C
{ \
if (hiter->paused) continue; \
cur_res = MRES_IGNORED; \
ifptr = reinterpret_cast<void*>(reinterpret_cast<char*>(this) - hiter->thisptr_offs); \
reinterpret_cast<CSHDelegate<FD>*>(hiter->handler)->GetDeleg() params; \
prev_res = cur_res; \
if (cur_res > status) \
@ -646,8 +682,8 @@ inline void SH_RELEASE_CALLCLASS_R(SourceHook::ISourceHook *shptr, SourceHook::C
{ \
using namespace ::SourceHook; \
MemFuncInfo mfi; \
MFI_Impl<sizeof(m_MFP)>::GetFuncInfo(m_MFP, mfi); \
OrigVTables::const_iterator iter = m_CC->vt.find(mfi.vtbloffs); \
GetFuncInfo(m_CC->ptr, m_MFP, mfi); \
OrigVTables::const_iterator iter = m_CC->vt.find(mfi.thisptroffs + mfi.vtbloffs); \
if (iter == m_CC->vt.end() || mfi.vtblindex >= (int)iter->second.size() || iter->second[mfi.vtblindex] == NULL) \
return (m_CC->ptr->*m_MFP)call; \
\
@ -659,7 +695,8 @@ inline void SH_RELEASE_CALLCLASS_R(SourceHook::ISourceHook *shptr, SourceHook::C
} u; \
u.addr = iter->second[mfi.vtblindex]; \
\
return (reinterpret_cast<EmptyClass*>(m_CC->ptr)->*u.mfpnew)call; \
void *adjustedthisptr = reinterpret_cast<void*>(reinterpret_cast<char*>(m_CC->ptr) + mfi.thisptroffs); \
return (reinterpret_cast<EmptyClass*>(adjustedthisptr)->*u.mfpnew)call; \
}
@ -683,38 +720,54 @@ namespace SourceHook
};
}
// SH_CALL needs to deduce the return type -> it uses templates and function overloading
// That's why SH_CALL takes two parameters: "mfp2" of type RetType(X::*mfp)(params), and "mfp" of type MFP
// The only purpose of the mfp2 parameter is to extract the return type
@VARARGS@
// Support for @$@ arguments
template <class X, class Y, class RetType@, @@class Param%%|, @>
SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, RetType (X::*)(@Param%%|, @)>
SH_CALL(SourceHook::CallClass<Y> *ptr, RetType(X::*mfp)(@Param%%|, @))
template <class X, class Y, class MFP, class RetType@, @@class Param%%|, @>
SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, MFP>
SH_CALL2(SourceHook::CallClass<Y> *ptr, MFP mfp, RetType(X::*mfp2)(@Param%%|, @))
{
return SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, RetType (X::*)(@Param%%|, @)>(ptr, mfp);
return SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, MFP>(ptr, mfp);
}
template <class X, class Y, class RetType@, @@class Param%%|, @>
SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, RetType (X::*)(@Param%%|, @) const>
SH_CALL(SourceHook::CallClass<Y> *ptr, RetType(X::*mfp)(@Param%%|, @)const)
template <class X, class Y, class MFP, class RetType@, @@class Param%%|, @>
SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, MFP>
SH_CALL2(SourceHook::CallClass<Y> *ptr, MFP mfp, RetType(X::*mfp2)(@Param%%|, @)const)
{
return SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, RetType (X::*)(@Param%%|, @) const>(ptr, mfp);
}
template <class X, class Y, class RetType@, @@class Param%%|, @>
SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, RetType (X::*)(@Param%%|, @@, @...)>
SH_CALL(SourceHook::CallClass<Y> *ptr, RetType(X::*mfp)(@Param%%|, @@, @...))
{
return SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, RetType (X::*)(@Param%%|, @@, @...)>(ptr, mfp);
}
template <class X, class Y, class RetType@, @@class Param%%|, @>
SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, RetType (X::*)(@Param%%|, @@, @...) const>
SH_CALL(SourceHook::CallClass<Y> *ptr, RetType(X::*mfp)(@Param%%|, @@, @...)const)
{
return SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, RetType (X::*)(@Param%%|, @@, @...) const>(ptr, mfp);
return SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, MFP>(ptr, mfp);
}
@ENDARGS@
#if SH_COMP != SH_COMP_MSVC
// **** MSVC doesn't like these, GCC needs them ****
@VARARGS@
// Support for @$@ arguments
template <class X, class Y, class MFP, class RetType@, @@class Param%%|, @>
SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, MFP>
SH_CALL2(SourceHook::CallClass<Y> *ptr, MFP mfp, RetType(X::*mfp2)(@Param%%|, @@, @...))
{
return SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, MFP>(ptr, mfp);
}
template <class X, class Y, class MFP, class RetType@, @@class Param%%|, @>
SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, MFP>
SH_CALL2(SourceHook::CallClass<Y> *ptr, MFP mfp, RetType(X::*mfp2)(@Param%%|, @@, @...)const)
{
return SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, MFP>(ptr, mfp);
}
@ENDARGS@
#endif
#define SH_CALL(ptr, mfp) SH_CALL2((ptr), (mfp), (mfp))
#undef SH_MAKE_EXECUTABLECLASS_BODY
#endif

View File

@ -281,12 +281,254 @@ namespace SourceHook
# error Unsupported compiler
# endif
// This version does not take a this pointer
// Useful for hookdecls, as they ensure that mfp is correct through a static_cast
template<class X> inline void GetFuncInfo(X mfp, MemFuncInfo &out)
{
MFI_Impl<sizeof(mfp)>::GetFuncInfo(mfp, out);
}
// Versions which do take a this
template<class X, class Y, class RetType>
inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(), MemFuncInfo &out)
{
RetType(Y::*mfp2)() = mfp;
MFI_Impl<sizeof(mfp2)>::GetFuncInfo(mfp2, out);
}
template<class X, class Y, class RetType>
inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)() const, MemFuncInfo &out)
{
RetType(Y::*mfp2)() const = mfp;
MFI_Impl<sizeof(mfp2)>::GetFuncInfo(mfp2, out);
}
template<class X, class Y, class RetType, class Param1>
inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1), MemFuncInfo &out)
{
RetType(Y::*mfp2)(Param1) = mfp;
MFI_Impl<sizeof(mfp2)>::GetFuncInfo(mfp2, out);
}
template<class X, class Y, class RetType, class Param1>
inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1) const, MemFuncInfo &out)
{
RetType(Y::*mfp2)(Param1) const = mfp;
MFI_Impl<sizeof(mfp2)>::GetFuncInfo(mfp2, out);
}
template<class X, class Y, class RetType, class Param1, class Param2>
inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2), MemFuncInfo &out)
{
RetType(Y::*mfp2)(Param1, Param2) = mfp;
MFI_Impl<sizeof(mfp2)>::GetFuncInfo(mfp2, out);
}
template<class X, class Y, class RetType, class Param1, class Param2>
inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2) const, MemFuncInfo &out)
{
RetType(Y::*mfp2)(Param1, Param2) const = mfp;
MFI_Impl<sizeof(mfp2)>::GetFuncInfo(mfp2, out);
}
template<class X, class Y, class RetType, class Param1, class Param2, class Param3>
inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3), MemFuncInfo &out)
{
RetType(Y::*mfp2)(Param1, Param2, Param3) = mfp;
MFI_Impl<sizeof(mfp2)>::GetFuncInfo(mfp2, out);
}
template<class X, class Y, class RetType, class Param1, class Param2, class Param3>
inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3) const, MemFuncInfo &out)
{
RetType(Y::*mfp2)(Param1, Param2, Param3) const = mfp;
MFI_Impl<sizeof(mfp2)>::GetFuncInfo(mfp2, out);
}
template<class X, class Y, class RetType, class Param1, class Param2, class Param3, class Param4>
inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4), MemFuncInfo &out)
{
RetType(Y::*mfp2)(Param1, Param2, Param3, Param4) = mfp;
MFI_Impl<sizeof(mfp2)>::GetFuncInfo(mfp2, out);
}
template<class X, class Y, class RetType, class Param1, class Param2, class Param3, class Param4>
inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4) const, MemFuncInfo &out)
{
RetType(Y::*mfp2)(Param1, Param2, Param3, Param4) const = mfp;
MFI_Impl<sizeof(mfp2)>::GetFuncInfo(mfp2, out);
}
template<class X, class Y, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5>
inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5), MemFuncInfo &out)
{
RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, Param5) = mfp;
MFI_Impl<sizeof(mfp2)>::GetFuncInfo(mfp2, out);
}
template<class X, class Y, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5>
inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5) const, MemFuncInfo &out)
{
RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, Param5) const = mfp;
MFI_Impl<sizeof(mfp2)>::GetFuncInfo(mfp2, out);
}
template<class X, class Y, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6>
inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6), MemFuncInfo &out)
{
RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6) = mfp;
MFI_Impl<sizeof(mfp2)>::GetFuncInfo(mfp2, out);
}
template<class X, class Y, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6>
inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6) const, MemFuncInfo &out)
{
RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6) const = mfp;
MFI_Impl<sizeof(mfp2)>::GetFuncInfo(mfp2, out);
}
template<class X, class Y, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7>
inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7), MemFuncInfo &out)
{
RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7) = mfp;
MFI_Impl<sizeof(mfp2)>::GetFuncInfo(mfp2, out);
}
template<class X, class Y, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7>
inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7) const, MemFuncInfo &out)
{
RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7) const = mfp;
MFI_Impl<sizeof(mfp2)>::GetFuncInfo(mfp2, out);
}
template<class X, class Y, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8>
inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8), MemFuncInfo &out)
{
RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8) = mfp;
MFI_Impl<sizeof(mfp2)>::GetFuncInfo(mfp2, out);
}
template<class X, class Y, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8>
inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8) const, MemFuncInfo &out)
{
RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8) const = mfp;
MFI_Impl<sizeof(mfp2)>::GetFuncInfo(mfp2, out);
}
template<class X, class Y, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8, class Param9>
inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9), MemFuncInfo &out)
{
RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9) = mfp;
MFI_Impl<sizeof(mfp2)>::GetFuncInfo(mfp2, out);
}
template<class X, class Y, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8, class Param9>
inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9) const, MemFuncInfo &out)
{
RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9) const = mfp;
MFI_Impl<sizeof(mfp2)>::GetFuncInfo(mfp2, out);
}
template<class X, class Y, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8, class Param9, class Param10>
inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10), MemFuncInfo &out)
{
RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10) = mfp;
MFI_Impl<sizeof(mfp2)>::GetFuncInfo(mfp2, out);
}
template<class X, class Y, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8, class Param9, class Param10>
inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10) const, MemFuncInfo &out)
{
RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10) const = mfp;
MFI_Impl<sizeof(mfp2)>::GetFuncInfo(mfp2, out);
}
template<class X, class Y, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8, class Param9, class Param10, class Param11>
inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11), MemFuncInfo &out)
{
RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11) = mfp;
MFI_Impl<sizeof(mfp2)>::GetFuncInfo(mfp2, out);
}
template<class X, class Y, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8, class Param9, class Param10, class Param11>
inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11) const, MemFuncInfo &out)
{
RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11) const = mfp;
MFI_Impl<sizeof(mfp2)>::GetFuncInfo(mfp2, out);
}
template<class X, class Y, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8, class Param9, class Param10, class Param11, class Param12>
inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12), MemFuncInfo &out)
{
RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12) = mfp;
MFI_Impl<sizeof(mfp2)>::GetFuncInfo(mfp2, out);
}
template<class X, class Y, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8, class Param9, class Param10, class Param11, class Param12>
inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12) const, MemFuncInfo &out)
{
RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12) const = mfp;
MFI_Impl<sizeof(mfp2)>::GetFuncInfo(mfp2, out);
}
template<class X, class Y, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8, class Param9, class Param10, class Param11, class Param12, class Param13>
inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13), MemFuncInfo &out)
{
RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13) = mfp;
MFI_Impl<sizeof(mfp2)>::GetFuncInfo(mfp2, out);
}
template<class X, class Y, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8, class Param9, class Param10, class Param11, class Param12, class Param13>
inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13) const, MemFuncInfo &out)
{
RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13) const = mfp;
MFI_Impl<sizeof(mfp2)>::GetFuncInfo(mfp2, out);
}
template<class X, class Y, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8, class Param9, class Param10, class Param11, class Param12, class Param13, class Param14>
inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14), MemFuncInfo &out)
{
RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14) = mfp;
MFI_Impl<sizeof(mfp2)>::GetFuncInfo(mfp2, out);
}
template<class X, class Y, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8, class Param9, class Param10, class Param11, class Param12, class Param13, class Param14>
inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14) const, MemFuncInfo &out)
{
RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14) const = mfp;
MFI_Impl<sizeof(mfp2)>::GetFuncInfo(mfp2, out);
}
template<class X, class Y, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8, class Param9, class Param10, class Param11, class Param12, class Param13, class Param14, class Param15>
inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15), MemFuncInfo &out)
{
RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15) = mfp;
MFI_Impl<sizeof(mfp2)>::GetFuncInfo(mfp2, out);
}
template<class X, class Y, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8, class Param9, class Param10, class Param11, class Param12, class Param13, class Param14, class Param15>
inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15) const, MemFuncInfo &out)
{
RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15) const = mfp;
MFI_Impl<sizeof(mfp2)>::GetFuncInfo(mfp2, out);
}
template<class X, class Y, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8, class Param9, class Param10, class Param11, class Param12, class Param13, class Param14, class Param15, class Param16>
inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, Param16), MemFuncInfo &out)
{
RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, Param16) = mfp;
MFI_Impl<sizeof(mfp2)>::GetFuncInfo(mfp2, out);
}
template<class X, class Y, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8, class Param9, class Param10, class Param11, class Param12, class Param13, class Param14, class Param15, class Param16>
inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, Param16) const, MemFuncInfo &out)
{
RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, Param16) const = mfp;
MFI_Impl<sizeof(mfp2)>::GetFuncInfo(mfp2, out);
}
}
#endif

View File

@ -26,6 +26,16 @@ namespace SourceHook
{
}
int CSourceHookImpl::GetIfaceVersion()
{
return SH_IFACE_VERSION;
}
int CSourceHookImpl::GetImplVersion()
{
return SH_IMPL_VERSION;
}
bool CSourceHookImpl::IsPluginInUse(Plugin plug)
{
// Iterate through all hook managers which are in this plugin
@ -65,7 +75,7 @@ namespace SourceHook
for (hook_iter = iface_iter->name.begin(); hook_iter != iface_iter->name.end(); ++hook_iter) \
if (hook_iter->plug == plug) \
hookstoremove.push_back(RemoveHookInfo(hook_iter->plug, iface_iter->ptr, \
hmil_iter->func, hook_iter->handler, ispost))
hook_iter->thisptr_offs, hmil_iter->func, hook_iter->handler, ispost))
for (HookManInfoList::iterator hmil_iter = m_HookMans.begin(); hmil_iter != m_HookMans.end(); ++hmil_iter)
{
for (HookManagerInfo::VfnPtrListIter vfnptr_iter = hmil_iter->vfnptrs.begin();
@ -141,7 +151,7 @@ namespace SourceHook
#define TMP_CHECK_LIST(name, ispost) \
for (hook_iter = iface_iter->name.begin(); hook_iter != iface_iter->name.end(); ++hook_iter) \
hookstoremove.push_back(RemoveHookInfo(hook_iter->plug, iface_iter->ptr, \
hmil_iter->func, hook_iter->handler, ispost))
hook_iter->thisptr_offs, hmil_iter->func, hook_iter->handler, ispost))
for (HookManInfoList::iterator hmil_iter = m_HookMans.begin(); hmil_iter != m_HookMans.end(); ++hmil_iter)
{
for (HookManagerInfo::VfnPtrListIter vfnptr_iter = hmil_iter->vfnptrs.begin();
@ -223,9 +233,7 @@ namespace SourceHook
--vfnptr_iter;
// Now that it is done, check whether we have to update any callclasses
for (Impl_CallClassList::iterator cciter = m_CallClasses.begin(); cciter != m_CallClasses.end(); ++cciter)
if (cciter->cc.ptr == iface)
ApplyCallClassPatch(*cciter, tmp.vtbl_offs, tmp.vtbl_idx, vfnptr_iter->orig_entry);
ApplyCallClassPatches(adjustediface, tmp.vtbl_offs, tmp.vtbl_idx, vfp.orig_entry);
}
HookManagerInfo::VfnPtr::IfaceListIter iface_iter = std::find(
@ -247,6 +255,7 @@ namespace SourceHook
hookinfo.handler = handler;
hookinfo.plug = plug;
hookinfo.paused = false;
hookinfo.thisptr_offs = thisptr_offs;
if (post)
iface_iter->hooks_post.push_back(hookinfo);
else
@ -258,17 +267,12 @@ namespace SourceHook
bool CSourceHookImpl::RemoveHook(RemoveHookInfo info)
{
return RemoveHook(info.plug, info.iface, info.hookman, info.handler, info.post);
return RemoveHook(info.plug, info.iface, info.thisptr_offs, info.hookman, info.handler, info.post);
}
bool CSourceHookImpl::RemoveHook(Plugin plug, void *iface, int thisptr_offs, HookManagerPubFunc myHookMan, ISHDelegate *handler, bool post)
{
return RemoveHook(plug, reinterpret_cast<void*>(reinterpret_cast<char*>(iface)+thisptr_offs),
myHookMan, handler, post);
}
bool CSourceHookImpl::RemoveHook(Plugin plug, void *adjustediface, HookManagerPubFunc myHookMan, ISHDelegate *handler, bool post)
{
void *adjustediface = reinterpret_cast<void*>(reinterpret_cast<char*>(iface)+thisptr_offs);
HookManagerInfo tmp;
if (myHookMan(HA_GetInfo, &tmp) != 0)
return false;
@ -297,7 +301,8 @@ namespace SourceHook
for (std::list<HookManagerInfo::VfnPtr::Iface::Hook>::iterator hookiter = hooks.begin();
hookiter != hooks.end(); erase ? hookiter = hooks.erase(hookiter) : ++hookiter)
{
erase = hookiter->plug == plug && hookiter->handler->IsEqual(handler);
erase = hookiter->plug == plug && hookiter->handler->IsEqual(handler) &&
hookiter->thisptr_offs == thisptr_offs;
if (erase)
hookiter->handler->DeleteThis(); // Make the _plugin_ delete the handler object
}
@ -333,11 +338,11 @@ namespace SourceHook
return true;
}
GenericCallClass *CSourceHookImpl::GetCallClass(void *iface)
GenericCallClass *CSourceHookImpl::GetCallClass(void *iface, size_t size)
{
for (Impl_CallClassList::iterator cciter = m_CallClasses.begin(); cciter != m_CallClasses.end(); ++cciter)
{
if (cciter->cc.ptr == iface)
if (cciter->cc.ptr == iface && cciter->cc.objsize == size)
{
++cciter->refcounter;
return &cciter->cc;
@ -347,15 +352,9 @@ namespace SourceHook
CallClassInfo tmp;
tmp.refcounter = 1;
tmp.cc.ptr = iface;
tmp.cc.objsize = size;
for (HookManInfoList::iterator hookman = m_HookMans.begin(); hookman != m_HookMans.end(); ++hookman)
for (HookManagerInfo::VfnPtrListIter vfnptr_iter = hookman->vfnptrs.begin();
vfnptr_iter != hookman->vfnptrs.end(); ++vfnptr_iter)
for (HookManagerInfo::VfnPtr::IfaceListIter iface_iter = vfnptr_iter->ifaces.begin();
iface_iter != vfnptr_iter->ifaces.end(); ++iface_iter)
if (iface_iter->ptr == iface)
ApplyCallClassPatch(tmp, hookman->vtbl_offs, hookman->vtbl_idx,
vfnptr_iter->orig_entry);
ApplyCallClassPatches(tmp);
m_CallClasses.push_back(tmp);
return &m_CallClasses.back().cc;
@ -379,6 +378,55 @@ namespace SourceHook
tmpvec[vtbl_idx] = orig_entry;
}
void CSourceHookImpl::ApplyCallClassPatches(CallClassInfo &cc)
{
for (HookManInfoList::iterator hookman = m_HookMans.begin(); hookman != m_HookMans.end(); ++hookman)
{
for (HookManagerInfo::VfnPtrListIter vfnptr_iter = hookman->vfnptrs.begin();
vfnptr_iter != hookman->vfnptrs.end(); ++vfnptr_iter)
{
for (HookManagerInfo::VfnPtr::IfaceListIter iface_iter = vfnptr_iter->ifaces.begin();
iface_iter != vfnptr_iter->ifaces.end(); ++iface_iter)
{
if (iface_iter->ptr >= cc.cc.ptr &&
iface_iter->ptr < (reinterpret_cast<char*>(cc.cc.ptr) + cc.cc.objsize))
{
ApplyCallClassPatch(cc, static_cast<int>(reinterpret_cast<char*>(iface_iter->ptr) -
reinterpret_cast<char*>(cc.cc.ptr)) + hookman->vtbl_offs,
hookman->vtbl_idx, vfnptr_iter->orig_entry);
}
}
}
}
}
void CSourceHookImpl::ApplyCallClassPatches(void *ifaceptr, int vtbl_offs, int vtbl_idx, void *orig_entry)
{
for (Impl_CallClassList::iterator cc_iter = m_CallClasses.begin(); cc_iter != m_CallClasses.end();
++cc_iter)
{
if (ifaceptr >= cc_iter->cc.ptr &&
ifaceptr < (reinterpret_cast<char*>(cc_iter->cc.ptr) + cc_iter->cc.objsize))
{
ApplyCallClassPatch(*cc_iter, static_cast<int>(reinterpret_cast<char*>(ifaceptr) -
reinterpret_cast<char*>(cc_iter->cc.ptr)) + vtbl_offs, vtbl_idx, orig_entry);
}
}
}
void CSourceHookImpl::RemoveCallClassPatches(void *ifaceptr, int vtbl_offs, int vtbl_idx)
{
for (Impl_CallClassList::iterator cc_iter = m_CallClasses.begin(); cc_iter != m_CallClasses.end();
++cc_iter)
{
if (ifaceptr >= cc_iter->cc.ptr &&
ifaceptr < (reinterpret_cast<char*>(cc_iter->cc.ptr) + cc_iter->cc.objsize))
{
RemoveCallClassPatch(*cc_iter, vtbl_offs, vtbl_idx);
}
}
}
void CSourceHookImpl::RemoveCallClassPatch(CallClassInfo &cc, int vtbl_offs, int vtbl_idx)
{
OrigVTables::iterator iter = cc.cc.vt.find(vtbl_offs);
@ -496,6 +544,11 @@ namespace SourceHook
return m_Status;
}
void * &CSourceHookImpl::GetIfacePtrRef()
{
return m_IfacePtr;
}
void CSourceHookImpl::SetOrigRet(const void *ptr)
{
m_OrigRet = ptr;
@ -506,10 +559,6 @@ namespace SourceHook
m_OverrideRet = ptr;
}
void CSourceHookImpl::SetIfacePtr(void *ptr)
{
m_IfacePtr = ptr;
}
void *CSourceHookImpl::GetIfacePtr()
{
return m_IfacePtr;

View File

@ -1,6 +1,10 @@
/* ======== SourceHook ========
* By PM
* Copyright (C) 2004-2005 Metamod:Source Development Team
* No warranties of any kind
*
* License: zlib/libpng
*
* Author(s): Pavol "PM OnoTo" Marko
* ============================
*/
@ -12,6 +16,9 @@
#ifndef __SOURCEHOOK_H__
#define __SOURCEHOOK_H__
#define SH_IFACE_VERSION 1
#define SH_IMPL_VERSION 1
#ifndef SH_GLOB_SHPTR
#define SH_GLOB_SHPTR g_SHPtr
#endif
@ -88,6 +95,15 @@ namespace SourceHook
{
};
/**
* @brief Implicit cast.
*/
template <class In, class Out>
inline Out implicit_cast(In input)
{
return input;
}
/**
* @brief A plugin typedef
*
@ -164,6 +180,7 @@ namespace SourceHook
ISHDelegate *handler; //!< Pointer to the handler
bool paused; //!< If true, the hook should not be executed
Plugin plug; //!< The owner plugin
int thisptr_offs; //!< This pointer offset
};
void *ptr; //!< Pointer to the interface instance
std::list<Hook> hooks_pre; //!< A list of pre-hooks
@ -205,8 +222,9 @@ namespace SourceHook
template<class B> struct CallClass
{
B *ptr;
OrigVTables vt;
B *ptr; //!< Pointer to the actual object
size_t objsize; //!< Size of the instance
OrigVTables vt; //!< Info about vtables & functions
};
typedef CallClass<void> GenericCallClass;
@ -217,6 +235,16 @@ namespace SourceHook
class ISourceHook
{
public:
/**
* @brief Return interface version
*/
virtual int GetIfaceVersion() = 0;
/**
* @brief Return implementation version
*/
virtual int GetImplVersion() = 0;
/**
* @brief Add a hook.
*
@ -255,9 +283,9 @@ namespace SourceHook
* @brief Return a pointer to a callclass. Generate a new one if required.
*
* @param iface The interface pointer
* @param size Size of the class
* @param size Size of the class instance
*/
virtual GenericCallClass *GetCallClass(void *iface) = 0;
virtual GenericCallClass *GetCallClass(void *iface, size_t size) = 0;
/**
* @brief Release a callclass
@ -274,12 +302,12 @@ namespace SourceHook
virtual void *GetIfacePtr() = 0; //!< Gets the interface pointer
//////////////////////////////////////////////////////////////////////////
// For hook managers
virtual META_RES &GetCurResRef() = 0; //!< Gets the pointer to the current meta result
virtual META_RES &GetPrevResRef() = 0; //!< Gets the pointer to the previous meta result
virtual META_RES &GetStatusRef() = 0; //!< Gets the pointer to the status variable
virtual META_RES &GetCurResRef() = 0; //!< Gets the reference to the current meta result
virtual META_RES &GetPrevResRef() = 0; //!< Gets the reference to the previous meta result
virtual META_RES &GetStatusRef() = 0; //!< Gets the reference to the status variable
virtual void* &GetIfacePtrRef() = 0; //!< Gets the reference to the interface this pointer
virtual void SetOrigRet(const void *ptr) = 0; //!< Sets the original return pointer
virtual void SetOverrideRet(const void *ptr) = 0; //!< Sets the override result pointer
virtual void SetIfacePtr(void *ptr) = 0; //!< Sets the interface this pointer
};
}
@ -306,7 +334,7 @@ template<class ifacetype>
inline SourceHook::CallClass<ifacetype> *SH_GET_CALLCLASS_R(SourceHook::ISourceHook *shptr, ifacetype *ptr)
{
return reinterpret_cast<SourceHook::CallClass<ifacetype>*>(
shptr->GetCallClass(reinterpret_cast<void*>(ptr)));
shptr->GetCallClass(reinterpret_cast<void*>(ptr), sizeof(ifacetype)));
}
template<class ifacetype>
@ -319,14 +347,16 @@ inline void SH_RELEASE_CALLCLASS_R(SourceHook::ISourceHook *shptr, SourceHook::C
#define SH_RELEASE_CALLCLASS(ptr) SH_RELEASE_CALLCLASS_R(SH_GLOB_SHPTR, ptr)
#define SH_ADD_HOOK(ifacetype, ifacefunc, ifaceptr, handler, post) \
__SourceHook_FHAdd##ifacetype##ifacefunc((void*)ifaceptr, post, handler)
__SourceHook_FHAdd##ifacetype##ifacefunc((void*)SourceHook::implicit_cast<ifacetype*>(ifaceptr), \
post, handler)
#define SH_ADD_HOOK_STATICFUNC(ifacetype, ifacefunc, ifaceptr, handler, post) \
SH_ADD_HOOK(ifacetype, ifacefunc, ifaceptr, fastdelegate::MakeDelegate(handler), post)
#define SH_ADD_HOOK_MEMFUNC(ifacetype, ifacefunc, ifaceptr, handler_inst, handler_func, post) \
SH_ADD_HOOK(ifacetype, ifacefunc, ifaceptr, fastdelegate::MakeDelegate(handler_inst, handler_func), post)
#define SH_REMOVE_HOOK(ifacetype, ifacefunc, ifaceptr, handler, post) \
__SourceHook_FHRemove##ifacetype##ifacefunc((void*)ifaceptr, post, handler)
__SourceHook_FHRemove##ifacetype##ifacefunc((void*)SourceHook::implicit_cast<ifacetype*>(ifaceptr), \
post, handler)
#define SH_REMOVE_HOOK_STATICFUNC(ifacetype, ifacefunc, ifaceptr, handler, post) \
SH_REMOVE_HOOK(ifacetype, ifacefunc, ifaceptr, fastdelegate::MakeDelegate(handler), post)
#define SH_REMOVE_HOOK_MEMFUNC(ifacetype, ifacefunc, ifaceptr, handler_inst, handler_func, post) \
@ -355,6 +385,10 @@ inline void SH_RELEASE_CALLCLASS_R(SourceHook::ISourceHook *shptr, SourceHook::C
static int HookManPubFunc(::SourceHook::HookManagerAction action, ::SourceHook::HookManagerInfo *param) \
{ \
using namespace ::SourceHook; \
/* Verify interface version */ \
if (SH_GLOB_SHPTR->GetIfaceVersion() != SH_IFACE_VERSION) \
return 1; \
\
if (action == ::SourceHook::HA_GetInfo) \
{ \
param->proto = ms_Proto; \
@ -458,8 +492,8 @@ inline void SH_RELEASE_CALLCLASS_R(SourceHook::ISourceHook *shptr, SourceHook::C
META_RES &cur_res = SH_GLOB_SHPTR->GetCurResRef(); \
META_RES &prev_res = SH_GLOB_SHPTR->GetPrevResRef(); \
META_RES &status = SH_GLOB_SHPTR->GetStatusRef(); \
void* &ifptr = SH_GLOB_SHPTR->GetIfacePtrRef(); \
status = MRES_IGNORED; \
SH_GLOB_SHPTR->SetIfacePtr(this); \
SH_GLOB_SHPTR->SetOrigRet(reinterpret_cast<void*>(&orig_ret)); \
SH_GLOB_SHPTR->SetOverrideRet(NULL);
@ -469,6 +503,7 @@ inline void SH_RELEASE_CALLCLASS_R(SourceHook::ISourceHook *shptr, SourceHook::C
{ \
if (hiter->paused) continue; \
cur_res = MRES_IGNORED; \
ifptr = reinterpret_cast<void*>(reinterpret_cast<char*>(this) - hiter->thisptr_offs); \
plugin_ret = reinterpret_cast<CSHDelegate<FD>*>(hiter->handler)->GetDeleg() params; \
prev_res = cur_res; \
if (cur_res > status) \
@ -532,8 +567,8 @@ inline void SH_RELEASE_CALLCLASS_R(SourceHook::ISourceHook *shptr, SourceHook::C
META_RES &cur_res = SH_GLOB_SHPTR->GetCurResRef(); \
META_RES &prev_res = SH_GLOB_SHPTR->GetPrevResRef(); \
META_RES &status = SH_GLOB_SHPTR->GetStatusRef(); \
void* &ifptr = SH_GLOB_SHPTR->GetIfacePtrRef(); \
status = MRES_IGNORED; \
SH_GLOB_SHPTR->SetIfacePtr(this); \
SH_GLOB_SHPTR->SetOverrideRet(NULL);
#define SH_CALL_HOOKS_void(post, params) \
@ -542,6 +577,7 @@ inline void SH_RELEASE_CALLCLASS_R(SourceHook::ISourceHook *shptr, SourceHook::C
{ \
if (hiter->paused) continue; \
cur_res = MRES_IGNORED; \
ifptr = reinterpret_cast<void*>(reinterpret_cast<char*>(this) - hiter->thisptr_offs); \
reinterpret_cast<CSHDelegate<FD>*>(hiter->handler)->GetDeleg() params; \
prev_res = cur_res; \
if (cur_res > status) \
@ -1460,8 +1496,8 @@ inline void SH_RELEASE_CALLCLASS_R(SourceHook::ISourceHook *shptr, SourceHook::C
{ \
using namespace ::SourceHook; \
MemFuncInfo mfi; \
MFI_Impl<sizeof(m_MFP)>::GetFuncInfo(m_MFP, mfi); \
OrigVTables::const_iterator iter = m_CC->vt.find(mfi.vtbloffs); \
GetFuncInfo(m_CC->ptr, m_MFP, mfi); \
OrigVTables::const_iterator iter = m_CC->vt.find(mfi.thisptroffs + mfi.vtbloffs); \
if (iter == m_CC->vt.end() || mfi.vtblindex >= (int)iter->second.size() || iter->second[mfi.vtblindex] == NULL) \
return (m_CC->ptr->*m_MFP)call; \
\
@ -1473,7 +1509,8 @@ inline void SH_RELEASE_CALLCLASS_R(SourceHook::ISourceHook *shptr, SourceHook::C
} u; \
u.addr = iter->second[mfi.vtblindex]; \
\
return (reinterpret_cast<EmptyClass*>(m_CC->ptr)->*u.mfpnew)call; \
void *adjustedthisptr = reinterpret_cast<void*>(reinterpret_cast<char*>(m_CC->ptr) + mfi.thisptroffs); \
return (reinterpret_cast<EmptyClass*>(adjustedthisptr)->*u.mfpnew)call; \
}
@ -1559,499 +1596,529 @@ namespace SourceHook
};
}
// SH_CALL needs to deduce the return type -> it uses templates and function overloading
// That's why SH_CALL takes two parameters: "mfp2" of type RetType(X::*mfp)(params), and "mfp" of type MFP
// The only purpose of the mfp2 parameter is to extract the return type
// Support for 0 arguments
template <class X, class Y, class RetType>
SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, RetType (X::*)()>
SH_CALL(SourceHook::CallClass<Y> *ptr, RetType(X::*mfp)())
template <class X, class Y, class MFP, class RetType>
SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, MFP>
SH_CALL2(SourceHook::CallClass<Y> *ptr, MFP mfp, RetType(X::*mfp2)())
{
return SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, RetType (X::*)()>(ptr, mfp);
return SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, MFP>(ptr, mfp);
}
template <class X, class Y, class RetType>
SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, RetType (X::*)() const>
SH_CALL(SourceHook::CallClass<Y> *ptr, RetType(X::*mfp)()const)
template <class X, class Y, class MFP, class RetType>
SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, MFP>
SH_CALL2(SourceHook::CallClass<Y> *ptr, MFP mfp, RetType(X::*mfp2)()const)
{
return SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, RetType (X::*)() const>(ptr, mfp);
}
template <class X, class Y, class RetType>
SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, RetType (X::*)(...)>
SH_CALL(SourceHook::CallClass<Y> *ptr, RetType(X::*mfp)(...))
{
return SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, RetType (X::*)(...)>(ptr, mfp);
}
template <class X, class Y, class RetType>
SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, RetType (X::*)(...) const>
SH_CALL(SourceHook::CallClass<Y> *ptr, RetType(X::*mfp)(...)const)
{
return SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, RetType (X::*)(...) const>(ptr, mfp);
return SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, MFP>(ptr, mfp);
}
// Support for 1 arguments
template <class X, class Y, class RetType, class Param1>
SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, RetType (X::*)(Param1)>
SH_CALL(SourceHook::CallClass<Y> *ptr, RetType(X::*mfp)(Param1))
template <class X, class Y, class MFP, class RetType, class Param1>
SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, MFP>
SH_CALL2(SourceHook::CallClass<Y> *ptr, MFP mfp, RetType(X::*mfp2)(Param1))
{
return SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, RetType (X::*)(Param1)>(ptr, mfp);
return SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, MFP>(ptr, mfp);
}
template <class X, class Y, class RetType, class Param1>
SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, RetType (X::*)(Param1) const>
SH_CALL(SourceHook::CallClass<Y> *ptr, RetType(X::*mfp)(Param1)const)
template <class X, class Y, class MFP, class RetType, class Param1>
SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, MFP>
SH_CALL2(SourceHook::CallClass<Y> *ptr, MFP mfp, RetType(X::*mfp2)(Param1)const)
{
return SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, RetType (X::*)(Param1) const>(ptr, mfp);
}
template <class X, class Y, class RetType, class Param1>
SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, RetType (X::*)(Param1, ...)>
SH_CALL(SourceHook::CallClass<Y> *ptr, RetType(X::*mfp)(Param1, ...))
{
return SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, RetType (X::*)(Param1, ...)>(ptr, mfp);
}
template <class X, class Y, class RetType, class Param1>
SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, RetType (X::*)(Param1, ...) const>
SH_CALL(SourceHook::CallClass<Y> *ptr, RetType(X::*mfp)(Param1, ...)const)
{
return SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, RetType (X::*)(Param1, ...) const>(ptr, mfp);
return SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, MFP>(ptr, mfp);
}
// Support for 2 arguments
template <class X, class Y, class RetType, class Param1, class Param2>
SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, RetType (X::*)(Param1, Param2)>
SH_CALL(SourceHook::CallClass<Y> *ptr, RetType(X::*mfp)(Param1, Param2))
template <class X, class Y, class MFP, class RetType, class Param1, class Param2>
SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, MFP>
SH_CALL2(SourceHook::CallClass<Y> *ptr, MFP mfp, RetType(X::*mfp2)(Param1, Param2))
{
return SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, RetType (X::*)(Param1, Param2)>(ptr, mfp);
return SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, MFP>(ptr, mfp);
}
template <class X, class Y, class RetType, class Param1, class Param2>
SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, RetType (X::*)(Param1, Param2) const>
SH_CALL(SourceHook::CallClass<Y> *ptr, RetType(X::*mfp)(Param1, Param2)const)
template <class X, class Y, class MFP, class RetType, class Param1, class Param2>
SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, MFP>
SH_CALL2(SourceHook::CallClass<Y> *ptr, MFP mfp, RetType(X::*mfp2)(Param1, Param2)const)
{
return SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, RetType (X::*)(Param1, Param2) const>(ptr, mfp);
}
template <class X, class Y, class RetType, class Param1, class Param2>
SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, RetType (X::*)(Param1, Param2, ...)>
SH_CALL(SourceHook::CallClass<Y> *ptr, RetType(X::*mfp)(Param1, Param2, ...))
{
return SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, RetType (X::*)(Param1, Param2, ...)>(ptr, mfp);
}
template <class X, class Y, class RetType, class Param1, class Param2>
SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, RetType (X::*)(Param1, Param2, ...) const>
SH_CALL(SourceHook::CallClass<Y> *ptr, RetType(X::*mfp)(Param1, Param2, ...)const)
{
return SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, RetType (X::*)(Param1, Param2, ...) const>(ptr, mfp);
return SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, MFP>(ptr, mfp);
}
// Support for 3 arguments
template <class X, class Y, class RetType, class Param1, class Param2, class Param3>
SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, RetType (X::*)(Param1, Param2, Param3)>
SH_CALL(SourceHook::CallClass<Y> *ptr, RetType(X::*mfp)(Param1, Param2, Param3))
template <class X, class Y, class MFP, class RetType, class Param1, class Param2, class Param3>
SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, MFP>
SH_CALL2(SourceHook::CallClass<Y> *ptr, MFP mfp, RetType(X::*mfp2)(Param1, Param2, Param3))
{
return SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, RetType (X::*)(Param1, Param2, Param3)>(ptr, mfp);
return SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, MFP>(ptr, mfp);
}
template <class X, class Y, class RetType, class Param1, class Param2, class Param3>
SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, RetType (X::*)(Param1, Param2, Param3) const>
SH_CALL(SourceHook::CallClass<Y> *ptr, RetType(X::*mfp)(Param1, Param2, Param3)const)
template <class X, class Y, class MFP, class RetType, class Param1, class Param2, class Param3>
SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, MFP>
SH_CALL2(SourceHook::CallClass<Y> *ptr, MFP mfp, RetType(X::*mfp2)(Param1, Param2, Param3)const)
{
return SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, RetType (X::*)(Param1, Param2, Param3) const>(ptr, mfp);
}
template <class X, class Y, class RetType, class Param1, class Param2, class Param3>
SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, RetType (X::*)(Param1, Param2, Param3, ...)>
SH_CALL(SourceHook::CallClass<Y> *ptr, RetType(X::*mfp)(Param1, Param2, Param3, ...))
{
return SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, RetType (X::*)(Param1, Param2, Param3, ...)>(ptr, mfp);
}
template <class X, class Y, class RetType, class Param1, class Param2, class Param3>
SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, RetType (X::*)(Param1, Param2, Param3, ...) const>
SH_CALL(SourceHook::CallClass<Y> *ptr, RetType(X::*mfp)(Param1, Param2, Param3, ...)const)
{
return SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, RetType (X::*)(Param1, Param2, Param3, ...) const>(ptr, mfp);
return SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, MFP>(ptr, mfp);
}
// Support for 4 arguments
template <class X, class Y, class RetType, class Param1, class Param2, class Param3, class Param4>
SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, RetType (X::*)(Param1, Param2, Param3, Param4)>
SH_CALL(SourceHook::CallClass<Y> *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4))
template <class X, class Y, class MFP, class RetType, class Param1, class Param2, class Param3, class Param4>
SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, MFP>
SH_CALL2(SourceHook::CallClass<Y> *ptr, MFP mfp, RetType(X::*mfp2)(Param1, Param2, Param3, Param4))
{
return SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, RetType (X::*)(Param1, Param2, Param3, Param4)>(ptr, mfp);
return SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, MFP>(ptr, mfp);
}
template <class X, class Y, class RetType, class Param1, class Param2, class Param3, class Param4>
SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, RetType (X::*)(Param1, Param2, Param3, Param4) const>
SH_CALL(SourceHook::CallClass<Y> *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4)const)
template <class X, class Y, class MFP, class RetType, class Param1, class Param2, class Param3, class Param4>
SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, MFP>
SH_CALL2(SourceHook::CallClass<Y> *ptr, MFP mfp, RetType(X::*mfp2)(Param1, Param2, Param3, Param4)const)
{
return SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, RetType (X::*)(Param1, Param2, Param3, Param4) const>(ptr, mfp);
}
template <class X, class Y, class RetType, class Param1, class Param2, class Param3, class Param4>
SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, RetType (X::*)(Param1, Param2, Param3, Param4, ...)>
SH_CALL(SourceHook::CallClass<Y> *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, ...))
{
return SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, RetType (X::*)(Param1, Param2, Param3, Param4, ...)>(ptr, mfp);
}
template <class X, class Y, class RetType, class Param1, class Param2, class Param3, class Param4>
SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, RetType (X::*)(Param1, Param2, Param3, Param4, ...) const>
SH_CALL(SourceHook::CallClass<Y> *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, ...)const)
{
return SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, RetType (X::*)(Param1, Param2, Param3, Param4, ...) const>(ptr, mfp);
return SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, MFP>(ptr, mfp);
}
// Support for 5 arguments
template <class X, class Y, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5>
SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, RetType (X::*)(Param1, Param2, Param3, Param4, Param5)>
SH_CALL(SourceHook::CallClass<Y> *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5))
template <class X, class Y, class MFP, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5>
SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, MFP>
SH_CALL2(SourceHook::CallClass<Y> *ptr, MFP mfp, RetType(X::*mfp2)(Param1, Param2, Param3, Param4, Param5))
{
return SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, RetType (X::*)(Param1, Param2, Param3, Param4, Param5)>(ptr, mfp);
return SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, MFP>(ptr, mfp);
}
template <class X, class Y, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5>
SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, RetType (X::*)(Param1, Param2, Param3, Param4, Param5) const>
SH_CALL(SourceHook::CallClass<Y> *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5)const)
template <class X, class Y, class MFP, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5>
SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, MFP>
SH_CALL2(SourceHook::CallClass<Y> *ptr, MFP mfp, RetType(X::*mfp2)(Param1, Param2, Param3, Param4, Param5)const)
{
return SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, RetType (X::*)(Param1, Param2, Param3, Param4, Param5) const>(ptr, mfp);
}
template <class X, class Y, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5>
SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, RetType (X::*)(Param1, Param2, Param3, Param4, Param5, ...)>
SH_CALL(SourceHook::CallClass<Y> *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, ...))
{
return SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, RetType (X::*)(Param1, Param2, Param3, Param4, Param5, ...)>(ptr, mfp);
}
template <class X, class Y, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5>
SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, RetType (X::*)(Param1, Param2, Param3, Param4, Param5, ...) const>
SH_CALL(SourceHook::CallClass<Y> *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, ...)const)
{
return SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, RetType (X::*)(Param1, Param2, Param3, Param4, Param5, ...) const>(ptr, mfp);
return SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, MFP>(ptr, mfp);
}
// Support for 6 arguments
template <class X, class Y, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6>
SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, RetType (X::*)(Param1, Param2, Param3, Param4, Param5, Param6)>
SH_CALL(SourceHook::CallClass<Y> *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6))
template <class X, class Y, class MFP, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6>
SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, MFP>
SH_CALL2(SourceHook::CallClass<Y> *ptr, MFP mfp, RetType(X::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6))
{
return SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, RetType (X::*)(Param1, Param2, Param3, Param4, Param5, Param6)>(ptr, mfp);
return SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, MFP>(ptr, mfp);
}
template <class X, class Y, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6>
SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, RetType (X::*)(Param1, Param2, Param3, Param4, Param5, Param6) const>
SH_CALL(SourceHook::CallClass<Y> *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6)const)
template <class X, class Y, class MFP, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6>
SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, MFP>
SH_CALL2(SourceHook::CallClass<Y> *ptr, MFP mfp, RetType(X::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6)const)
{
return SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, RetType (X::*)(Param1, Param2, Param3, Param4, Param5, Param6) const>(ptr, mfp);
}
template <class X, class Y, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6>
SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, RetType (X::*)(Param1, Param2, Param3, Param4, Param5, Param6, ...)>
SH_CALL(SourceHook::CallClass<Y> *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, ...))
{
return SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, RetType (X::*)(Param1, Param2, Param3, Param4, Param5, Param6, ...)>(ptr, mfp);
}
template <class X, class Y, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6>
SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, RetType (X::*)(Param1, Param2, Param3, Param4, Param5, Param6, ...) const>
SH_CALL(SourceHook::CallClass<Y> *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, ...)const)
{
return SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, RetType (X::*)(Param1, Param2, Param3, Param4, Param5, Param6, ...) const>(ptr, mfp);
return SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, MFP>(ptr, mfp);
}
// Support for 7 arguments
template <class X, class Y, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7>
SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, RetType (X::*)(Param1, Param2, Param3, Param4, Param5, Param6, Param7)>
SH_CALL(SourceHook::CallClass<Y> *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7))
template <class X, class Y, class MFP, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7>
SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, MFP>
SH_CALL2(SourceHook::CallClass<Y> *ptr, MFP mfp, RetType(X::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7))
{
return SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, RetType (X::*)(Param1, Param2, Param3, Param4, Param5, Param6, Param7)>(ptr, mfp);
return SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, MFP>(ptr, mfp);
}
template <class X, class Y, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7>
SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, RetType (X::*)(Param1, Param2, Param3, Param4, Param5, Param6, Param7) const>
SH_CALL(SourceHook::CallClass<Y> *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7)const)
template <class X, class Y, class MFP, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7>
SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, MFP>
SH_CALL2(SourceHook::CallClass<Y> *ptr, MFP mfp, RetType(X::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7)const)
{
return SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, RetType (X::*)(Param1, Param2, Param3, Param4, Param5, Param6, Param7) const>(ptr, mfp);
}
template <class X, class Y, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7>
SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, RetType (X::*)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, ...)>
SH_CALL(SourceHook::CallClass<Y> *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, ...))
{
return SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, RetType (X::*)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, ...)>(ptr, mfp);
}
template <class X, class Y, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7>
SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, RetType (X::*)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, ...) const>
SH_CALL(SourceHook::CallClass<Y> *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, ...)const)
{
return SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, RetType (X::*)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, ...) const>(ptr, mfp);
return SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, MFP>(ptr, mfp);
}
// Support for 8 arguments
template <class X, class Y, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8>
SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, RetType (X::*)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8)>
SH_CALL(SourceHook::CallClass<Y> *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8))
template <class X, class Y, class MFP, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8>
SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, MFP>
SH_CALL2(SourceHook::CallClass<Y> *ptr, MFP mfp, RetType(X::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8))
{
return SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, RetType (X::*)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8)>(ptr, mfp);
return SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, MFP>(ptr, mfp);
}
template <class X, class Y, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8>
SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, RetType (X::*)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8) const>
SH_CALL(SourceHook::CallClass<Y> *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8)const)
template <class X, class Y, class MFP, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8>
SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, MFP>
SH_CALL2(SourceHook::CallClass<Y> *ptr, MFP mfp, RetType(X::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8)const)
{
return SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, RetType (X::*)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8) const>(ptr, mfp);
}
template <class X, class Y, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8>
SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, RetType (X::*)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, ...)>
SH_CALL(SourceHook::CallClass<Y> *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, ...))
{
return SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, RetType (X::*)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, ...)>(ptr, mfp);
}
template <class X, class Y, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8>
SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, RetType (X::*)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, ...) const>
SH_CALL(SourceHook::CallClass<Y> *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, ...)const)
{
return SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, RetType (X::*)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, ...) const>(ptr, mfp);
return SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, MFP>(ptr, mfp);
}
// Support for 9 arguments
template <class X, class Y, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8, class Param9>
SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, RetType (X::*)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9)>
SH_CALL(SourceHook::CallClass<Y> *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9))
template <class X, class Y, class MFP, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8, class Param9>
SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, MFP>
SH_CALL2(SourceHook::CallClass<Y> *ptr, MFP mfp, RetType(X::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9))
{
return SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, RetType (X::*)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9)>(ptr, mfp);
return SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, MFP>(ptr, mfp);
}
template <class X, class Y, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8, class Param9>
SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, RetType (X::*)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9) const>
SH_CALL(SourceHook::CallClass<Y> *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9)const)
template <class X, class Y, class MFP, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8, class Param9>
SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, MFP>
SH_CALL2(SourceHook::CallClass<Y> *ptr, MFP mfp, RetType(X::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9)const)
{
return SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, RetType (X::*)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9) const>(ptr, mfp);
}
template <class X, class Y, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8, class Param9>
SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, RetType (X::*)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, ...)>
SH_CALL(SourceHook::CallClass<Y> *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, ...))
{
return SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, RetType (X::*)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, ...)>(ptr, mfp);
}
template <class X, class Y, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8, class Param9>
SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, RetType (X::*)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, ...) const>
SH_CALL(SourceHook::CallClass<Y> *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, ...)const)
{
return SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, RetType (X::*)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, ...) const>(ptr, mfp);
return SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, MFP>(ptr, mfp);
}
// Support for 10 arguments
template <class X, class Y, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8, class Param9, class Param10>
SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, RetType (X::*)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10)>
SH_CALL(SourceHook::CallClass<Y> *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10))
template <class X, class Y, class MFP, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8, class Param9, class Param10>
SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, MFP>
SH_CALL2(SourceHook::CallClass<Y> *ptr, MFP mfp, RetType(X::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10))
{
return SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, RetType (X::*)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10)>(ptr, mfp);
return SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, MFP>(ptr, mfp);
}
template <class X, class Y, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8, class Param9, class Param10>
SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, RetType (X::*)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10) const>
SH_CALL(SourceHook::CallClass<Y> *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10)const)
template <class X, class Y, class MFP, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8, class Param9, class Param10>
SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, MFP>
SH_CALL2(SourceHook::CallClass<Y> *ptr, MFP mfp, RetType(X::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10)const)
{
return SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, RetType (X::*)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10) const>(ptr, mfp);
}
template <class X, class Y, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8, class Param9, class Param10>
SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, RetType (X::*)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, ...)>
SH_CALL(SourceHook::CallClass<Y> *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, ...))
{
return SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, RetType (X::*)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, ...)>(ptr, mfp);
}
template <class X, class Y, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8, class Param9, class Param10>
SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, RetType (X::*)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, ...) const>
SH_CALL(SourceHook::CallClass<Y> *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, ...)const)
{
return SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, RetType (X::*)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, ...) const>(ptr, mfp);
return SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, MFP>(ptr, mfp);
}
// Support for 11 arguments
template <class X, class Y, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8, class Param9, class Param10, class Param11>
SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, RetType (X::*)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11)>
SH_CALL(SourceHook::CallClass<Y> *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11))
template <class X, class Y, class MFP, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8, class Param9, class Param10, class Param11>
SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, MFP>
SH_CALL2(SourceHook::CallClass<Y> *ptr, MFP mfp, RetType(X::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11))
{
return SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, RetType (X::*)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11)>(ptr, mfp);
return SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, MFP>(ptr, mfp);
}
template <class X, class Y, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8, class Param9, class Param10, class Param11>
SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, RetType (X::*)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11) const>
SH_CALL(SourceHook::CallClass<Y> *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11)const)
template <class X, class Y, class MFP, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8, class Param9, class Param10, class Param11>
SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, MFP>
SH_CALL2(SourceHook::CallClass<Y> *ptr, MFP mfp, RetType(X::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11)const)
{
return SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, RetType (X::*)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11) const>(ptr, mfp);
}
template <class X, class Y, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8, class Param9, class Param10, class Param11>
SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, RetType (X::*)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, ...)>
SH_CALL(SourceHook::CallClass<Y> *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, ...))
{
return SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, RetType (X::*)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, ...)>(ptr, mfp);
}
template <class X, class Y, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8, class Param9, class Param10, class Param11>
SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, RetType (X::*)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, ...) const>
SH_CALL(SourceHook::CallClass<Y> *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, ...)const)
{
return SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, RetType (X::*)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, ...) const>(ptr, mfp);
return SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, MFP>(ptr, mfp);
}
// Support for 12 arguments
template <class X, class Y, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8, class Param9, class Param10, class Param11, class Param12>
SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, RetType (X::*)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12)>
SH_CALL(SourceHook::CallClass<Y> *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12))
template <class X, class Y, class MFP, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8, class Param9, class Param10, class Param11, class Param12>
SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, MFP>
SH_CALL2(SourceHook::CallClass<Y> *ptr, MFP mfp, RetType(X::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12))
{
return SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, RetType (X::*)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12)>(ptr, mfp);
return SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, MFP>(ptr, mfp);
}
template <class X, class Y, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8, class Param9, class Param10, class Param11, class Param12>
SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, RetType (X::*)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12) const>
SH_CALL(SourceHook::CallClass<Y> *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12)const)
template <class X, class Y, class MFP, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8, class Param9, class Param10, class Param11, class Param12>
SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, MFP>
SH_CALL2(SourceHook::CallClass<Y> *ptr, MFP mfp, RetType(X::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12)const)
{
return SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, RetType (X::*)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12) const>(ptr, mfp);
}
template <class X, class Y, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8, class Param9, class Param10, class Param11, class Param12>
SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, RetType (X::*)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, ...)>
SH_CALL(SourceHook::CallClass<Y> *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, ...))
{
return SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, RetType (X::*)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, ...)>(ptr, mfp);
}
template <class X, class Y, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8, class Param9, class Param10, class Param11, class Param12>
SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, RetType (X::*)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, ...) const>
SH_CALL(SourceHook::CallClass<Y> *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, ...)const)
{
return SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, RetType (X::*)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, ...) const>(ptr, mfp);
return SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, MFP>(ptr, mfp);
}
// Support for 13 arguments
template <class X, class Y, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8, class Param9, class Param10, class Param11, class Param12, class Param13>
SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, RetType (X::*)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13)>
SH_CALL(SourceHook::CallClass<Y> *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13))
template <class X, class Y, class MFP, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8, class Param9, class Param10, class Param11, class Param12, class Param13>
SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, MFP>
SH_CALL2(SourceHook::CallClass<Y> *ptr, MFP mfp, RetType(X::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13))
{
return SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, RetType (X::*)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13)>(ptr, mfp);
return SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, MFP>(ptr, mfp);
}
template <class X, class Y, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8, class Param9, class Param10, class Param11, class Param12, class Param13>
SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, RetType (X::*)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13) const>
SH_CALL(SourceHook::CallClass<Y> *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13)const)
template <class X, class Y, class MFP, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8, class Param9, class Param10, class Param11, class Param12, class Param13>
SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, MFP>
SH_CALL2(SourceHook::CallClass<Y> *ptr, MFP mfp, RetType(X::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13)const)
{
return SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, RetType (X::*)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13) const>(ptr, mfp);
}
template <class X, class Y, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8, class Param9, class Param10, class Param11, class Param12, class Param13>
SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, RetType (X::*)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, ...)>
SH_CALL(SourceHook::CallClass<Y> *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, ...))
{
return SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, RetType (X::*)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, ...)>(ptr, mfp);
}
template <class X, class Y, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8, class Param9, class Param10, class Param11, class Param12, class Param13>
SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, RetType (X::*)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, ...) const>
SH_CALL(SourceHook::CallClass<Y> *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, ...)const)
{
return SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, RetType (X::*)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, ...) const>(ptr, mfp);
return SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, MFP>(ptr, mfp);
}
// Support for 14 arguments
template <class X, class Y, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8, class Param9, class Param10, class Param11, class Param12, class Param13, class Param14>
SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, RetType (X::*)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14)>
SH_CALL(SourceHook::CallClass<Y> *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14))
template <class X, class Y, class MFP, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8, class Param9, class Param10, class Param11, class Param12, class Param13, class Param14>
SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, MFP>
SH_CALL2(SourceHook::CallClass<Y> *ptr, MFP mfp, RetType(X::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14))
{
return SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, RetType (X::*)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14)>(ptr, mfp);
return SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, MFP>(ptr, mfp);
}
template <class X, class Y, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8, class Param9, class Param10, class Param11, class Param12, class Param13, class Param14>
SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, RetType (X::*)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14) const>
SH_CALL(SourceHook::CallClass<Y> *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14)const)
template <class X, class Y, class MFP, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8, class Param9, class Param10, class Param11, class Param12, class Param13, class Param14>
SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, MFP>
SH_CALL2(SourceHook::CallClass<Y> *ptr, MFP mfp, RetType(X::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14)const)
{
return SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, RetType (X::*)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14) const>(ptr, mfp);
}
template <class X, class Y, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8, class Param9, class Param10, class Param11, class Param12, class Param13, class Param14>
SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, RetType (X::*)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, ...)>
SH_CALL(SourceHook::CallClass<Y> *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, ...))
{
return SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, RetType (X::*)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, ...)>(ptr, mfp);
}
template <class X, class Y, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8, class Param9, class Param10, class Param11, class Param12, class Param13, class Param14>
SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, RetType (X::*)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, ...) const>
SH_CALL(SourceHook::CallClass<Y> *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, ...)const)
{
return SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, RetType (X::*)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, ...) const>(ptr, mfp);
return SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, MFP>(ptr, mfp);
}
// Support for 15 arguments
template <class X, class Y, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8, class Param9, class Param10, class Param11, class Param12, class Param13, class Param14, class Param15>
SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, RetType (X::*)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15)>
SH_CALL(SourceHook::CallClass<Y> *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15))
template <class X, class Y, class MFP, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8, class Param9, class Param10, class Param11, class Param12, class Param13, class Param14, class Param15>
SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, MFP>
SH_CALL2(SourceHook::CallClass<Y> *ptr, MFP mfp, RetType(X::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15))
{
return SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, RetType (X::*)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15)>(ptr, mfp);
return SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, MFP>(ptr, mfp);
}
template <class X, class Y, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8, class Param9, class Param10, class Param11, class Param12, class Param13, class Param14, class Param15>
SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, RetType (X::*)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15) const>
SH_CALL(SourceHook::CallClass<Y> *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15)const)
template <class X, class Y, class MFP, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8, class Param9, class Param10, class Param11, class Param12, class Param13, class Param14, class Param15>
SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, MFP>
SH_CALL2(SourceHook::CallClass<Y> *ptr, MFP mfp, RetType(X::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15)const)
{
return SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, RetType (X::*)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15) const>(ptr, mfp);
}
template <class X, class Y, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8, class Param9, class Param10, class Param11, class Param12, class Param13, class Param14, class Param15>
SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, RetType (X::*)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, ...)>
SH_CALL(SourceHook::CallClass<Y> *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, ...))
{
return SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, RetType (X::*)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, ...)>(ptr, mfp);
}
template <class X, class Y, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8, class Param9, class Param10, class Param11, class Param12, class Param13, class Param14, class Param15>
SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, RetType (X::*)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, ...) const>
SH_CALL(SourceHook::CallClass<Y> *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, ...)const)
{
return SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, RetType (X::*)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, ...) const>(ptr, mfp);
return SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, MFP>(ptr, mfp);
}
// Support for 16 arguments
template <class X, class Y, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8, class Param9, class Param10, class Param11, class Param12, class Param13, class Param14, class Param15, class Param16>
SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, RetType (X::*)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, Param16)>
SH_CALL(SourceHook::CallClass<Y> *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, Param16))
template <class X, class Y, class MFP, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8, class Param9, class Param10, class Param11, class Param12, class Param13, class Param14, class Param15, class Param16>
SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, MFP>
SH_CALL2(SourceHook::CallClass<Y> *ptr, MFP mfp, RetType(X::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, Param16))
{
return SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, RetType (X::*)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, Param16)>(ptr, mfp);
return SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, MFP>(ptr, mfp);
}
template <class X, class Y, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8, class Param9, class Param10, class Param11, class Param12, class Param13, class Param14, class Param15, class Param16>
SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, RetType (X::*)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, Param16) const>
SH_CALL(SourceHook::CallClass<Y> *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, Param16)const)
template <class X, class Y, class MFP, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8, class Param9, class Param10, class Param11, class Param12, class Param13, class Param14, class Param15, class Param16>
SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, MFP>
SH_CALL2(SourceHook::CallClass<Y> *ptr, MFP mfp, RetType(X::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, Param16)const)
{
return SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, RetType (X::*)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, Param16) const>(ptr, mfp);
return SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, MFP>(ptr, mfp);
}
template <class X, class Y, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8, class Param9, class Param10, class Param11, class Param12, class Param13, class Param14, class Param15, class Param16>
SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, RetType (X::*)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, Param16, ...)>
SH_CALL(SourceHook::CallClass<Y> *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, Param16, ...))
#if SH_COMP != SH_COMP_MSVC
// **** MSVC doesn't like these, GCC needs them ****
// Support for 0 arguments
template <class X, class Y, class MFP, class RetType>
SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, MFP>
SH_CALL2(SourceHook::CallClass<Y> *ptr, MFP mfp, RetType(X::*mfp2)(...))
{
return SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, RetType (X::*)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, Param16, ...)>(ptr, mfp);
return SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, MFP>(ptr, mfp);
}
template <class X, class Y, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8, class Param9, class Param10, class Param11, class Param12, class Param13, class Param14, class Param15, class Param16>
SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, RetType (X::*)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, Param16, ...) const>
SH_CALL(SourceHook::CallClass<Y> *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, Param16, ...)const)
template <class X, class Y, class MFP, class RetType>
SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, MFP>
SH_CALL2(SourceHook::CallClass<Y> *ptr, MFP mfp, RetType(X::*mfp2)(...)const)
{
return SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, RetType (X::*)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, Param16, ...) const>(ptr, mfp);
return SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, MFP>(ptr, mfp);
}
// Support for 1 arguments
template <class X, class Y, class MFP, class RetType, class Param1>
SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, MFP>
SH_CALL2(SourceHook::CallClass<Y> *ptr, MFP mfp, RetType(X::*mfp2)(Param1, ...))
{
return SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, MFP>(ptr, mfp);
}
template <class X, class Y, class MFP, class RetType, class Param1>
SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, MFP>
SH_CALL2(SourceHook::CallClass<Y> *ptr, MFP mfp, RetType(X::*mfp2)(Param1, ...)const)
{
return SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, MFP>(ptr, mfp);
}
// Support for 2 arguments
template <class X, class Y, class MFP, class RetType, class Param1, class Param2>
SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, MFP>
SH_CALL2(SourceHook::CallClass<Y> *ptr, MFP mfp, RetType(X::*mfp2)(Param1, Param2, ...))
{
return SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, MFP>(ptr, mfp);
}
template <class X, class Y, class MFP, class RetType, class Param1, class Param2>
SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, MFP>
SH_CALL2(SourceHook::CallClass<Y> *ptr, MFP mfp, RetType(X::*mfp2)(Param1, Param2, ...)const)
{
return SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, MFP>(ptr, mfp);
}
// Support for 3 arguments
template <class X, class Y, class MFP, class RetType, class Param1, class Param2, class Param3>
SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, MFP>
SH_CALL2(SourceHook::CallClass<Y> *ptr, MFP mfp, RetType(X::*mfp2)(Param1, Param2, Param3, ...))
{
return SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, MFP>(ptr, mfp);
}
template <class X, class Y, class MFP, class RetType, class Param1, class Param2, class Param3>
SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, MFP>
SH_CALL2(SourceHook::CallClass<Y> *ptr, MFP mfp, RetType(X::*mfp2)(Param1, Param2, Param3, ...)const)
{
return SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, MFP>(ptr, mfp);
}
// Support for 4 arguments
template <class X, class Y, class MFP, class RetType, class Param1, class Param2, class Param3, class Param4>
SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, MFP>
SH_CALL2(SourceHook::CallClass<Y> *ptr, MFP mfp, RetType(X::*mfp2)(Param1, Param2, Param3, Param4, ...))
{
return SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, MFP>(ptr, mfp);
}
template <class X, class Y, class MFP, class RetType, class Param1, class Param2, class Param3, class Param4>
SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, MFP>
SH_CALL2(SourceHook::CallClass<Y> *ptr, MFP mfp, RetType(X::*mfp2)(Param1, Param2, Param3, Param4, ...)const)
{
return SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, MFP>(ptr, mfp);
}
// Support for 5 arguments
template <class X, class Y, class MFP, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5>
SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, MFP>
SH_CALL2(SourceHook::CallClass<Y> *ptr, MFP mfp, RetType(X::*mfp2)(Param1, Param2, Param3, Param4, Param5, ...))
{
return SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, MFP>(ptr, mfp);
}
template <class X, class Y, class MFP, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5>
SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, MFP>
SH_CALL2(SourceHook::CallClass<Y> *ptr, MFP mfp, RetType(X::*mfp2)(Param1, Param2, Param3, Param4, Param5, ...)const)
{
return SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, MFP>(ptr, mfp);
}
// Support for 6 arguments
template <class X, class Y, class MFP, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6>
SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, MFP>
SH_CALL2(SourceHook::CallClass<Y> *ptr, MFP mfp, RetType(X::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, ...))
{
return SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, MFP>(ptr, mfp);
}
template <class X, class Y, class MFP, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6>
SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, MFP>
SH_CALL2(SourceHook::CallClass<Y> *ptr, MFP mfp, RetType(X::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, ...)const)
{
return SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, MFP>(ptr, mfp);
}
// Support for 7 arguments
template <class X, class Y, class MFP, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7>
SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, MFP>
SH_CALL2(SourceHook::CallClass<Y> *ptr, MFP mfp, RetType(X::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, ...))
{
return SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, MFP>(ptr, mfp);
}
template <class X, class Y, class MFP, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7>
SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, MFP>
SH_CALL2(SourceHook::CallClass<Y> *ptr, MFP mfp, RetType(X::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, ...)const)
{
return SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, MFP>(ptr, mfp);
}
// Support for 8 arguments
template <class X, class Y, class MFP, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8>
SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, MFP>
SH_CALL2(SourceHook::CallClass<Y> *ptr, MFP mfp, RetType(X::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, ...))
{
return SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, MFP>(ptr, mfp);
}
template <class X, class Y, class MFP, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8>
SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, MFP>
SH_CALL2(SourceHook::CallClass<Y> *ptr, MFP mfp, RetType(X::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, ...)const)
{
return SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, MFP>(ptr, mfp);
}
// Support for 9 arguments
template <class X, class Y, class MFP, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8, class Param9>
SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, MFP>
SH_CALL2(SourceHook::CallClass<Y> *ptr, MFP mfp, RetType(X::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, ...))
{
return SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, MFP>(ptr, mfp);
}
template <class X, class Y, class MFP, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8, class Param9>
SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, MFP>
SH_CALL2(SourceHook::CallClass<Y> *ptr, MFP mfp, RetType(X::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, ...)const)
{
return SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, MFP>(ptr, mfp);
}
// Support for 10 arguments
template <class X, class Y, class MFP, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8, class Param9, class Param10>
SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, MFP>
SH_CALL2(SourceHook::CallClass<Y> *ptr, MFP mfp, RetType(X::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, ...))
{
return SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, MFP>(ptr, mfp);
}
template <class X, class Y, class MFP, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8, class Param9, class Param10>
SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, MFP>
SH_CALL2(SourceHook::CallClass<Y> *ptr, MFP mfp, RetType(X::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, ...)const)
{
return SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, MFP>(ptr, mfp);
}
// Support for 11 arguments
template <class X, class Y, class MFP, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8, class Param9, class Param10, class Param11>
SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, MFP>
SH_CALL2(SourceHook::CallClass<Y> *ptr, MFP mfp, RetType(X::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, ...))
{
return SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, MFP>(ptr, mfp);
}
template <class X, class Y, class MFP, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8, class Param9, class Param10, class Param11>
SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, MFP>
SH_CALL2(SourceHook::CallClass<Y> *ptr, MFP mfp, RetType(X::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, ...)const)
{
return SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, MFP>(ptr, mfp);
}
// Support for 12 arguments
template <class X, class Y, class MFP, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8, class Param9, class Param10, class Param11, class Param12>
SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, MFP>
SH_CALL2(SourceHook::CallClass<Y> *ptr, MFP mfp, RetType(X::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, ...))
{
return SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, MFP>(ptr, mfp);
}
template <class X, class Y, class MFP, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8, class Param9, class Param10, class Param11, class Param12>
SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, MFP>
SH_CALL2(SourceHook::CallClass<Y> *ptr, MFP mfp, RetType(X::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, ...)const)
{
return SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, MFP>(ptr, mfp);
}
// Support for 13 arguments
template <class X, class Y, class MFP, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8, class Param9, class Param10, class Param11, class Param12, class Param13>
SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, MFP>
SH_CALL2(SourceHook::CallClass<Y> *ptr, MFP mfp, RetType(X::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, ...))
{
return SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, MFP>(ptr, mfp);
}
template <class X, class Y, class MFP, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8, class Param9, class Param10, class Param11, class Param12, class Param13>
SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, MFP>
SH_CALL2(SourceHook::CallClass<Y> *ptr, MFP mfp, RetType(X::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, ...)const)
{
return SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, MFP>(ptr, mfp);
}
// Support for 14 arguments
template <class X, class Y, class MFP, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8, class Param9, class Param10, class Param11, class Param12, class Param13, class Param14>
SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, MFP>
SH_CALL2(SourceHook::CallClass<Y> *ptr, MFP mfp, RetType(X::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, ...))
{
return SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, MFP>(ptr, mfp);
}
template <class X, class Y, class MFP, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8, class Param9, class Param10, class Param11, class Param12, class Param13, class Param14>
SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, MFP>
SH_CALL2(SourceHook::CallClass<Y> *ptr, MFP mfp, RetType(X::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, ...)const)
{
return SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, MFP>(ptr, mfp);
}
// Support for 15 arguments
template <class X, class Y, class MFP, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8, class Param9, class Param10, class Param11, class Param12, class Param13, class Param14, class Param15>
SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, MFP>
SH_CALL2(SourceHook::CallClass<Y> *ptr, MFP mfp, RetType(X::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, ...))
{
return SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, MFP>(ptr, mfp);
}
template <class X, class Y, class MFP, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8, class Param9, class Param10, class Param11, class Param12, class Param13, class Param14, class Param15>
SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, MFP>
SH_CALL2(SourceHook::CallClass<Y> *ptr, MFP mfp, RetType(X::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, ...)const)
{
return SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, MFP>(ptr, mfp);
}
// Support for 16 arguments
template <class X, class Y, class MFP, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8, class Param9, class Param10, class Param11, class Param12, class Param13, class Param14, class Param15, class Param16>
SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, MFP>
SH_CALL2(SourceHook::CallClass<Y> *ptr, MFP mfp, RetType(X::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, Param16, ...))
{
return SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, MFP>(ptr, mfp);
}
template <class X, class Y, class MFP, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8, class Param9, class Param10, class Param11, class Param12, class Param13, class Param14, class Param15, class Param16>
SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, MFP>
SH_CALL2(SourceHook::CallClass<Y> *ptr, MFP mfp, RetType(X::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, Param16, ...)const)
{
return SourceHook::ExecutableClass<SourceHook::CallClass<Y>, RetType, MFP>(ptr, mfp);
}
#endif
#define SH_CALL(ptr, mfp) SH_CALL2((ptr), (mfp), (mfp))
#undef SH_MAKE_EXECUTABLECLASS_BODY

View File

@ -28,14 +28,16 @@ namespace SourceHook
*/
struct RemoveHookInfo
{
RemoveHookInfo(Plugin pplug, void *piface, HookManagerPubFunc phookman,
RemoveHookInfo(Plugin pplug, void *piface, int tpo, HookManagerPubFunc phookman,
ISHDelegate *phandler, bool ppost)
: plug(pplug), iface(piface), hookman(phookman), handler(phandler), post(ppost)
: plug(pplug), iface(piface), thisptr_offs(tpo),
hookman(phookman), handler(phandler), post(ppost)
{
}
Plugin plug;
void *iface;
int thisptr_offs;
HookManagerPubFunc hookman;
ISHDelegate *handler;
bool post;
@ -70,7 +72,10 @@ namespace SourceHook
const char *proto, int vtblofs, int vtblidx);
void ApplyCallClassPatch(CallClassInfo &cc, int vtbl_offs, int vtbl_idx, void *orig_entry);
void ApplyCallClassPatches(CallClassInfo &cc);
void ApplyCallClassPatches(void *ifaceptr, int vtbl_offs, int vtbl_idx, void *orig_entry);
void RemoveCallClassPatch(CallClassInfo &cc, int vtbl_offs, int vtbl_idx);
void RemoveCallClassPatches(void *ifaceptr, int vtbl_offs, int vtbl_idx);
META_RES m_Status, m_PrevRes, m_CurRes;
const void *m_OrigRet;
@ -80,6 +85,16 @@ namespace SourceHook
CSourceHookImpl();
~CSourceHookImpl();
/**
* @brief Returns the interface version
*/
int GetIfaceVersion();
/**
* @brief Returns the implemnetation version
*/
int GetImplVersion();
/**
* @brief Make sure that a plugin is not used by any other plugins anymore, and unregister all its hook managers
*/
@ -118,19 +133,6 @@ namespace SourceHook
*/
bool RemoveHook(Plugin plug, void *iface, int thisptr_offs, HookManagerPubFunc myHookMan, ISHDelegate *handler, bool post);
/**
* @brief Removes a hook.
*
* @return True if the function succeeded, false otherwise
*
* @param plug The unique identifier of the plugin that calls this function
* @param iface Already adjusted interface pointer
* @param myHookMan A hook manager function that should be capable of handling the function
* @param handler A pointer to a FastDelegate containing the hook handler
* @param post Set to true if you want a post handler
*/
bool RemoveHook(Plugin plug, void *iface, HookManagerPubFunc myHookMan, ISHDelegate *handler, bool post);
/**
* @brief Removes a hook.
*
@ -165,8 +167,9 @@ namespace SourceHook
* @brief Return a pointer to a callclass. Generate a new one if required.
*
* @param iface The interface pointer
* @param size Size of the class instance
*/
GenericCallClass *GetCallClass(void *iface);
GenericCallClass *GetCallClass(void *iface, size_t size);
/**
* @brief Release a callclass
@ -184,12 +187,12 @@ namespace SourceHook
//////////////////////////////////////////////////////////////////////////
// For hook managers
virtual META_RES &GetCurResRef(); //!< Gets the pointer to the current meta result
virtual META_RES &GetPrevResRef(); //!< Gets the pointer to the previous meta result
virtual META_RES &GetStatusRef(); //!< Gets the pointer to the status variable
virtual META_RES &GetCurResRef(); //!< Gets the reference to the current meta result
virtual META_RES &GetPrevResRef(); //!< Gets the reference to the previous meta result
virtual META_RES &GetStatusRef(); //!< Gets the reference to the status variable
virtual void* &GetIfacePtrRef(); //!< Gets the reference to the iface ptr
virtual void SetOrigRet(const void *ptr); //!< Sets the original return pointer
virtual void SetOverrideRet(const void *ptr); //!< Sets the override result pointer
virtual void SetIfacePtr(void *ptr); //!< Sets the interface this pointer
};
}

View File

@ -61,6 +61,7 @@ std::list<Test *> Test::ms_Tests;
DO_TEST(Basic);
DO_TEST(VafmtAndOverload);
DO_TEST(ThisPtrOffs);
int main(int argc, char *argv[])
{

View File

@ -248,6 +248,9 @@
<File
RelativePath="..\generate\FastDelegate.hxx">
</File>
<File
RelativePath="..\generate\sh_memfuncinfo.hxx">
</File>
<File
RelativePath="..\generate\sourcehook.hxx">
<FileConfiguration

View File

@ -13,8 +13,8 @@ namespace
// Hooking and callclass
MAKE_STATE(State_F1_Called);
MAKE_STATE(State_F1_PreHandler_Called);
MAKE_STATE(State_F1_PostHandler_Called);
MAKE_STATE_1(State_F1_PreHandler_Called, void*);
MAKE_STATE_1(State_F1_PostHandler_Called, void*);
MAKE_STATE_1(State_F1_HookAdded, bool);
MAKE_STATE(State_F1_HookRemoved);
MAKE_STATE(State_F1_CallClassGenerated);
@ -354,13 +354,13 @@ namespace
{
void Pre()
{
ADD_STATE(State_F1_PreHandler_Called);
ADD_STATE(State_F1_PreHandler_Called(reinterpret_cast<void*>(this)));
RETURN_META(g_F1Pre_WhatToDo);
}
void Post()
{
ADD_STATE(State_F1_PostHandler_Called);
ADD_STATE(State_F1_PostHandler_Called(reinterpret_cast<void*>(this)));
RETURN_META(g_F1Post_WhatToDo);
}
};
@ -440,7 +440,7 @@ bool TestBasic(std::string &error)
CHECK_STATES((&g_States,
new State_F1_HookAdded(true),
new State_F1_Called,
new State_F1_PreHandler_Called,
new State_F1_PreHandler_Called(&f1_handlers),
NULL), "Part 3");
// 4) Rerequest the callclass
@ -456,7 +456,7 @@ bool TestBasic(std::string &error)
new State_F1_CallClassReleased,
new State_F1_CallClassGenerated,
new State_F1_Called,
new State_F1_PreHandler_Called,
new State_F1_PreHandler_Called(&f1_handlers),
NULL), "Part 4");
// 5) Check ignore / supercede
@ -470,9 +470,9 @@ bool TestBasic(std::string &error)
CHECK_STATES((&g_States,
new State_F1_Called,
new State_F1_PreHandler_Called,
new State_F1_PreHandler_Called(&f1_handlers),
new State_F1_Called,
new State_F1_PreHandler_Called,
new State_F1_PreHandler_Called(&f1_handlers),
new State_F1_Called,
NULL), "Part 5");
@ -500,7 +500,7 @@ bool TestBasic(std::string &error)
new State_F1_HookAdded(true),
new State_F1_Called,
new State_F1_Called,
new State_F1_PostHandler_Called,
new State_F1_PostHandler_Called(&f1_handlers),
NULL), "Part 7");
// 8) And a pre hook again
@ -517,12 +517,12 @@ bool TestBasic(std::string &error)
CHECK_STATES((&g_States,
new State_F1_HookAdded(true),
new State_F1_Called,
new State_F1_PreHandler_Called,
new State_F1_PreHandler_Called(&f1_handlers),
new State_F1_Called,
new State_F1_PostHandler_Called,
new State_F1_PostHandler_Called(&f1_handlers),
new State_F1_Called,
new State_F1_PreHandler_Called,
new State_F1_PostHandler_Called,
new State_F1_PreHandler_Called(&f1_handlers),
new State_F1_PostHandler_Called(&f1_handlers),
NULL), "Part 8");
// 9) Remove all hooks

239
sourcehook/test/test3.cpp Normal file
View File

@ -0,0 +1,239 @@
#include <string>
#include "sourcehook_impl.h"
#include "testevents.h"
// TEST3
// Tests with inheritance / thisptroffsets
namespace
{
StateList g_States;
SourceHook::ISourceHook *g_SHPtr;
SourceHook::Plugin g_PLID;
MAKE_STATE_1(State_Func1_Called, void*); // param1: This pointer
MAKE_STATE_1(State_Func2_Called, void*); // param1: This pointer
MAKE_STATE_1(State_Func3_Called, void*); // param1: This pointer
MAKE_STATE_1(State_Func1H_Called, void*);
MAKE_STATE_1(State_Func2H_Called, void*);
MAKE_STATE_1(State_Func3H_Called, void*);
class Base1
{
int a;
public:
virtual void Func1()
{
ADD_STATE(State_Func1_Called(reinterpret_cast<void*>(this)));
}
};
class Base2
{
int b;
public:
virtual void Func2()
{
ADD_STATE(State_Func2_Called(reinterpret_cast<void*>(this)));
}
};
class Derived : public Base1, public Base2
{
int c;
public:
virtual void Func3()
{
ADD_STATE(State_Func3_Called(reinterpret_cast<void*>(this)));
}
};
SH_DECL_HOOK0_void(Derived, Func1, SH_NOATTRIB, 0);
SH_DECL_HOOK0_void(Derived, Func2, SH_NOATTRIB, 0);
SH_DECL_HOOK0_void(Derived, Func3, SH_NOATTRIB, 0);
SH_DECL_HOOK0_void(Base1, Func1, SH_NOATTRIB, 0);
SH_DECL_HOOK0_void(Base2, Func2, SH_NOATTRIB, 0);
void Handler_Func1()
{
ADD_STATE(State_Func1H_Called(reinterpret_cast<void*>(META_IFACEPTR)));
}
void Handler_Func2()
{
ADD_STATE(State_Func2H_Called(reinterpret_cast<void*>(META_IFACEPTR)));
}
void Handler_Func3()
{
ADD_STATE(State_Func3H_Called(reinterpret_cast<void*>(META_IFACEPTR)));
}
}
bool TestThisPtrOffs(std::string &error)
{
SourceHook::CSourceHookImpl g_SHImpl;
g_SHPtr = &g_SHImpl;
g_PLID = 1337;
Derived inst;
Derived *pD = &inst;
Base1 *pB1 = pD;
Base2 *pB2 = pD;
// It should be:
// pB1 = pD
// pB2 > pB1
// 1)
// Get a callclass for pD
// Verify whether the this pointers are correct
// Also call them normally to make sure that we aren't messing it up ;)
SourceHook::CallClass<Derived> *pD_CC = SH_GET_CALLCLASS(pD);
SH_CALL(pD_CC, &Derived::Func1)();
SH_CALL(pD_CC, &Derived::Func2)();
SH_CALL(pD_CC, &Derived::Func3)();
pD->Func1();
pD->Func2();
pD->Func3();
CHECK_STATES((&g_States,
new State_Func1_Called(pB1),
new State_Func2_Called(pB2),
new State_Func3_Called(pD),
new State_Func1_Called(pB1),
new State_Func2_Called(pB2),
new State_Func3_Called(pD),
NULL), "Part 1");
SH_CALL(pD_CC, &Base1::Func1)();
SH_CALL(pD_CC, &Base2::Func2)();
CHECK_STATES((&g_States,
new State_Func1_Called(pB1),
new State_Func2_Called(pB2),
NULL), "Part 1.1");
// 2)
// Get callclasses for the other ones and verify it as well
SourceHook::CallClass<Base1> *pB1_CC = SH_GET_CALLCLASS(pB1);
SourceHook::CallClass<Base2> *pB2_CC = SH_GET_CALLCLASS(pB2);
SH_CALL(pB1_CC, &Base1::Func1)();
SH_CALL(pB2_CC, &Base2::Func2)();
CHECK_STATES((&g_States,
new State_Func1_Called(pB1),
new State_Func2_Called(pB2),
NULL), "Part 2");
// 3) Add hooks on them (referring to them through pD1 / Derived)
// Check whether the hooks are called with the correct this pointer
SH_ADD_HOOK_STATICFUNC(Derived, Func1, pD, Handler_Func1, false);
SH_ADD_HOOK_STATICFUNC(Derived, Func2, pD, Handler_Func2, false);
SH_ADD_HOOK_STATICFUNC(Derived, Func3, pD, Handler_Func3, false);
pD->Func1();
pD->Func2();
pD->Func3();
pB1->Func1();
pB2->Func2();
// The handlers should always be called with the pointer to Derived
CHECK_STATES((&g_States,
new State_Func1H_Called(pD),
new State_Func1_Called(pB1),
new State_Func2H_Called(pD),
new State_Func2_Called(pB2),
new State_Func3H_Called(pD),
new State_Func3_Called(pD),
new State_Func1H_Called(pD),
new State_Func1_Called(pB1),
new State_Func2H_Called(pD),
new State_Func2_Called(pB2),
NULL), "Part 3");
SH_REMOVE_HOOK_STATICFUNC(Derived, Func1, pD, Handler_Func1, false);
SH_REMOVE_HOOK_STATICFUNC(Derived, Func2, pD, Handler_Func2, false);
SH_REMOVE_HOOK_STATICFUNC(Derived, Func3, pD, Handler_Func3, false);
// 4)
// Now add the hooks on Base1 and Base2 and check again
// Note that the new implicit_cast should convert the pD to Base1*/Base2* :)
SH_ADD_HOOK_STATICFUNC(Base1, Func1, pD, Handler_Func1, false);
SH_ADD_HOOK_STATICFUNC(Base2, Func2, pD, Handler_Func2, false);
SH_ADD_HOOK_STATICFUNC(Derived, Func3, pD, Handler_Func3, false);
pD->Func1();
pD->Func2();
pD->Func3();
pB1->Func1();
pB2->Func2();
// This time, the handlers for Func1 should be called with pB1 and the handlers
// for Func2 should be called with pB2
CHECK_STATES((&g_States,
new State_Func1H_Called(pB1),
new State_Func1_Called(pB1),
new State_Func2H_Called(pB2),
new State_Func2_Called(pB2),
new State_Func3H_Called(pD),
new State_Func3_Called(pD),
new State_Func1H_Called(pB1),
new State_Func1_Called(pB1),
new State_Func2H_Called(pB2),
new State_Func2_Called(pB2),
NULL), "Part 4");
SH_REMOVE_HOOK_STATICFUNC(Base1, Func1, pD, Handler_Func1, false);
SH_REMOVE_HOOK_STATICFUNC(Base2, Func2, pD, Handler_Func2, false);
SH_REMOVE_HOOK_STATICFUNC(Derived, Func3, pD, Handler_Func3, false);
// 5)
// Add some hooks, and use callclasses
// 5.1) First off, add all of them on pD
SH_ADD_HOOK_STATICFUNC(Derived, Func1, pD, Handler_Func1, false);
SH_ADD_HOOK_STATICFUNC(Derived, Func2, pD, Handler_Func2, false);
SH_ADD_HOOK_STATICFUNC(Derived, Func3, pD, Handler_Func3, false);
pD->Func1();
pD->Func2();
pD->Func3();
CHECK_STATES((&g_States,
new State_Func1H_Called(pD),
new State_Func1_Called(pB1),
new State_Func2H_Called(pD),
new State_Func2_Called(pB2),
new State_Func3H_Called(pD),
new State_Func3_Called(pD),
NULL), "Part 5.1");
SH_CALL(pD_CC, &Derived::Func1)();
SH_CALL(pD_CC, &Derived::Func2)();
SH_CALL(pD_CC, &Derived::Func3)();
SH_CALL(pB1_CC, &Base1::Func1)();
SH_CALL(pB2_CC, &Base2::Func2)();
CHECK_STATES((&g_States,
new State_Func1_Called(pB1),
new State_Func2_Called(pB2),
new State_Func3_Called(pD),
new State_Func1_Called(pB1),
new State_Func2_Called(pB2),
NULL), "Part 5.2");
SH_REMOVE_HOOK_STATICFUNC(Derived, Func1, pD, Handler_Func1, false);
SH_REMOVE_HOOK_STATICFUNC(Derived, Func2, pD, Handler_Func2, false);
SH_REMOVE_HOOK_STATICFUNC(Derived, Func3, pD, Handler_Func3, false);
SH_RELEASE_CALLCLASS(pB1_CC);
SH_RELEASE_CALLCLASS(pB2_CC);
SH_RELEASE_CALLCLASS(pD_CC);
return true;
}

View File

@ -1,3 +1,13 @@
/* ======== SourceHook ========
* Copyright (C) 2004-2005 Metamod:Source Development Team
* No warranties of any kind
*
* License: zlib/libpng
*
* Author(s): Pavol "PM OnoTo" Marko
* ============================
*/
#ifndef __TESTEVENTS_H__
#define __TESTEVENTS_H__