mirror of
https://github.com/alliedmodders/metamod-source.git
synced 2025-12-07 02:18:30 +00:00
Merged hookman_autogen into trunk
--HG-- extra : convert_revision : svn%3Ac2935e3e-5518-0410-8daf-afa5dab7d4e3/trunk%40581
This commit is contained in:
parent
12cb24aed8
commit
59bd50c69d
@ -35,6 +35,11 @@
|
||||
// 1 - standard
|
||||
#define SH_HOOKMAN_VERSION 1
|
||||
|
||||
// Hookmanautogen versions
|
||||
// 1 - initial
|
||||
#define SH_HOOKMANAUTOGEN_IFACE_VERSION 1
|
||||
#define SH_HOOKMANAUTOGEN_IMPL_VERSION 1
|
||||
|
||||
// The value of SH_GLOB_SHPTR has to be a pointer to SourceHook::ISourceHook
|
||||
// It's used in various macros
|
||||
#ifndef SH_GLOB_SHPTR
|
||||
@ -173,7 +178,13 @@ namespace SourceHook
|
||||
PassFlag_ODtor = (1<<2), /**< Object has a destructor */
|
||||
PassFlag_OCtor = (1<<3), /**< Object has a normal non-trivial constructor */
|
||||
PassFlag_AssignOp = (1<<4), /**< Object has a non-trivial assignment operator */
|
||||
PassFlag_CCtor = (1<<5) /**< Object has a copy constructor (which takes const Object& as only parameter) */
|
||||
PassFlag_CCtor = (1<<5), /**< Object has a copy constructor (which takes const Object& as only parameter) */
|
||||
|
||||
// The following two flags are only relevant for byval return types.
|
||||
// SH tries to auto-detect these
|
||||
// If you want to override SH's auto-detection, pass them in yourself
|
||||
PassFlag_RetMem = (1<<6), /**< Object is returned in memory (through hidden first param */
|
||||
PassFlag_RetReg = (1<<7) /**< Object is returned in EAX(:EDX) */
|
||||
};
|
||||
|
||||
size_t size; //!< Size of the data being passed
|
||||
@ -196,9 +207,13 @@ namespace SourceHook
|
||||
{
|
||||
enum CallConvention
|
||||
{
|
||||
CallConv_Unknown, /**< Unknown -- no extra info available */
|
||||
CallConv_ThisCall, /**< This call (object pointer required) */
|
||||
CallConv_Cdecl, /**< Standard C call */
|
||||
CallConv_Unknown, /**< Unknown -- no extra info available (0)*/
|
||||
CallConv_ThisCall, /**< This call (object pointer required) (1)*/
|
||||
CallConv_Cdecl, /**< C call (2)*/
|
||||
CallConv_StdCall, /**< Windows "stdcall" (3)*/
|
||||
|
||||
CallConv_HasVarArgs = (1<<16), /**< Has variable arguments */
|
||||
CallConv_HasVafmt = CallConv_HasVarArgs | (1<<17) /**< last params: const char*, ... */
|
||||
};
|
||||
|
||||
int numOfParams; //!< number of parameters
|
||||
@ -462,6 +477,17 @@ namespace SourceHook
|
||||
virtual void EndContext(IHookContext *pCtx) = 0;
|
||||
};
|
||||
|
||||
|
||||
class IHookManagerAutoGen
|
||||
{
|
||||
public:
|
||||
virtual int GetIfaceVersion() = 0;
|
||||
virtual int GetImplVersion() = 0;
|
||||
|
||||
virtual HookManagerPubFunc MakeHookMan(const ProtoInfo *proto, int vtbl_offs, int vtbl_idx) = 0;
|
||||
virtual void ReleaseHookMan(HookManagerPubFunc pubFunc) = 0;
|
||||
};
|
||||
|
||||
// For META_RESULT_ORIG_RET and META_RESULT_OVERRIDE_RET:
|
||||
// These have to be able to return references. If T is a reference, the pointers returned
|
||||
// from the SH_GLOB_SHPTR are pointers to instances of ReferenceCarrier<T>::type.
|
||||
@ -1014,7 +1040,7 @@ SourceHook::CallClass<T> *SH_GET_CALLCLASS(T *p)
|
||||
char buf[::SourceHook::STRBUF_LEN]; \
|
||||
va_list ap; \
|
||||
va_start(ap, fmt); \
|
||||
vsnprintf(buf, sizeof(buf) - 1, fmt, ap); \
|
||||
vsnprintf(buf, sizeof(buf), fmt, ap); \
|
||||
buf[sizeof(buf) - 1] = 0; \
|
||||
va_end(ap);
|
||||
|
||||
@ -6737,204 +6763,408 @@ namespace SourceHook
|
||||
return OverrideFunctor<RetType>();
|
||||
}
|
||||
|
||||
template <class Iface, class RetType>
|
||||
OverrideFunctor<RetType> SetOverrideResult(RetType (Iface::*mfp)(...))
|
||||
{
|
||||
return OverrideFunctor<RetType>();
|
||||
}
|
||||
|
||||
template <class Iface, class RetType>
|
||||
Iface *RecallGetIface(ISourceHook *shptr, RetType (Iface::*mfp)())
|
||||
{
|
||||
return reinterpret_cast<Iface*>(shptr->GetIfacePtr());
|
||||
}
|
||||
|
||||
template <class Iface, class RetType>
|
||||
Iface *RecallGetIface(ISourceHook *shptr, RetType (Iface::*mfp)(...))
|
||||
{
|
||||
return reinterpret_cast<Iface*>(shptr->GetIfacePtr());
|
||||
}
|
||||
|
||||
template <class Iface, class RetType, class Param1>
|
||||
OverrideFunctor<RetType> SetOverrideResult(RetType (Iface::*mfp)(Param1))
|
||||
{
|
||||
return OverrideFunctor<RetType>();
|
||||
}
|
||||
|
||||
template <class Iface, class RetType, class Param1>
|
||||
OverrideFunctor<RetType> SetOverrideResult(RetType (Iface::*mfp)(Param1, ...))
|
||||
{
|
||||
return OverrideFunctor<RetType>();
|
||||
}
|
||||
|
||||
template <class Iface, class RetType, class Param1>
|
||||
Iface *RecallGetIface(ISourceHook *shptr, RetType (Iface::*mfp)(Param1))
|
||||
{
|
||||
return reinterpret_cast<Iface*>(shptr->GetIfacePtr());
|
||||
}
|
||||
|
||||
template <class Iface, class RetType, class Param1>
|
||||
Iface *RecallGetIface(ISourceHook *shptr, RetType (Iface::*mfp)(Param1, ...))
|
||||
{
|
||||
return reinterpret_cast<Iface*>(shptr->GetIfacePtr());
|
||||
}
|
||||
|
||||
template <class Iface, class RetType, class Param1, class Param2>
|
||||
OverrideFunctor<RetType> SetOverrideResult(RetType (Iface::*mfp)(Param1, Param2))
|
||||
{
|
||||
return OverrideFunctor<RetType>();
|
||||
}
|
||||
|
||||
template <class Iface, class RetType, class Param1, class Param2>
|
||||
OverrideFunctor<RetType> SetOverrideResult(RetType (Iface::*mfp)(Param1, Param2, ...))
|
||||
{
|
||||
return OverrideFunctor<RetType>();
|
||||
}
|
||||
|
||||
template <class Iface, class RetType, class Param1, class Param2>
|
||||
Iface *RecallGetIface(ISourceHook *shptr, RetType (Iface::*mfp)(Param1, Param2))
|
||||
{
|
||||
return reinterpret_cast<Iface*>(shptr->GetIfacePtr());
|
||||
}
|
||||
|
||||
template <class Iface, class RetType, class Param1, class Param2>
|
||||
Iface *RecallGetIface(ISourceHook *shptr, RetType (Iface::*mfp)(Param1, Param2, ...))
|
||||
{
|
||||
return reinterpret_cast<Iface*>(shptr->GetIfacePtr());
|
||||
}
|
||||
|
||||
template <class Iface, class RetType, class Param1, class Param2, class Param3>
|
||||
OverrideFunctor<RetType> SetOverrideResult(RetType (Iface::*mfp)(Param1, Param2, Param3))
|
||||
{
|
||||
return OverrideFunctor<RetType>();
|
||||
}
|
||||
|
||||
template <class Iface, class RetType, class Param1, class Param2, class Param3>
|
||||
OverrideFunctor<RetType> SetOverrideResult(RetType (Iface::*mfp)(Param1, Param2, Param3, ...))
|
||||
{
|
||||
return OverrideFunctor<RetType>();
|
||||
}
|
||||
|
||||
template <class Iface, class RetType, class Param1, class Param2, class Param3>
|
||||
Iface *RecallGetIface(ISourceHook *shptr, RetType (Iface::*mfp)(Param1, Param2, Param3))
|
||||
{
|
||||
return reinterpret_cast<Iface*>(shptr->GetIfacePtr());
|
||||
}
|
||||
|
||||
template <class Iface, class RetType, class Param1, class Param2, class Param3>
|
||||
Iface *RecallGetIface(ISourceHook *shptr, RetType (Iface::*mfp)(Param1, Param2, Param3, ...))
|
||||
{
|
||||
return reinterpret_cast<Iface*>(shptr->GetIfacePtr());
|
||||
}
|
||||
|
||||
template <class Iface, class RetType, class Param1, class Param2, class Param3, class Param4>
|
||||
OverrideFunctor<RetType> SetOverrideResult(RetType (Iface::*mfp)(Param1, Param2, Param3, Param4))
|
||||
{
|
||||
return OverrideFunctor<RetType>();
|
||||
}
|
||||
|
||||
template <class Iface, class RetType, class Param1, class Param2, class Param3, class Param4>
|
||||
OverrideFunctor<RetType> SetOverrideResult(RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, ...))
|
||||
{
|
||||
return OverrideFunctor<RetType>();
|
||||
}
|
||||
|
||||
template <class Iface, class RetType, class Param1, class Param2, class Param3, class Param4>
|
||||
Iface *RecallGetIface(ISourceHook *shptr, RetType (Iface::*mfp)(Param1, Param2, Param3, Param4))
|
||||
{
|
||||
return reinterpret_cast<Iface*>(shptr->GetIfacePtr());
|
||||
}
|
||||
|
||||
template <class Iface, class RetType, class Param1, class Param2, class Param3, class Param4>
|
||||
Iface *RecallGetIface(ISourceHook *shptr, RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, ...))
|
||||
{
|
||||
return reinterpret_cast<Iface*>(shptr->GetIfacePtr());
|
||||
}
|
||||
|
||||
template <class Iface, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5>
|
||||
OverrideFunctor<RetType> SetOverrideResult(RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5))
|
||||
{
|
||||
return OverrideFunctor<RetType>();
|
||||
}
|
||||
|
||||
template <class Iface, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5>
|
||||
OverrideFunctor<RetType> SetOverrideResult(RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, ...))
|
||||
{
|
||||
return OverrideFunctor<RetType>();
|
||||
}
|
||||
|
||||
template <class Iface, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5>
|
||||
Iface *RecallGetIface(ISourceHook *shptr, RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5))
|
||||
{
|
||||
return reinterpret_cast<Iface*>(shptr->GetIfacePtr());
|
||||
}
|
||||
|
||||
template <class Iface, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5>
|
||||
Iface *RecallGetIface(ISourceHook *shptr, RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, ...))
|
||||
{
|
||||
return reinterpret_cast<Iface*>(shptr->GetIfacePtr());
|
||||
}
|
||||
|
||||
template <class Iface, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6>
|
||||
OverrideFunctor<RetType> SetOverrideResult(RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6))
|
||||
{
|
||||
return OverrideFunctor<RetType>();
|
||||
}
|
||||
|
||||
template <class Iface, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6>
|
||||
OverrideFunctor<RetType> SetOverrideResult(RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, ...))
|
||||
{
|
||||
return OverrideFunctor<RetType>();
|
||||
}
|
||||
|
||||
template <class Iface, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6>
|
||||
Iface *RecallGetIface(ISourceHook *shptr, RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6))
|
||||
{
|
||||
return reinterpret_cast<Iface*>(shptr->GetIfacePtr());
|
||||
}
|
||||
|
||||
template <class Iface, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6>
|
||||
Iface *RecallGetIface(ISourceHook *shptr, RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, ...))
|
||||
{
|
||||
return reinterpret_cast<Iface*>(shptr->GetIfacePtr());
|
||||
}
|
||||
|
||||
template <class Iface, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7>
|
||||
OverrideFunctor<RetType> SetOverrideResult(RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7))
|
||||
{
|
||||
return OverrideFunctor<RetType>();
|
||||
}
|
||||
|
||||
template <class Iface, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7>
|
||||
OverrideFunctor<RetType> SetOverrideResult(RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, ...))
|
||||
{
|
||||
return OverrideFunctor<RetType>();
|
||||
}
|
||||
|
||||
template <class Iface, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7>
|
||||
Iface *RecallGetIface(ISourceHook *shptr, RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7))
|
||||
{
|
||||
return reinterpret_cast<Iface*>(shptr->GetIfacePtr());
|
||||
}
|
||||
|
||||
template <class Iface, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7>
|
||||
Iface *RecallGetIface(ISourceHook *shptr, RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, ...))
|
||||
{
|
||||
return reinterpret_cast<Iface*>(shptr->GetIfacePtr());
|
||||
}
|
||||
|
||||
template <class Iface, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8>
|
||||
OverrideFunctor<RetType> SetOverrideResult(RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8))
|
||||
{
|
||||
return OverrideFunctor<RetType>();
|
||||
}
|
||||
|
||||
template <class Iface, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8>
|
||||
OverrideFunctor<RetType> SetOverrideResult(RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, ...))
|
||||
{
|
||||
return OverrideFunctor<RetType>();
|
||||
}
|
||||
|
||||
template <class Iface, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8>
|
||||
Iface *RecallGetIface(ISourceHook *shptr, RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8))
|
||||
{
|
||||
return reinterpret_cast<Iface*>(shptr->GetIfacePtr());
|
||||
}
|
||||
|
||||
template <class Iface, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8>
|
||||
Iface *RecallGetIface(ISourceHook *shptr, RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, ...))
|
||||
{
|
||||
return reinterpret_cast<Iface*>(shptr->GetIfacePtr());
|
||||
}
|
||||
|
||||
template <class Iface, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8, class Param9>
|
||||
OverrideFunctor<RetType> SetOverrideResult(RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9))
|
||||
{
|
||||
return OverrideFunctor<RetType>();
|
||||
}
|
||||
|
||||
template <class Iface, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8, class Param9>
|
||||
OverrideFunctor<RetType> SetOverrideResult(RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, ...))
|
||||
{
|
||||
return OverrideFunctor<RetType>();
|
||||
}
|
||||
|
||||
template <class Iface, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8, class Param9>
|
||||
Iface *RecallGetIface(ISourceHook *shptr, RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9))
|
||||
{
|
||||
return reinterpret_cast<Iface*>(shptr->GetIfacePtr());
|
||||
}
|
||||
|
||||
template <class Iface, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8, class Param9>
|
||||
Iface *RecallGetIface(ISourceHook *shptr, RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, ...))
|
||||
{
|
||||
return reinterpret_cast<Iface*>(shptr->GetIfacePtr());
|
||||
}
|
||||
|
||||
template <class Iface, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8, class Param9, class Param10>
|
||||
OverrideFunctor<RetType> SetOverrideResult(RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10))
|
||||
{
|
||||
return OverrideFunctor<RetType>();
|
||||
}
|
||||
|
||||
template <class Iface, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8, class Param9, class Param10>
|
||||
OverrideFunctor<RetType> SetOverrideResult(RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, ...))
|
||||
{
|
||||
return OverrideFunctor<RetType>();
|
||||
}
|
||||
|
||||
template <class Iface, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8, class Param9, class Param10>
|
||||
Iface *RecallGetIface(ISourceHook *shptr, RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10))
|
||||
{
|
||||
return reinterpret_cast<Iface*>(shptr->GetIfacePtr());
|
||||
}
|
||||
|
||||
template <class Iface, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8, class Param9, class Param10>
|
||||
Iface *RecallGetIface(ISourceHook *shptr, RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, ...))
|
||||
{
|
||||
return reinterpret_cast<Iface*>(shptr->GetIfacePtr());
|
||||
}
|
||||
|
||||
template <class Iface, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8, class Param9, class Param10, class Param11>
|
||||
OverrideFunctor<RetType> SetOverrideResult(RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11))
|
||||
{
|
||||
return OverrideFunctor<RetType>();
|
||||
}
|
||||
|
||||
template <class Iface, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8, class Param9, class Param10, class Param11>
|
||||
OverrideFunctor<RetType> SetOverrideResult(RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, ...))
|
||||
{
|
||||
return OverrideFunctor<RetType>();
|
||||
}
|
||||
|
||||
template <class Iface, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8, class Param9, class Param10, class Param11>
|
||||
Iface *RecallGetIface(ISourceHook *shptr, RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11))
|
||||
{
|
||||
return reinterpret_cast<Iface*>(shptr->GetIfacePtr());
|
||||
}
|
||||
|
||||
template <class Iface, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8, class Param9, class Param10, class Param11>
|
||||
Iface *RecallGetIface(ISourceHook *shptr, RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, ...))
|
||||
{
|
||||
return reinterpret_cast<Iface*>(shptr->GetIfacePtr());
|
||||
}
|
||||
|
||||
template <class Iface, 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>
|
||||
OverrideFunctor<RetType> SetOverrideResult(RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12))
|
||||
{
|
||||
return OverrideFunctor<RetType>();
|
||||
}
|
||||
|
||||
template <class Iface, 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>
|
||||
OverrideFunctor<RetType> SetOverrideResult(RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, ...))
|
||||
{
|
||||
return OverrideFunctor<RetType>();
|
||||
}
|
||||
|
||||
template <class Iface, 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>
|
||||
Iface *RecallGetIface(ISourceHook *shptr, RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12))
|
||||
{
|
||||
return reinterpret_cast<Iface*>(shptr->GetIfacePtr());
|
||||
}
|
||||
|
||||
template <class Iface, 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>
|
||||
Iface *RecallGetIface(ISourceHook *shptr, RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, ...))
|
||||
{
|
||||
return reinterpret_cast<Iface*>(shptr->GetIfacePtr());
|
||||
}
|
||||
|
||||
template <class Iface, 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>
|
||||
OverrideFunctor<RetType> SetOverrideResult(RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13))
|
||||
{
|
||||
return OverrideFunctor<RetType>();
|
||||
}
|
||||
|
||||
template <class Iface, 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>
|
||||
OverrideFunctor<RetType> SetOverrideResult(RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, ...))
|
||||
{
|
||||
return OverrideFunctor<RetType>();
|
||||
}
|
||||
|
||||
template <class Iface, 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>
|
||||
Iface *RecallGetIface(ISourceHook *shptr, RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13))
|
||||
{
|
||||
return reinterpret_cast<Iface*>(shptr->GetIfacePtr());
|
||||
}
|
||||
|
||||
template <class Iface, 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>
|
||||
Iface *RecallGetIface(ISourceHook *shptr, RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, ...))
|
||||
{
|
||||
return reinterpret_cast<Iface*>(shptr->GetIfacePtr());
|
||||
}
|
||||
|
||||
template <class Iface, 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>
|
||||
OverrideFunctor<RetType> SetOverrideResult(RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14))
|
||||
{
|
||||
return OverrideFunctor<RetType>();
|
||||
}
|
||||
|
||||
template <class Iface, 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>
|
||||
OverrideFunctor<RetType> SetOverrideResult(RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, ...))
|
||||
{
|
||||
return OverrideFunctor<RetType>();
|
||||
}
|
||||
|
||||
template <class Iface, 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>
|
||||
Iface *RecallGetIface(ISourceHook *shptr, RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14))
|
||||
{
|
||||
return reinterpret_cast<Iface*>(shptr->GetIfacePtr());
|
||||
}
|
||||
|
||||
template <class Iface, 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>
|
||||
Iface *RecallGetIface(ISourceHook *shptr, RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, ...))
|
||||
{
|
||||
return reinterpret_cast<Iface*>(shptr->GetIfacePtr());
|
||||
}
|
||||
|
||||
template <class Iface, 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>
|
||||
OverrideFunctor<RetType> SetOverrideResult(RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15))
|
||||
{
|
||||
return OverrideFunctor<RetType>();
|
||||
}
|
||||
|
||||
template <class Iface, 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>
|
||||
OverrideFunctor<RetType> SetOverrideResult(RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, ...))
|
||||
{
|
||||
return OverrideFunctor<RetType>();
|
||||
}
|
||||
|
||||
template <class Iface, 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>
|
||||
Iface *RecallGetIface(ISourceHook *shptr, RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15))
|
||||
{
|
||||
return reinterpret_cast<Iface*>(shptr->GetIfacePtr());
|
||||
}
|
||||
|
||||
template <class Iface, 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>
|
||||
Iface *RecallGetIface(ISourceHook *shptr, RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, ...))
|
||||
{
|
||||
return reinterpret_cast<Iface*>(shptr->GetIfacePtr());
|
||||
}
|
||||
|
||||
template <class Iface, 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>
|
||||
OverrideFunctor<RetType> SetOverrideResult(RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, Param16))
|
||||
{
|
||||
return OverrideFunctor<RetType>();
|
||||
}
|
||||
|
||||
template <class Iface, 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>
|
||||
OverrideFunctor<RetType> SetOverrideResult(RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, Param16, ...))
|
||||
{
|
||||
return OverrideFunctor<RetType>();
|
||||
}
|
||||
|
||||
template <class Iface, 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>
|
||||
Iface *RecallGetIface(ISourceHook *shptr, RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, Param16))
|
||||
{
|
||||
return reinterpret_cast<Iface*>(shptr->GetIfacePtr());
|
||||
}
|
||||
|
||||
template <class Iface, 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>
|
||||
Iface *RecallGetIface(ISourceHook *shptr, RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, Param16, ...))
|
||||
{
|
||||
return reinterpret_cast<Iface*>(shptr->GetIfacePtr());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@ -35,6 +35,11 @@
|
||||
// 1 - standard
|
||||
#define SH_HOOKMAN_VERSION 1
|
||||
|
||||
// Hookmanautogen versions
|
||||
// 1 - initial
|
||||
#define SH_HOOKMANAUTOGEN_IFACE_VERSION 1
|
||||
#define SH_HOOKMANAUTOGEN_IMPL_VERSION 1
|
||||
|
||||
// The value of SH_GLOB_SHPTR has to be a pointer to SourceHook::ISourceHook
|
||||
// It's used in various macros
|
||||
#ifndef SH_GLOB_SHPTR
|
||||
@ -173,7 +178,13 @@ namespace SourceHook
|
||||
PassFlag_ODtor = (1<<2), /**< Object has a destructor */
|
||||
PassFlag_OCtor = (1<<3), /**< Object has a normal non-trivial constructor */
|
||||
PassFlag_AssignOp = (1<<4), /**< Object has a non-trivial assignment operator */
|
||||
PassFlag_CCtor = (1<<5) /**< Object has a copy constructor (which takes const Object& as only parameter) */
|
||||
PassFlag_CCtor = (1<<5), /**< Object has a copy constructor (which takes const Object& as only parameter) */
|
||||
|
||||
// The following two flags are only relevant for byval return types.
|
||||
// SH tries to auto-detect these
|
||||
// If you want to override SH's auto-detection, pass them in yourself
|
||||
PassFlag_RetMem = (1<<6), /**< Object is returned in memory (through hidden first param */
|
||||
PassFlag_RetReg = (1<<7) /**< Object is returned in EAX(:EDX) */
|
||||
};
|
||||
|
||||
size_t size; //!< Size of the data being passed
|
||||
@ -196,9 +207,13 @@ namespace SourceHook
|
||||
{
|
||||
enum CallConvention
|
||||
{
|
||||
CallConv_Unknown, /**< Unknown -- no extra info available */
|
||||
CallConv_ThisCall, /**< This call (object pointer required) */
|
||||
CallConv_Cdecl, /**< Standard C call */
|
||||
CallConv_Unknown, /**< Unknown -- no extra info available (0)*/
|
||||
CallConv_ThisCall, /**< This call (object pointer required) (1)*/
|
||||
CallConv_Cdecl, /**< C call (2)*/
|
||||
CallConv_StdCall, /**< Windows "stdcall" (3)*/
|
||||
|
||||
CallConv_HasVarArgs = (1<<16), /**< Has variable arguments */
|
||||
CallConv_HasVafmt = CallConv_HasVarArgs | (1<<17) /**< last params: const char*, ... */
|
||||
};
|
||||
|
||||
int numOfParams; //!< number of parameters
|
||||
@ -462,6 +477,17 @@ namespace SourceHook
|
||||
virtual void EndContext(IHookContext *pCtx) = 0;
|
||||
};
|
||||
|
||||
|
||||
class IHookManagerAutoGen
|
||||
{
|
||||
public:
|
||||
virtual int GetIfaceVersion() = 0;
|
||||
virtual int GetImplVersion() = 0;
|
||||
|
||||
virtual HookManagerPubFunc MakeHookMan(const ProtoInfo *proto, int vtbl_offs, int vtbl_idx) = 0;
|
||||
virtual void ReleaseHookMan(HookManagerPubFunc pubFunc) = 0;
|
||||
};
|
||||
|
||||
// For META_RESULT_ORIG_RET and META_RESULT_OVERRIDE_RET:
|
||||
// These have to be able to return references. If T is a reference, the pointers returned
|
||||
// from the SH_GLOB_SHPTR are pointers to instances of ReferenceCarrier<T>::type.
|
||||
@ -1014,7 +1040,7 @@ SourceHook::CallClass<T> *SH_GET_CALLCLASS(T *p)
|
||||
char buf[::SourceHook::STRBUF_LEN]; \
|
||||
va_list ap; \
|
||||
va_start(ap, fmt); \
|
||||
vsnprintf(buf, sizeof(buf) - 1, fmt, ap); \
|
||||
vsnprintf(buf, sizeof(buf), fmt, ap); \
|
||||
buf[sizeof(buf) - 1] = 0; \
|
||||
va_end(ap);
|
||||
|
||||
@ -1415,11 +1441,23 @@ namespace SourceHook
|
||||
return OverrideFunctor<RetType>();
|
||||
}
|
||||
|
||||
template <class Iface, class RetType@[$2,1,$1:, class Param$2@]>
|
||||
OverrideFunctor<RetType> SetOverrideResult(RetType (Iface::*mfp)(@[$2,1,$1:Param$2, @]...))
|
||||
{
|
||||
return OverrideFunctor<RetType>();
|
||||
}
|
||||
|
||||
template <class Iface, class RetType@[$2,1,$1:, class Param$2@]>
|
||||
Iface *RecallGetIface(ISourceHook *shptr, RetType (Iface::*mfp)(@[$2,1,$1|, :Param$2@]))
|
||||
{
|
||||
return reinterpret_cast<Iface*>(shptr->GetIfacePtr());
|
||||
}
|
||||
|
||||
template <class Iface, class RetType@[$2,1,$1:, class Param$2@]>
|
||||
Iface *RecallGetIface(ISourceHook *shptr, RetType (Iface::*mfp)(@[$2,1,$1:Param$2, @]...))
|
||||
{
|
||||
return reinterpret_cast<Iface*>(shptr->GetIfacePtr());
|
||||
}
|
||||
@]
|
||||
}
|
||||
|
||||
|
||||
@ -103,6 +103,20 @@ namespace SourceHook
|
||||
insert(begin(), obj);
|
||||
}
|
||||
|
||||
void push_sorted(const T &obj)
|
||||
{
|
||||
iterator iter;
|
||||
for (iter = begin(); iter != end(); ++iter)
|
||||
{
|
||||
if (obj < *iter)
|
||||
{
|
||||
insert(iter, obj);
|
||||
return;
|
||||
}
|
||||
}
|
||||
push_back(obj);
|
||||
}
|
||||
|
||||
size_t size() const
|
||||
{
|
||||
return m_Size;
|
||||
@ -301,6 +315,7 @@ namespace SourceHook
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
}; //NAMESPACE
|
||||
|
||||
#endif //_INCLUDE_CSDM_LIST_H
|
||||
|
||||
@ -38,11 +38,12 @@
|
||||
// We need to align addr down to pagesize on linux
|
||||
// We assume PAGESIZE is a power of two
|
||||
# define SH_LALIGN(x) (void*)((intptr_t)(x) & ~(PAGESIZE-1))
|
||||
# define SH_LALDIF(x) ((intptr_t)(x) & (PAGESIZE-1))
|
||||
# define SH_LALDIF(x) ((intptr_t)(x) % PAGESIZE)
|
||||
# else
|
||||
# error Unsupported OS/Compiler
|
||||
# endif
|
||||
|
||||
#include "sh_list.h"
|
||||
|
||||
namespace SourceHook
|
||||
{
|
||||
|
||||
288
sourcehook/sh_pagealloc.h
Normal file
288
sourcehook/sh_pagealloc.h
Normal file
@ -0,0 +1,288 @@
|
||||
#ifndef __SH_PAGEALLOC_H__
|
||||
#define __SH_PAGEALLOC_H__
|
||||
|
||||
# if /********/ defined _WIN32
|
||||
# include <windows.h>
|
||||
# elif /******/ defined __linux__
|
||||
# include <sys/mman.h>
|
||||
# include <unistd.h>
|
||||
# else
|
||||
# error Unsupported OS/Compiler
|
||||
# endif
|
||||
|
||||
|
||||
namespace SourceHook
|
||||
{
|
||||
|
||||
/*
|
||||
Class which lets us allocate memory regions in special pages only meant for on the fly code generation.
|
||||
|
||||
If we alloc with malloc and then set the page access type to read/exec only, other regions returned by
|
||||
malloc that are in the same page would lose their write access as well and the process could crash.
|
||||
|
||||
Allocating one page per code generation session is usually a waste of memory and on some platforms also
|
||||
a waste of virtual address space (Windows’ VirtualAlloc has a granularity of 64K).
|
||||
|
||||
|
||||
IMPORTANT: the memory that Alloc() returns is not a in a defined state!
|
||||
It could be in read+exec OR read+write mode.
|
||||
-> call SetRE() or SetRW() before using allocated memory!
|
||||
*/
|
||||
class CPageAlloc
|
||||
{
|
||||
struct AllocationUnit
|
||||
{
|
||||
size_t begin_offset;
|
||||
size_t size;
|
||||
|
||||
AllocationUnit(size_t p_offs, size_t p_size) : begin_offset(p_offs), size(p_size)
|
||||
{
|
||||
}
|
||||
|
||||
bool operator < (const AllocationUnit &other) const
|
||||
{
|
||||
return begin_offset < other.begin_offset;
|
||||
}
|
||||
};
|
||||
|
||||
typedef List<AllocationUnit> AUList;
|
||||
struct AllocatedRegion
|
||||
{
|
||||
void *startPtr;
|
||||
size_t size;
|
||||
bool isolated; // may contain only one AU
|
||||
size_t minAlignment;
|
||||
AUList allocUnits;
|
||||
|
||||
void CheckGap(size_t gap_begin, size_t gap_end, size_t reqsize,
|
||||
size_t &smallestgap_pos, size_t &smallestgap_size, size_t &outAlignBytes)
|
||||
{
|
||||
size_t gapsize = gap_end - gap_begin;
|
||||
// How many bytes do we actually need here?
|
||||
// = requested size + alignment bytes
|
||||
size_t neededSize = reqsize;
|
||||
size_t alignBytes = minAlignment - ((reinterpret_cast<intptr_t>(startPtr) + gap_begin) % minAlignment);
|
||||
|
||||
alignBytes %= minAlignment;
|
||||
neededSize += alignBytes;
|
||||
|
||||
if (gapsize >= neededSize)
|
||||
{
|
||||
if (gapsize < smallestgap_size)
|
||||
{
|
||||
smallestgap_size = gapsize;
|
||||
smallestgap_pos = gap_begin;
|
||||
outAlignBytes = alignBytes;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool TryAlloc(size_t reqsize, void * &outAddr)
|
||||
{
|
||||
// Check for isolated
|
||||
if (isolated && !allocUnits.empty())
|
||||
return false;
|
||||
|
||||
// Find the smallest gap where req fits
|
||||
size_t lastend = 0;
|
||||
size_t smallestgap_pos = size + 1;
|
||||
size_t smallestgap_size = size + 1;
|
||||
size_t alignmentbytes = 0;
|
||||
|
||||
for (AUList::iterator iter = allocUnits.begin(); iter != allocUnits.end(); ++iter)
|
||||
{
|
||||
CheckGap(lastend, iter->begin_offset, reqsize, smallestgap_pos, smallestgap_size, alignmentbytes);
|
||||
lastend = iter->begin_offset + iter->size;
|
||||
}
|
||||
|
||||
CheckGap(lastend, size, reqsize, smallestgap_pos, smallestgap_size, alignmentbytes);
|
||||
|
||||
if (smallestgap_pos < size)
|
||||
{
|
||||
outAddr = reinterpret_cast<void*>(reinterpret_cast<char*>(startPtr) + smallestgap_pos + alignmentbytes);
|
||||
allocUnits.push_sorted( AllocationUnit(smallestgap_pos, reqsize + alignmentbytes) );
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool TryFree(void *addr)
|
||||
{
|
||||
if (addr < startPtr || addr >= reinterpret_cast<void*>(reinterpret_cast<char*>(startPtr) + size))
|
||||
return false;
|
||||
|
||||
intptr_t start = reinterpret_cast<intptr_t>(startPtr);
|
||||
|
||||
for (AUList::iterator iter = allocUnits.begin(); iter != allocUnits.end(); ++iter)
|
||||
{
|
||||
size_t AUBegin = start + iter->begin_offset;
|
||||
void *alignedAUBegin = reinterpret_cast<void*>(
|
||||
AUBegin + ((minAlignment - AUBegin % minAlignment) % minAlignment)
|
||||
);
|
||||
|
||||
if (addr == alignedAUBegin)
|
||||
{
|
||||
allocUnits.erase(iter);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Contains(void *addr)
|
||||
{
|
||||
return addr >= startPtr && addr < reinterpret_cast<void*>(reinterpret_cast<char*>(startPtr) + size);
|
||||
}
|
||||
|
||||
void FreeRegion()
|
||||
{
|
||||
#ifdef __linux__
|
||||
munmap(startPtr, size);
|
||||
#else
|
||||
VirtualFree(startPtr, 0, MEM_RELEASE);
|
||||
#endif
|
||||
}
|
||||
};
|
||||
|
||||
typedef List<AllocatedRegion> ARList;
|
||||
|
||||
size_t m_MinAlignment;
|
||||
size_t m_PageSize;
|
||||
ARList m_Regions;
|
||||
|
||||
bool AddRegion(size_t minSize, bool isolated)
|
||||
{
|
||||
AllocatedRegion newRegion;
|
||||
newRegion.startPtr = 0;
|
||||
newRegion.isolated = isolated;
|
||||
newRegion.minAlignment = m_MinAlignment;
|
||||
|
||||
// Compute real size -> align up to m_PageSize boundary
|
||||
|
||||
newRegion.size = minSize - (minSize % m_PageSize);
|
||||
if (newRegion.size < minSize)
|
||||
newRegion.size += m_PageSize;
|
||||
|
||||
#ifdef __linux__
|
||||
newRegion.startPtr = mmap(0, newRegion.size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
|
||||
#else
|
||||
newRegion.startPtr = VirtualAlloc(NULL, newRegion.size, MEM_COMMIT, PAGE_READWRITE);
|
||||
#endif
|
||||
|
||||
if (newRegion.startPtr)
|
||||
{
|
||||
m_Regions.push_back(newRegion);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void *AllocPriv(size_t size, bool isolated)
|
||||
{
|
||||
void *addr;
|
||||
|
||||
if (!isolated)
|
||||
{
|
||||
for (ARList::iterator iter = m_Regions.begin(); iter != m_Regions.end(); ++iter)
|
||||
{
|
||||
if (iter->TryAlloc(size, addr))
|
||||
return addr;
|
||||
}
|
||||
}
|
||||
|
||||
if (!AddRegion(size, isolated))
|
||||
return NULL;
|
||||
|
||||
bool tmp = m_Regions.back().TryAlloc(size, addr);
|
||||
SH_ASSERT(tmp, ("TryAlloc fails after AddRegion"));
|
||||
return tmp ? addr : NULL;
|
||||
}
|
||||
|
||||
public:
|
||||
CPageAlloc(size_t minAlignment = 1 /* power of 2 */ ) : m_MinAlignment(minAlignment)
|
||||
{
|
||||
#ifdef __linux__
|
||||
m_PageSize = sysconf(_SC_PAGESIZE);
|
||||
#else
|
||||
SYSTEM_INFO sysInfo;
|
||||
GetSystemInfo(&sysInfo);
|
||||
m_PageSize = sysInfo.dwPageSize;
|
||||
#endif
|
||||
}
|
||||
|
||||
~CPageAlloc()
|
||||
{
|
||||
// Free all regions
|
||||
for (ARList::iterator iter = m_Regions.begin(); iter != m_Regions.end(); ++iter)
|
||||
{
|
||||
iter->FreeRegion();
|
||||
}
|
||||
}
|
||||
|
||||
void *Alloc(size_t size)
|
||||
{
|
||||
return AllocPriv(size, false);
|
||||
}
|
||||
|
||||
void *AllocIsolated(size_t size)
|
||||
{
|
||||
return AllocPriv(size, true);
|
||||
}
|
||||
|
||||
void Free(void *ptr)
|
||||
{
|
||||
for (ARList::iterator iter = m_Regions.begin(); iter != m_Regions.end(); ++iter)
|
||||
{
|
||||
if (iter->TryFree(ptr))
|
||||
{
|
||||
if (iter->allocUnits.empty())
|
||||
{
|
||||
iter->FreeRegion();
|
||||
m_Regions.erase(iter);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SetRE(void *ptr)
|
||||
{
|
||||
for (ARList::iterator iter = m_Regions.begin(); iter != m_Regions.end(); ++iter)
|
||||
{
|
||||
if (iter->Contains(ptr))
|
||||
{
|
||||
SetMemAccess(iter->startPtr, iter->size, SH_MEM_READ | SH_MEM_EXEC);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SetRW(void *ptr)
|
||||
{
|
||||
for (ARList::iterator iter = m_Regions.begin(); iter != m_Regions.end(); ++iter)
|
||||
{
|
||||
if (iter->Contains(ptr))
|
||||
{
|
||||
SetMemAccess(iter->startPtr, iter->size, SH_MEM_READ | SH_MEM_WRITE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
size_t GetPageSize()
|
||||
{
|
||||
return m_PageSize;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@ -151,6 +151,25 @@ namespace SourceHook
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CProto::ExactlyEqual(const CProto &other) const
|
||||
{
|
||||
if (m_Version != other.m_Version ||
|
||||
m_NumOfParams != other.m_NumOfParams ||
|
||||
m_Convention != other.m_Convention ||
|
||||
GetRet() != other.GetRet())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
for (int i = 0; i < m_NumOfParams; ++i)
|
||||
{
|
||||
if(GetParam(i) != other.GetParam(i))
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// CHookManager
|
||||
|
||||
@ -35,6 +35,11 @@
|
||||
// 1 - standard
|
||||
#define SH_HOOKMAN_VERSION 1
|
||||
|
||||
// Hookmanautogen versions
|
||||
// 1 - initial
|
||||
#define SH_HOOKMANAUTOGEN_IFACE_VERSION 1
|
||||
#define SH_HOOKMANAUTOGEN_IMPL_VERSION 1
|
||||
|
||||
// The value of SH_GLOB_SHPTR has to be a pointer to SourceHook::ISourceHook
|
||||
// It's used in various macros
|
||||
#ifndef SH_GLOB_SHPTR
|
||||
@ -173,7 +178,13 @@ namespace SourceHook
|
||||
PassFlag_ODtor = (1<<2), /**< Object has a destructor */
|
||||
PassFlag_OCtor = (1<<3), /**< Object has a normal non-trivial constructor */
|
||||
PassFlag_AssignOp = (1<<4), /**< Object has a non-trivial assignment operator */
|
||||
PassFlag_CCtor = (1<<5) /**< Object has a copy constructor (which takes const Object& as only parameter) */
|
||||
PassFlag_CCtor = (1<<5), /**< Object has a copy constructor (which takes const Object& as only parameter) */
|
||||
|
||||
// The following two flags are only relevant for byval return types.
|
||||
// SH tries to auto-detect these
|
||||
// If you want to override SH's auto-detection, pass them in yourself
|
||||
PassFlag_RetMem = (1<<6), /**< Object is returned in memory (through hidden first param */
|
||||
PassFlag_RetReg = (1<<7) /**< Object is returned in EAX(:EDX) */
|
||||
};
|
||||
|
||||
size_t size; //!< Size of the data being passed
|
||||
@ -196,9 +207,13 @@ namespace SourceHook
|
||||
{
|
||||
enum CallConvention
|
||||
{
|
||||
CallConv_Unknown, /**< Unknown -- no extra info available */
|
||||
CallConv_ThisCall, /**< This call (object pointer required) */
|
||||
CallConv_Cdecl, /**< Standard C call */
|
||||
CallConv_Unknown, /**< Unknown -- no extra info available (0)*/
|
||||
CallConv_ThisCall, /**< This call (object pointer required) (1)*/
|
||||
CallConv_Cdecl, /**< C call (2)*/
|
||||
CallConv_StdCall, /**< Windows "stdcall" (3)*/
|
||||
|
||||
CallConv_HasVarArgs = (1<<16), /**< Has variable arguments */
|
||||
CallConv_HasVafmt = CallConv_HasVarArgs | (1<<17) /**< last params: const char*, ... */
|
||||
};
|
||||
|
||||
int numOfParams; //!< number of parameters
|
||||
@ -462,6 +477,17 @@ namespace SourceHook
|
||||
virtual void EndContext(IHookContext *pCtx) = 0;
|
||||
};
|
||||
|
||||
|
||||
class IHookManagerAutoGen
|
||||
{
|
||||
public:
|
||||
virtual int GetIfaceVersion() = 0;
|
||||
virtual int GetImplVersion() = 0;
|
||||
|
||||
virtual HookManagerPubFunc MakeHookMan(const ProtoInfo *proto, int vtbl_offs, int vtbl_idx) = 0;
|
||||
virtual void ReleaseHookMan(HookManagerPubFunc pubFunc) = 0;
|
||||
};
|
||||
|
||||
// For META_RESULT_ORIG_RET and META_RESULT_OVERRIDE_RET:
|
||||
// These have to be able to return references. If T is a reference, the pointers returned
|
||||
// from the SH_GLOB_SHPTR are pointers to instances of ReferenceCarrier<T>::type.
|
||||
@ -1014,7 +1040,7 @@ SourceHook::CallClass<T> *SH_GET_CALLCLASS(T *p)
|
||||
char buf[::SourceHook::STRBUF_LEN]; \
|
||||
va_list ap; \
|
||||
va_start(ap, fmt); \
|
||||
vsnprintf(buf, sizeof(buf) - 1, fmt, ap); \
|
||||
vsnprintf(buf, sizeof(buf), fmt, ap); \
|
||||
buf[sizeof(buf) - 1] = 0; \
|
||||
va_end(ap);
|
||||
|
||||
@ -6737,204 +6763,408 @@ namespace SourceHook
|
||||
return OverrideFunctor<RetType>();
|
||||
}
|
||||
|
||||
template <class Iface, class RetType>
|
||||
OverrideFunctor<RetType> SetOverrideResult(RetType (Iface::*mfp)(...))
|
||||
{
|
||||
return OverrideFunctor<RetType>();
|
||||
}
|
||||
|
||||
template <class Iface, class RetType>
|
||||
Iface *RecallGetIface(ISourceHook *shptr, RetType (Iface::*mfp)())
|
||||
{
|
||||
return reinterpret_cast<Iface*>(shptr->GetIfacePtr());
|
||||
}
|
||||
|
||||
template <class Iface, class RetType>
|
||||
Iface *RecallGetIface(ISourceHook *shptr, RetType (Iface::*mfp)(...))
|
||||
{
|
||||
return reinterpret_cast<Iface*>(shptr->GetIfacePtr());
|
||||
}
|
||||
|
||||
template <class Iface, class RetType, class Param1>
|
||||
OverrideFunctor<RetType> SetOverrideResult(RetType (Iface::*mfp)(Param1))
|
||||
{
|
||||
return OverrideFunctor<RetType>();
|
||||
}
|
||||
|
||||
template <class Iface, class RetType, class Param1>
|
||||
OverrideFunctor<RetType> SetOverrideResult(RetType (Iface::*mfp)(Param1, ...))
|
||||
{
|
||||
return OverrideFunctor<RetType>();
|
||||
}
|
||||
|
||||
template <class Iface, class RetType, class Param1>
|
||||
Iface *RecallGetIface(ISourceHook *shptr, RetType (Iface::*mfp)(Param1))
|
||||
{
|
||||
return reinterpret_cast<Iface*>(shptr->GetIfacePtr());
|
||||
}
|
||||
|
||||
template <class Iface, class RetType, class Param1>
|
||||
Iface *RecallGetIface(ISourceHook *shptr, RetType (Iface::*mfp)(Param1, ...))
|
||||
{
|
||||
return reinterpret_cast<Iface*>(shptr->GetIfacePtr());
|
||||
}
|
||||
|
||||
template <class Iface, class RetType, class Param1, class Param2>
|
||||
OverrideFunctor<RetType> SetOverrideResult(RetType (Iface::*mfp)(Param1, Param2))
|
||||
{
|
||||
return OverrideFunctor<RetType>();
|
||||
}
|
||||
|
||||
template <class Iface, class RetType, class Param1, class Param2>
|
||||
OverrideFunctor<RetType> SetOverrideResult(RetType (Iface::*mfp)(Param1, Param2, ...))
|
||||
{
|
||||
return OverrideFunctor<RetType>();
|
||||
}
|
||||
|
||||
template <class Iface, class RetType, class Param1, class Param2>
|
||||
Iface *RecallGetIface(ISourceHook *shptr, RetType (Iface::*mfp)(Param1, Param2))
|
||||
{
|
||||
return reinterpret_cast<Iface*>(shptr->GetIfacePtr());
|
||||
}
|
||||
|
||||
template <class Iface, class RetType, class Param1, class Param2>
|
||||
Iface *RecallGetIface(ISourceHook *shptr, RetType (Iface::*mfp)(Param1, Param2, ...))
|
||||
{
|
||||
return reinterpret_cast<Iface*>(shptr->GetIfacePtr());
|
||||
}
|
||||
|
||||
template <class Iface, class RetType, class Param1, class Param2, class Param3>
|
||||
OverrideFunctor<RetType> SetOverrideResult(RetType (Iface::*mfp)(Param1, Param2, Param3))
|
||||
{
|
||||
return OverrideFunctor<RetType>();
|
||||
}
|
||||
|
||||
template <class Iface, class RetType, class Param1, class Param2, class Param3>
|
||||
OverrideFunctor<RetType> SetOverrideResult(RetType (Iface::*mfp)(Param1, Param2, Param3, ...))
|
||||
{
|
||||
return OverrideFunctor<RetType>();
|
||||
}
|
||||
|
||||
template <class Iface, class RetType, class Param1, class Param2, class Param3>
|
||||
Iface *RecallGetIface(ISourceHook *shptr, RetType (Iface::*mfp)(Param1, Param2, Param3))
|
||||
{
|
||||
return reinterpret_cast<Iface*>(shptr->GetIfacePtr());
|
||||
}
|
||||
|
||||
template <class Iface, class RetType, class Param1, class Param2, class Param3>
|
||||
Iface *RecallGetIface(ISourceHook *shptr, RetType (Iface::*mfp)(Param1, Param2, Param3, ...))
|
||||
{
|
||||
return reinterpret_cast<Iface*>(shptr->GetIfacePtr());
|
||||
}
|
||||
|
||||
template <class Iface, class RetType, class Param1, class Param2, class Param3, class Param4>
|
||||
OverrideFunctor<RetType> SetOverrideResult(RetType (Iface::*mfp)(Param1, Param2, Param3, Param4))
|
||||
{
|
||||
return OverrideFunctor<RetType>();
|
||||
}
|
||||
|
||||
template <class Iface, class RetType, class Param1, class Param2, class Param3, class Param4>
|
||||
OverrideFunctor<RetType> SetOverrideResult(RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, ...))
|
||||
{
|
||||
return OverrideFunctor<RetType>();
|
||||
}
|
||||
|
||||
template <class Iface, class RetType, class Param1, class Param2, class Param3, class Param4>
|
||||
Iface *RecallGetIface(ISourceHook *shptr, RetType (Iface::*mfp)(Param1, Param2, Param3, Param4))
|
||||
{
|
||||
return reinterpret_cast<Iface*>(shptr->GetIfacePtr());
|
||||
}
|
||||
|
||||
template <class Iface, class RetType, class Param1, class Param2, class Param3, class Param4>
|
||||
Iface *RecallGetIface(ISourceHook *shptr, RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, ...))
|
||||
{
|
||||
return reinterpret_cast<Iface*>(shptr->GetIfacePtr());
|
||||
}
|
||||
|
||||
template <class Iface, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5>
|
||||
OverrideFunctor<RetType> SetOverrideResult(RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5))
|
||||
{
|
||||
return OverrideFunctor<RetType>();
|
||||
}
|
||||
|
||||
template <class Iface, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5>
|
||||
OverrideFunctor<RetType> SetOverrideResult(RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, ...))
|
||||
{
|
||||
return OverrideFunctor<RetType>();
|
||||
}
|
||||
|
||||
template <class Iface, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5>
|
||||
Iface *RecallGetIface(ISourceHook *shptr, RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5))
|
||||
{
|
||||
return reinterpret_cast<Iface*>(shptr->GetIfacePtr());
|
||||
}
|
||||
|
||||
template <class Iface, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5>
|
||||
Iface *RecallGetIface(ISourceHook *shptr, RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, ...))
|
||||
{
|
||||
return reinterpret_cast<Iface*>(shptr->GetIfacePtr());
|
||||
}
|
||||
|
||||
template <class Iface, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6>
|
||||
OverrideFunctor<RetType> SetOverrideResult(RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6))
|
||||
{
|
||||
return OverrideFunctor<RetType>();
|
||||
}
|
||||
|
||||
template <class Iface, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6>
|
||||
OverrideFunctor<RetType> SetOverrideResult(RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, ...))
|
||||
{
|
||||
return OverrideFunctor<RetType>();
|
||||
}
|
||||
|
||||
template <class Iface, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6>
|
||||
Iface *RecallGetIface(ISourceHook *shptr, RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6))
|
||||
{
|
||||
return reinterpret_cast<Iface*>(shptr->GetIfacePtr());
|
||||
}
|
||||
|
||||
template <class Iface, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6>
|
||||
Iface *RecallGetIface(ISourceHook *shptr, RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, ...))
|
||||
{
|
||||
return reinterpret_cast<Iface*>(shptr->GetIfacePtr());
|
||||
}
|
||||
|
||||
template <class Iface, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7>
|
||||
OverrideFunctor<RetType> SetOverrideResult(RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7))
|
||||
{
|
||||
return OverrideFunctor<RetType>();
|
||||
}
|
||||
|
||||
template <class Iface, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7>
|
||||
OverrideFunctor<RetType> SetOverrideResult(RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, ...))
|
||||
{
|
||||
return OverrideFunctor<RetType>();
|
||||
}
|
||||
|
||||
template <class Iface, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7>
|
||||
Iface *RecallGetIface(ISourceHook *shptr, RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7))
|
||||
{
|
||||
return reinterpret_cast<Iface*>(shptr->GetIfacePtr());
|
||||
}
|
||||
|
||||
template <class Iface, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7>
|
||||
Iface *RecallGetIface(ISourceHook *shptr, RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, ...))
|
||||
{
|
||||
return reinterpret_cast<Iface*>(shptr->GetIfacePtr());
|
||||
}
|
||||
|
||||
template <class Iface, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8>
|
||||
OverrideFunctor<RetType> SetOverrideResult(RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8))
|
||||
{
|
||||
return OverrideFunctor<RetType>();
|
||||
}
|
||||
|
||||
template <class Iface, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8>
|
||||
OverrideFunctor<RetType> SetOverrideResult(RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, ...))
|
||||
{
|
||||
return OverrideFunctor<RetType>();
|
||||
}
|
||||
|
||||
template <class Iface, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8>
|
||||
Iface *RecallGetIface(ISourceHook *shptr, RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8))
|
||||
{
|
||||
return reinterpret_cast<Iface*>(shptr->GetIfacePtr());
|
||||
}
|
||||
|
||||
template <class Iface, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8>
|
||||
Iface *RecallGetIface(ISourceHook *shptr, RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, ...))
|
||||
{
|
||||
return reinterpret_cast<Iface*>(shptr->GetIfacePtr());
|
||||
}
|
||||
|
||||
template <class Iface, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8, class Param9>
|
||||
OverrideFunctor<RetType> SetOverrideResult(RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9))
|
||||
{
|
||||
return OverrideFunctor<RetType>();
|
||||
}
|
||||
|
||||
template <class Iface, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8, class Param9>
|
||||
OverrideFunctor<RetType> SetOverrideResult(RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, ...))
|
||||
{
|
||||
return OverrideFunctor<RetType>();
|
||||
}
|
||||
|
||||
template <class Iface, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8, class Param9>
|
||||
Iface *RecallGetIface(ISourceHook *shptr, RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9))
|
||||
{
|
||||
return reinterpret_cast<Iface*>(shptr->GetIfacePtr());
|
||||
}
|
||||
|
||||
template <class Iface, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8, class Param9>
|
||||
Iface *RecallGetIface(ISourceHook *shptr, RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, ...))
|
||||
{
|
||||
return reinterpret_cast<Iface*>(shptr->GetIfacePtr());
|
||||
}
|
||||
|
||||
template <class Iface, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8, class Param9, class Param10>
|
||||
OverrideFunctor<RetType> SetOverrideResult(RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10))
|
||||
{
|
||||
return OverrideFunctor<RetType>();
|
||||
}
|
||||
|
||||
template <class Iface, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8, class Param9, class Param10>
|
||||
OverrideFunctor<RetType> SetOverrideResult(RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, ...))
|
||||
{
|
||||
return OverrideFunctor<RetType>();
|
||||
}
|
||||
|
||||
template <class Iface, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8, class Param9, class Param10>
|
||||
Iface *RecallGetIface(ISourceHook *shptr, RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10))
|
||||
{
|
||||
return reinterpret_cast<Iface*>(shptr->GetIfacePtr());
|
||||
}
|
||||
|
||||
template <class Iface, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8, class Param9, class Param10>
|
||||
Iface *RecallGetIface(ISourceHook *shptr, RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, ...))
|
||||
{
|
||||
return reinterpret_cast<Iface*>(shptr->GetIfacePtr());
|
||||
}
|
||||
|
||||
template <class Iface, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8, class Param9, class Param10, class Param11>
|
||||
OverrideFunctor<RetType> SetOverrideResult(RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11))
|
||||
{
|
||||
return OverrideFunctor<RetType>();
|
||||
}
|
||||
|
||||
template <class Iface, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8, class Param9, class Param10, class Param11>
|
||||
OverrideFunctor<RetType> SetOverrideResult(RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, ...))
|
||||
{
|
||||
return OverrideFunctor<RetType>();
|
||||
}
|
||||
|
||||
template <class Iface, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8, class Param9, class Param10, class Param11>
|
||||
Iface *RecallGetIface(ISourceHook *shptr, RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11))
|
||||
{
|
||||
return reinterpret_cast<Iface*>(shptr->GetIfacePtr());
|
||||
}
|
||||
|
||||
template <class Iface, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8, class Param9, class Param10, class Param11>
|
||||
Iface *RecallGetIface(ISourceHook *shptr, RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, ...))
|
||||
{
|
||||
return reinterpret_cast<Iface*>(shptr->GetIfacePtr());
|
||||
}
|
||||
|
||||
template <class Iface, 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>
|
||||
OverrideFunctor<RetType> SetOverrideResult(RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12))
|
||||
{
|
||||
return OverrideFunctor<RetType>();
|
||||
}
|
||||
|
||||
template <class Iface, 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>
|
||||
OverrideFunctor<RetType> SetOverrideResult(RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, ...))
|
||||
{
|
||||
return OverrideFunctor<RetType>();
|
||||
}
|
||||
|
||||
template <class Iface, 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>
|
||||
Iface *RecallGetIface(ISourceHook *shptr, RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12))
|
||||
{
|
||||
return reinterpret_cast<Iface*>(shptr->GetIfacePtr());
|
||||
}
|
||||
|
||||
template <class Iface, 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>
|
||||
Iface *RecallGetIface(ISourceHook *shptr, RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, ...))
|
||||
{
|
||||
return reinterpret_cast<Iface*>(shptr->GetIfacePtr());
|
||||
}
|
||||
|
||||
template <class Iface, 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>
|
||||
OverrideFunctor<RetType> SetOverrideResult(RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13))
|
||||
{
|
||||
return OverrideFunctor<RetType>();
|
||||
}
|
||||
|
||||
template <class Iface, 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>
|
||||
OverrideFunctor<RetType> SetOverrideResult(RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, ...))
|
||||
{
|
||||
return OverrideFunctor<RetType>();
|
||||
}
|
||||
|
||||
template <class Iface, 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>
|
||||
Iface *RecallGetIface(ISourceHook *shptr, RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13))
|
||||
{
|
||||
return reinterpret_cast<Iface*>(shptr->GetIfacePtr());
|
||||
}
|
||||
|
||||
template <class Iface, 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>
|
||||
Iface *RecallGetIface(ISourceHook *shptr, RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, ...))
|
||||
{
|
||||
return reinterpret_cast<Iface*>(shptr->GetIfacePtr());
|
||||
}
|
||||
|
||||
template <class Iface, 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>
|
||||
OverrideFunctor<RetType> SetOverrideResult(RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14))
|
||||
{
|
||||
return OverrideFunctor<RetType>();
|
||||
}
|
||||
|
||||
template <class Iface, 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>
|
||||
OverrideFunctor<RetType> SetOverrideResult(RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, ...))
|
||||
{
|
||||
return OverrideFunctor<RetType>();
|
||||
}
|
||||
|
||||
template <class Iface, 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>
|
||||
Iface *RecallGetIface(ISourceHook *shptr, RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14))
|
||||
{
|
||||
return reinterpret_cast<Iface*>(shptr->GetIfacePtr());
|
||||
}
|
||||
|
||||
template <class Iface, 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>
|
||||
Iface *RecallGetIface(ISourceHook *shptr, RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, ...))
|
||||
{
|
||||
return reinterpret_cast<Iface*>(shptr->GetIfacePtr());
|
||||
}
|
||||
|
||||
template <class Iface, 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>
|
||||
OverrideFunctor<RetType> SetOverrideResult(RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15))
|
||||
{
|
||||
return OverrideFunctor<RetType>();
|
||||
}
|
||||
|
||||
template <class Iface, 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>
|
||||
OverrideFunctor<RetType> SetOverrideResult(RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, ...))
|
||||
{
|
||||
return OverrideFunctor<RetType>();
|
||||
}
|
||||
|
||||
template <class Iface, 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>
|
||||
Iface *RecallGetIface(ISourceHook *shptr, RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15))
|
||||
{
|
||||
return reinterpret_cast<Iface*>(shptr->GetIfacePtr());
|
||||
}
|
||||
|
||||
template <class Iface, 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>
|
||||
Iface *RecallGetIface(ISourceHook *shptr, RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, ...))
|
||||
{
|
||||
return reinterpret_cast<Iface*>(shptr->GetIfacePtr());
|
||||
}
|
||||
|
||||
template <class Iface, 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>
|
||||
OverrideFunctor<RetType> SetOverrideResult(RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, Param16))
|
||||
{
|
||||
return OverrideFunctor<RetType>();
|
||||
}
|
||||
|
||||
template <class Iface, 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>
|
||||
OverrideFunctor<RetType> SetOverrideResult(RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, Param16, ...))
|
||||
{
|
||||
return OverrideFunctor<RetType>();
|
||||
}
|
||||
|
||||
template <class Iface, 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>
|
||||
Iface *RecallGetIface(ISourceHook *shptr, RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, Param16))
|
||||
{
|
||||
return reinterpret_cast<Iface*>(shptr->GetIfacePtr());
|
||||
}
|
||||
|
||||
template <class Iface, 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>
|
||||
Iface *RecallGetIface(ISourceHook *shptr, RetType (Iface::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, Param16, ...))
|
||||
{
|
||||
return reinterpret_cast<Iface*>(shptr->GetIfacePtr());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
2030
sourcehook/sourcehook_hookmangen.cpp
Normal file
2030
sourcehook/sourcehook_hookmangen.cpp
Normal file
File diff suppressed because it is too large
Load Diff
299
sourcehook/sourcehook_hookmangen.h
Normal file
299
sourcehook/sourcehook_hookmangen.h
Normal file
@ -0,0 +1,299 @@
|
||||
/* ======== SourceHook ========
|
||||
* Copyright (C) 2004-2007 Metamod:Source Development Team
|
||||
* No warranties of any kind
|
||||
*
|
||||
* License: zlib/libpng
|
||||
*
|
||||
* Author(s): Pavol "PM OnoTo" Marko
|
||||
* ============================
|
||||
*/
|
||||
|
||||
#ifndef __SOURCEHOOK_HOOKMANGEN_H__
|
||||
#define __SOURCEHOOK_HOOKMANGEN_H__
|
||||
|
||||
#include "sh_pagealloc.h"
|
||||
|
||||
namespace SourceHook
|
||||
{
|
||||
namespace Impl
|
||||
{
|
||||
|
||||
// Code gen stuff
|
||||
#if SH_COMP == SH_COMP_GCC
|
||||
#include <stdint.h>
|
||||
typedef int8_t jit_int8_t;
|
||||
typedef uint8_t jit_uint8_t;
|
||||
typedef int32_t jit_int32_t;
|
||||
typedef uint32_t jit_uint32_t;
|
||||
typedef int64_t jit_int64_t;
|
||||
typedef uint64_t jit_uint64_t;
|
||||
#elif SH_COMP == SH_COMP_MSVC
|
||||
typedef __int8 jit_int8_t;
|
||||
typedef unsigned __int8 jit_uint8_t;
|
||||
typedef __int32 jit_int32_t;
|
||||
typedef unsigned __int32 jit_uint32_t;
|
||||
typedef __int64 jit_int64_t;
|
||||
typedef unsigned __int64 jit_uint64_t;
|
||||
#endif
|
||||
typedef unsigned int jitoffs_t;
|
||||
typedef signed int jitrel_t;
|
||||
|
||||
|
||||
class GenBuffer
|
||||
{
|
||||
static CPageAlloc ms_Allocator;
|
||||
|
||||
unsigned char *m_pData;
|
||||
jitoffs_t m_Size;
|
||||
jitoffs_t m_AllocatedSize;
|
||||
|
||||
public:
|
||||
GenBuffer() : m_pData(NULL), m_Size(0), m_AllocatedSize(0)
|
||||
{
|
||||
}
|
||||
~GenBuffer()
|
||||
{
|
||||
clear();
|
||||
}
|
||||
jitoffs_t GetSize()
|
||||
{
|
||||
return m_Size;
|
||||
}
|
||||
unsigned char *GetData()
|
||||
{
|
||||
return m_pData;
|
||||
}
|
||||
|
||||
template <class PT> void push(PT what)
|
||||
{
|
||||
push((const unsigned char *)&what, sizeof(PT));
|
||||
}
|
||||
|
||||
void push(const unsigned char *data, jitoffs_t size)
|
||||
{
|
||||
jitoffs_t newSize = m_Size + size;
|
||||
if (newSize > m_AllocatedSize)
|
||||
{
|
||||
m_AllocatedSize = newSize > m_AllocatedSize*2 ? newSize : m_AllocatedSize*2;
|
||||
if (m_AllocatedSize < 64)
|
||||
m_AllocatedSize = 64;
|
||||
|
||||
unsigned char *newBuf;
|
||||
newBuf = reinterpret_cast<unsigned char*>(ms_Allocator.Alloc(m_AllocatedSize));
|
||||
ms_Allocator.SetRW(newBuf);
|
||||
if (!newBuf)
|
||||
{
|
||||
SH_ASSERT(0, ("bad_alloc: couldn't allocate 0x%08X bytes of memory\n", m_AllocatedSize));
|
||||
return;
|
||||
}
|
||||
memset((void*)newBuf, 0xCC, m_AllocatedSize); // :TODO: remove this !
|
||||
memcpy((void*)newBuf, (const void*)m_pData, m_Size);
|
||||
if (m_pData)
|
||||
{
|
||||
ms_Allocator.SetRE(reinterpret_cast<void*>(m_pData));
|
||||
ms_Allocator.SetRW(newBuf);
|
||||
ms_Allocator.Free(reinterpret_cast<void*>(m_pData));
|
||||
}
|
||||
m_pData = newBuf;
|
||||
}
|
||||
memcpy((void*)(m_pData + m_Size), (const void*)data, size);
|
||||
m_Size = newSize;
|
||||
}
|
||||
|
||||
template <class PT> void rewrite(jitoffs_t offset, PT what)
|
||||
{
|
||||
rewrite(offset, (const unsigned char *)&what, sizeof(PT));
|
||||
}
|
||||
|
||||
void rewrite(jitoffs_t offset, const unsigned char *data, jitoffs_t size)
|
||||
{
|
||||
SH_ASSERT(offset + size <= m_AllocatedSize, ("rewrite too far"));
|
||||
|
||||
memcpy((void*)(m_pData + offset), (const void*)data, size);
|
||||
}
|
||||
|
||||
void clear()
|
||||
{
|
||||
if (m_pData)
|
||||
ms_Allocator.Free(reinterpret_cast<void*>(m_pData));
|
||||
m_pData = NULL;
|
||||
m_Size = 0;
|
||||
m_AllocatedSize = 0;
|
||||
}
|
||||
|
||||
void SetRE()
|
||||
{
|
||||
ms_Allocator.SetRE(reinterpret_cast<void*>(m_pData));
|
||||
}
|
||||
|
||||
operator void *()
|
||||
{
|
||||
return reinterpret_cast<void*>(GetData());
|
||||
}
|
||||
|
||||
void write_ubyte(jit_uint8_t x) { push(x); }
|
||||
void write_byte(jit_uint8_t x) { push(x); }
|
||||
|
||||
void write_ushort(unsigned short x) { push(x); }
|
||||
void write_short(signed short x) { push(x); }
|
||||
|
||||
void write_uint32(jit_uint32_t x) { push(x); }
|
||||
void write_int32(jit_uint32_t x) { push(x); }
|
||||
|
||||
jitoffs_t get_outputpos()
|
||||
{
|
||||
return m_Size;
|
||||
}
|
||||
|
||||
void start_count(jitoffs_t &offs)
|
||||
{
|
||||
offs = get_outputpos();
|
||||
}
|
||||
void end_count(jitoffs_t &offs)
|
||||
{
|
||||
offs = get_outputpos() - offs;
|
||||
}
|
||||
};
|
||||
|
||||
class GenContext
|
||||
{
|
||||
const static int SIZE_MWORD = 4;
|
||||
const static int SIZE_PTR = sizeof(void*);
|
||||
const static int PassFlag_ForcedByRef = (1<<30); // ByVal in source, but actually passed by reference (GCC) -> private pass, destruct
|
||||
|
||||
HookManagerPubFunc m_GeneratedPubFunc;
|
||||
|
||||
CProto m_OrigProto; // original passed-in prototype
|
||||
CProto m_Proto;
|
||||
int m_VtblOffs;
|
||||
int m_VtblIdx;
|
||||
ISourceHook *m_SHPtr;
|
||||
|
||||
GenBuffer m_HookFunc;
|
||||
GenBuffer m_PubFunc;
|
||||
|
||||
ProtoInfo *m_BuiltPI;
|
||||
PassInfo *m_BuiltPI_Params;
|
||||
PassInfo::V2Info *m_BuiltPI_Params2;
|
||||
|
||||
// For hookfunc
|
||||
void **m_pHI;
|
||||
void **m_HookfuncVfnptr;
|
||||
|
||||
// Level 3 - Helpers
|
||||
int m_RegCounter;
|
||||
jit_int8_t NextRegEBX_ECX_EDX();
|
||||
|
||||
int m_BytesPushedAfterInitialAlignment;
|
||||
enum AlignStackFlags
|
||||
{
|
||||
AlignStack_GCC_ThisOnStack = 1,
|
||||
AlignStack_MSVC_ThisOnStack = 2,
|
||||
AlignStack_MemRet = 4
|
||||
};
|
||||
jit_int32_t AlignStackBeforeCall(int paramsize, int flags);
|
||||
void AlignStackAfterCall(jit_int32_t numofbytes);
|
||||
void CheckAlignmentBeforeCall();
|
||||
|
||||
// size info
|
||||
jit_int32_t GetRealSize(const IntPassInfo &info); // checks for reference
|
||||
jit_int32_t AlignSize(jit_int32_t x, jit_int32_t boundary); // align a size
|
||||
jit_int32_t GetParamStackSize(const IntPassInfo &info); // get the size of a param in the param stack
|
||||
short GetParamsTotalStackSize(); // sum(GetParamStackSize(param[i]), 0 <= i < numOfParams)
|
||||
|
||||
// Helpers
|
||||
void BitwiseCopy_Setup();
|
||||
void BitwiseCopy_Do(size_t size);
|
||||
|
||||
|
||||
// HookFunc frame
|
||||
jit_int32_t m_HookFunc_FrameOffset;
|
||||
jit_int32_t m_HookFunc_FrameVarsSize;
|
||||
|
||||
void ResetFrame(jit_int32_t startOffset);
|
||||
jit_int32_t AddVarToFrame(jit_int32_t size);
|
||||
jit_int32_t ComputeVarsSize();
|
||||
|
||||
// Param push
|
||||
short GetForcedByRefParamsSize(); // sum(param[i] is forcedbyref ? GetStackSize(param[i]) : 0, 0 <= i < numOfParams)
|
||||
short GetForcedByRefParamOffset(int p); // sum(param[i] is forcedbyref ? GetStackSize(param[i]) : 0, 0 <= i < p)
|
||||
jit_int32_t PushParams(jit_int32_t param_base_offset, jit_int32_t save_ret_to,
|
||||
jit_int32_t v_place_for_memret, jit_int32_t v_place_fbrr_base); // save_ret_to and v_place_for_memret only used for memory returns
|
||||
jit_int32_t PushRef(jit_int32_t param_offset, const IntPassInfo &pi);
|
||||
jit_int32_t PushBasic(jit_int32_t param_offset, const IntPassInfo &pi);
|
||||
jit_int32_t PushFloat(jit_int32_t param_offset, const IntPassInfo &pi);
|
||||
jit_int32_t PushObject(jit_int32_t param_offset, const IntPassInfo &pi, jit_int32_t v_place_fbrr);
|
||||
jit_int32_t PushMemRetPtr(jit_int32_t save_ret_to, jit_int32_t v_place_for_memret);
|
||||
void DestroyParams(jit_int32_t fbrr_base);
|
||||
|
||||
// Ret val processing
|
||||
void SaveRetVal(jit_int32_t v_where, jit_int32_t v_place_for_memret);
|
||||
void ProcessPluginRetVal(jit_int32_t v_cur_res, jit_int32_t v_pContext, jit_int32_t v_plugin_ret);
|
||||
|
||||
void PrepareReturn(jit_int32_t v_status, jit_int32_t v_pContext, jit_int32_t v_retptr);
|
||||
void DoReturn(jit_int32_t v_retptr, jit_int32_t v_memret_outaddr);
|
||||
|
||||
bool MemRetWithTempObj(); // do we do a memory return AND need a temporary place for it?
|
||||
|
||||
// Call hooks
|
||||
void GenerateCallHooks(int v_status, int v_prev_res, int v_cur_res, int v_iter,
|
||||
int v_pContext, int base_param_offset, int v_plugin_ret, int v_place_for_memret, jit_int32_t v_place_fbrr_base, jit_int32_t v_va_buf);
|
||||
|
||||
// Call orig
|
||||
void GenerateCallOrig(int v_status, int v_pContext, int param_base_offs, int v_this,
|
||||
int v_vfnptr_origentry, int v_orig_ret, int v_override_ret, int v_place_for_memret, jit_int32_t v_place_fbrr_base, jit_int32_t v_va_buf);
|
||||
|
||||
// Hook loop
|
||||
void CallSetupHookLoop(int v_orig_ret, int v_override_ret,
|
||||
int v_cur_res, int v_prev_res, int v_status, int v_vnfptr_origentry,
|
||||
int v_this, int v_pContext);
|
||||
|
||||
void CallEndContext(int v_pContext);
|
||||
|
||||
// Level 2 -> called from Generate()
|
||||
void AutoDetectRetType();
|
||||
void AutoDetectParamFlags();
|
||||
bool PassInfoSupported(const IntPassInfo &pi, bool is_ret);
|
||||
void Clear();
|
||||
void BuildProtoInfo();
|
||||
void *GenerateHookFunc();
|
||||
void *GeneratePubFunc();
|
||||
|
||||
HookManagerPubFunc Generate();
|
||||
public:
|
||||
// Level 1 -> Public interface
|
||||
GenContext(const ProtoInfo *proto, int vtbl_offs, int vtbl_idx, ISourceHook *pSHPtr);
|
||||
~GenContext();
|
||||
|
||||
bool Equal(const CProto &proto, int vtbl_offs, int vtbl_idx);
|
||||
bool Equal(HookManagerPubFunc other);
|
||||
|
||||
HookManagerPubFunc GetPubFunc();
|
||||
};
|
||||
|
||||
class CHookManagerAutoGen : public IHookManagerAutoGen
|
||||
{
|
||||
struct StoredContext
|
||||
{
|
||||
int m_RefCnt;
|
||||
GenContext *m_GenContext;
|
||||
};
|
||||
List<StoredContext> m_Contexts;
|
||||
ISourceHook *m_pSHPtr;
|
||||
|
||||
public:
|
||||
CHookManagerAutoGen(ISourceHook *pSHPtr);
|
||||
~CHookManagerAutoGen();
|
||||
|
||||
int GetIfaceVersion();
|
||||
int GetImplVersion();
|
||||
|
||||
HookManagerPubFunc MakeHookMan(const ProtoInfo *proto, int vtbl_offs, int vtbl_idx);
|
||||
void ReleaseHookMan(HookManagerPubFunc pubFunc);
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
1611
sourcehook/sourcehook_hookmangen_x86.h
Normal file
1611
sourcehook/sourcehook_hookmangen_x86.h
Normal file
File diff suppressed because it is too large
Load Diff
@ -26,6 +26,21 @@ namespace SourceHook
|
||||
void *pCopyCtor;
|
||||
void *pDtor;
|
||||
void *pAssignOperator;
|
||||
|
||||
bool operator == (const IntPassInfo &other) const
|
||||
{
|
||||
return size == other.size
|
||||
&& type == other.type
|
||||
&& flags == other.flags
|
||||
&& pNormalCtor == other.pNormalCtor
|
||||
&& pDtor == other.pDtor
|
||||
&& pAssignOperator == other.pAssignOperator;
|
||||
}
|
||||
|
||||
bool operator != (const IntPassInfo &other) const
|
||||
{
|
||||
return !(*this == other);
|
||||
}
|
||||
};
|
||||
|
||||
class CProto
|
||||
@ -72,6 +87,8 @@ namespace SourceHook
|
||||
|
||||
bool operator == (const CProto &other) const;
|
||||
|
||||
bool ExactlyEqual(const CProto &other) const;
|
||||
|
||||
int GetVersion() const
|
||||
{
|
||||
return m_Version;
|
||||
@ -87,11 +104,21 @@ namespace SourceHook
|
||||
return m_ParamsPassInfo[i];
|
||||
}
|
||||
|
||||
IntPassInfo & GetParam(int i)
|
||||
{
|
||||
return m_ParamsPassInfo[i];
|
||||
}
|
||||
|
||||
const IntPassInfo & GetRet() const
|
||||
{
|
||||
return m_RetPassInfo;
|
||||
}
|
||||
|
||||
IntPassInfo & GetRet()
|
||||
{
|
||||
return m_RetPassInfo;
|
||||
}
|
||||
|
||||
int GetConvention() const
|
||||
{
|
||||
return m_Convention;
|
||||
|
||||
109
sourcehook/sourcehook_pibuilder.h
Normal file
109
sourcehook/sourcehook_pibuilder.h
Normal file
@ -0,0 +1,109 @@
|
||||
/* ======== SourceHook ========
|
||||
* Copyright (C) 2004-2007 Metamod:Source Development Team
|
||||
* No warranties of any kind
|
||||
*
|
||||
* License: zlib/libpng
|
||||
*
|
||||
* Author(s): Pavol "PM OnoTo" Marko
|
||||
* ============================
|
||||
*/
|
||||
|
||||
#ifndef __SOURCEHOOK_PIBUILDER_H__
|
||||
#define __SOURCEHOOK_PIBUILDER_H__
|
||||
|
||||
#include "sourcehook.h"
|
||||
#include "sh_vector.h"
|
||||
|
||||
namespace SourceHook
|
||||
{
|
||||
// Helper class: protocol information builder
|
||||
class CProtoInfoBuilder
|
||||
{
|
||||
ProtoInfo m_PI;
|
||||
CVector<PassInfo> m_Params;
|
||||
CVector<PassInfo::V2Info> m_Params2;
|
||||
public:
|
||||
CProtoInfoBuilder(int cc)
|
||||
{
|
||||
memset(reinterpret_cast<void*>(&m_PI), 0, sizeof(ProtoInfo));
|
||||
m_PI.convention = cc;
|
||||
|
||||
// dummy 0 params
|
||||
PassInfo dummy;
|
||||
PassInfo::V2Info dummy2;
|
||||
memset(reinterpret_cast<void*>(&dummy), 0, sizeof(PassInfo));
|
||||
memset(reinterpret_cast<void*>(&dummy2), 0, sizeof(PassInfo::V2Info));
|
||||
|
||||
dummy.size = 1; // Version1
|
||||
|
||||
m_Params.push_back(dummy);
|
||||
m_Params2.push_back(dummy2);
|
||||
}
|
||||
|
||||
void SetReturnType(size_t size, PassInfo::PassType type, int flags,
|
||||
void *pNormalCtor, void *pCopyCtor, void *pDtor, void *pAssignOperator)
|
||||
{
|
||||
if (pNormalCtor)
|
||||
flags |= PassInfo::PassFlag_OCtor;
|
||||
|
||||
if (pCopyCtor)
|
||||
flags |= PassInfo::PassFlag_CCtor;
|
||||
|
||||
if (pDtor)
|
||||
flags |= PassInfo::PassFlag_ODtor;
|
||||
|
||||
if (pAssignOperator)
|
||||
flags |= PassInfo::PassFlag_AssignOp;
|
||||
|
||||
m_PI.retPassInfo.size = size;
|
||||
m_PI.retPassInfo.type = type;
|
||||
m_PI.retPassInfo.flags = flags;
|
||||
m_PI.retPassInfo2.pNormalCtor = pNormalCtor;
|
||||
m_PI.retPassInfo2.pCopyCtor = pCopyCtor;
|
||||
m_PI.retPassInfo2.pDtor = pDtor;
|
||||
m_PI.retPassInfo2.pAssignOperator = pAssignOperator;
|
||||
}
|
||||
|
||||
void AddParam(size_t size, PassInfo::PassType type, int flags,
|
||||
void *pNormalCtor, void *pCopyCtor, void *pDtor, void *pAssignOperator)
|
||||
{
|
||||
PassInfo pi;
|
||||
PassInfo::V2Info pi2;
|
||||
|
||||
if (pNormalCtor)
|
||||
flags |= PassInfo::PassFlag_OCtor;
|
||||
|
||||
if (pCopyCtor)
|
||||
flags |= PassInfo::PassFlag_CCtor;
|
||||
|
||||
if (pDtor)
|
||||
flags |= PassInfo::PassFlag_ODtor;
|
||||
|
||||
if (pAssignOperator)
|
||||
flags |= PassInfo::PassFlag_AssignOp;
|
||||
|
||||
|
||||
pi.size = size;
|
||||
pi.type = type;
|
||||
pi.flags = flags;
|
||||
pi2.pNormalCtor = pNormalCtor;
|
||||
pi2.pCopyCtor = pCopyCtor;
|
||||
pi2.pDtor = pDtor;
|
||||
pi2.pAssignOperator = pAssignOperator;
|
||||
|
||||
m_Params.push_back(pi);
|
||||
m_Params2.push_back(pi2);
|
||||
++m_PI.numOfParams;
|
||||
}
|
||||
|
||||
operator ProtoInfo*()
|
||||
{
|
||||
m_PI.paramsPassInfo = &(m_Params[0]);
|
||||
m_PI.paramsPassInfo2 = &(m_Params2[0]);
|
||||
return &m_PI;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@ -9,7 +9,7 @@ INCLUDE = -I. -I..
|
||||
MAX_PARAMS=20
|
||||
|
||||
BINARY = sourcehook_test
|
||||
OBJECTS = main.cpp sourcehook.cpp $(shell ls -t test*.cpp)
|
||||
OBJECTS = main.cpp sourcehook.cpp ../sourcehook_hookmangen.cpp $(shell ls -t test*.cpp)
|
||||
HEADERS = ../sh_list.h ../sh_tinyhash.h ../sh_memory.h ../sh_string.h ../sh_vector.h ../sourcehook_impl.h ../FastDelegate.h ../sourcehook.h ../sh_memfuncinfo.h
|
||||
|
||||
ifeq "$(DEBUG)" "true"
|
||||
@ -20,7 +20,7 @@ else
|
||||
CFLAGS = $(OPT_FLAGS)
|
||||
endif
|
||||
|
||||
CFLAGS += -Wall
|
||||
CFLAGS += -Wall -Wno-non-virtual-dtor
|
||||
# Also, enable SH_ASSERT
|
||||
CFLAGS += -DSH_DEBUG
|
||||
|
||||
|
||||
6
sourcehook/test/generate.bat
Normal file
6
sourcehook/test/generate.bat
Normal file
@ -0,0 +1,6 @@
|
||||
:: Generates everything
|
||||
:: Usage:
|
||||
:: generate.bat <num-of-arguments>
|
||||
|
||||
|
||||
..\generate\shworker iter testhookmangen.hxx testhookmangen.h %1
|
||||
@ -13,6 +13,7 @@
|
||||
|
||||
#include "sourcehook_impl.h"
|
||||
#include "sourcehook.h"
|
||||
#include "sourcehook_hookmangen.h"
|
||||
|
||||
using namespace std;
|
||||
bool g_Verbose;
|
||||
@ -46,6 +47,8 @@ DECL_TEST(Multi);
|
||||
DECL_TEST(Ref);
|
||||
DECL_TEST(RefRet);
|
||||
DECL_TEST(VPHooks);
|
||||
DECL_TEST(CPageAlloc); // in testhookmangen.cpp
|
||||
DECL_TEST(HookManGen);
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
@ -68,6 +71,8 @@ int main(int argc, char *argv[])
|
||||
DO_TEST(Ref);
|
||||
DO_TEST(RefRet);
|
||||
DO_TEST(VPHooks);
|
||||
DO_TEST(CPageAlloc);
|
||||
DO_TEST(HookManGen);
|
||||
|
||||
cout << endl << "----" << endl << "Passed: " << passed << endl << "Failed: " << failed << endl;
|
||||
cout << "Total: " << passed + failed << endl;
|
||||
@ -107,3 +112,14 @@ void Test_UnpausePlugin(SourceHook::ISourceHook *shptr, SourceHook::Plugin plug)
|
||||
{
|
||||
static_cast<SourceHook::Impl::CSourceHookImpl *>(shptr)->UnpausePlugin(plug);
|
||||
}
|
||||
|
||||
SourceHook::IHookManagerAutoGen *Test_HMAG_Factory(SourceHook::ISourceHook *shptr)
|
||||
{
|
||||
return new SourceHook::Impl::CHookManagerAutoGen(shptr);
|
||||
}
|
||||
|
||||
void Test_HMAG_Delete(SourceHook::IHookManagerAutoGen *ptr)
|
||||
{
|
||||
delete static_cast<SourceHook::Impl::CHookManagerAutoGen*>(ptr);
|
||||
}
|
||||
|
||||
|
||||
@ -248,6 +248,9 @@
|
||||
<File
|
||||
RelativePath="..\..\sourcehook.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\sourcehook_hookmangen.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\test1.cpp">
|
||||
</File>
|
||||
@ -266,6 +269,9 @@
|
||||
<File
|
||||
RelativePath="..\testbail2.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\testhookmangen.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\testlist.cpp">
|
||||
</File>
|
||||
@ -306,6 +312,12 @@
|
||||
<File
|
||||
RelativePath="..\..\sh_list.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\sh_memory.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\sh_pagealloc.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\sh_stack.h">
|
||||
</File>
|
||||
@ -321,6 +333,12 @@
|
||||
<File
|
||||
RelativePath="..\..\sourcehook.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\sourcehook_hookmangen.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\sourcehook_hookmangen_x86.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\sourcehook_impl.h">
|
||||
</File>
|
||||
@ -345,6 +363,9 @@
|
||||
<File
|
||||
RelativePath="..\..\sourcehook_impl_cvfnptr.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\sourcehook_pibuilder.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\sourcehook_test.h">
|
||||
</File>
|
||||
@ -354,6 +375,9 @@
|
||||
<File
|
||||
RelativePath="..\testevents.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\testhookmangen.h">
|
||||
</File>
|
||||
<Filter
|
||||
Name="generate"
|
||||
Filter="">
|
||||
@ -378,6 +402,9 @@ popd
|
||||
Outputs="..\sourcehook.h"/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\testhookmangen.hxx">
|
||||
</File>
|
||||
</Filter>
|
||||
</Filter>
|
||||
<Filter
|
||||
|
||||
@ -303,6 +303,7 @@
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE;_CRT_SECURE_NO_DEPRECATE"
|
||||
StringPooling="true"
|
||||
MinimalRebuild="true"
|
||||
ExceptionHandling="1"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="0"
|
||||
EnableFunctionLevelLinking="true"
|
||||
@ -371,6 +372,10 @@
|
||||
RelativePath="..\..\sourcehook.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\sourcehook_hookmangen.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\test1.cpp"
|
||||
>
|
||||
@ -395,6 +400,10 @@
|
||||
RelativePath="..\testbail2.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\testhookmangen.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\testlist.cpp"
|
||||
>
|
||||
@ -472,6 +481,14 @@
|
||||
RelativePath="..\..\sourcehook.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\sourcehook_hookmangen.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\sourcehook_hookmangen_x86.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\sourcehook_impl.h"
|
||||
>
|
||||
@ -500,6 +517,10 @@
|
||||
RelativePath="..\..\sourcehook_impl_cvfnptr.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\sourcehook_pibuilder.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\sourcehook_test.h"
|
||||
>
|
||||
@ -512,6 +533,10 @@
|
||||
RelativePath="..\testevents.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\testhookmangen.h"
|
||||
>
|
||||
</File>
|
||||
<Filter
|
||||
Name="generate"
|
||||
>
|
||||
@ -536,6 +561,10 @@
|
||||
/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\testhookmangen.hxx"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
</Filter>
|
||||
<Filter
|
||||
|
||||
@ -17,6 +17,7 @@ struct CAutoPtrDestruction
|
||||
CAutoPtrDestruction(T *p) : m_Ptr(p) { }
|
||||
~CAutoPtrDestruction() { if (m_Ptr) delete m_Ptr; }
|
||||
void clear() { m_Ptr = NULL; }
|
||||
void set(T *ptr) { m_Ptr = ptr; }
|
||||
};
|
||||
|
||||
struct CSHPtrAutoDestruction
|
||||
@ -33,3 +34,16 @@ void Test_CompleteShutdown(SourceHook::ISourceHook *shptr);
|
||||
void Test_UnloadPlugin(SourceHook::ISourceHook *shptr, SourceHook::Plugin plug);
|
||||
void Test_PausePlugin(SourceHook::ISourceHook *shptr, SourceHook::Plugin plug);
|
||||
void Test_UnpausePlugin(SourceHook::ISourceHook *shptr, SourceHook::Plugin plug);
|
||||
|
||||
SourceHook::IHookManagerAutoGen *Test_HMAG_Factory(SourceHook::ISourceHook *pSHPtr);
|
||||
void Test_HMAG_Delete(SourceHook::IHookManagerAutoGen *ptr);
|
||||
|
||||
struct CHMAGAutoDestruction
|
||||
{
|
||||
SourceHook::IHookManagerAutoGen *m_Ptr;
|
||||
CHMAGAutoDestruction(SourceHook::IHookManagerAutoGen *ptr) : m_Ptr(ptr) {}
|
||||
~CHMAGAutoDestruction() { Test_HMAG_Delete(m_Ptr); }
|
||||
};
|
||||
|
||||
|
||||
#define GET_HMAG(var, shptr) var = Test_HMAG_Factory(shptr); CHMAGAutoDestruction __hmagautodestruction(var);
|
||||
|
||||
@ -178,7 +178,7 @@ bool TestVafmtAndOverload(std::string &error)
|
||||
tmpbuf, tmpbuf, tmpbuf, tmpbuf, tmpbuf, tmpbuf, tmpbuf, tmpbuf, tmpbuf, tmpbuf,
|
||||
tmpbuf, tmpbuf, tmpbuf, tmpbuf, tmpbuf, tmpbuf, tmpbuf, tmpbuf, tmpbuf, tmpbuf);
|
||||
|
||||
char refbuf[SourceHook::STRBUF_LEN];
|
||||
char refbuf[SourceHook::STRBUF_LEN];
|
||||
for (int i = 0; i < (SourceHook::STRBUF_LEN - 1); ++i)
|
||||
refbuf[i] = (i % 10) + '0';
|
||||
refbuf[SourceHook::STRBUF_LEN - 1] = 0;
|
||||
|
||||
@ -19,6 +19,19 @@
|
||||
|
||||
extern bool g_Verbose;
|
||||
|
||||
static unsigned int MakeHash(const char *name)
|
||||
{
|
||||
int a = 0;
|
||||
unsigned int res = 0xFFFFFFFF;
|
||||
|
||||
while (*name)
|
||||
{
|
||||
res ^= ((unsigned int)*name << ((a++ % 4)*8));
|
||||
++name;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
struct State
|
||||
{
|
||||
virtual ~State()
|
||||
@ -28,10 +41,27 @@ struct State
|
||||
|
||||
virtual bool IsEqual(State *other)
|
||||
{
|
||||
return (typeid(other) == typeid(this)) ? true : false;
|
||||
return (MakeHash(GetName()) == MakeHash(other->GetName())) ? true : false;
|
||||
}
|
||||
|
||||
virtual bool Ignore()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
virtual void Dump() = 0;
|
||||
virtual const char *GetName() = 0;
|
||||
};
|
||||
|
||||
struct IgnoreState : public State
|
||||
{
|
||||
virtual bool Ignore()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
virtual void Dump()
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
typedef std::list<State*> StateList;
|
||||
@ -53,6 +83,8 @@ namespace
|
||||
State *cs = va_arg(argptr, State*);
|
||||
if (!cs)
|
||||
break;
|
||||
if (cs->Ignore())
|
||||
continue;
|
||||
requiredstates.push_back(cs);
|
||||
}
|
||||
va_end(argptr);
|
||||
@ -112,19 +144,21 @@ namespace
|
||||
#define MAKE_STATE(name) struct name : State { \
|
||||
virtual void Dump() { \
|
||||
std::cout << " " << #name << std::endl; } \
|
||||
const char *GetName() { return #name; } \
|
||||
};
|
||||
|
||||
#define MAKE_STATE_1(name, p1_type) struct name : State { \
|
||||
p1_type m_Param1; \
|
||||
name(p1_type param1) : m_Param1(param1) {} \
|
||||
virtual bool IsEqual(State *other) { \
|
||||
name *other2 = dynamic_cast<name*>(other); \
|
||||
if (!other2) \
|
||||
if (MakeHash(GetName()) != MakeHash(other->GetName())) \
|
||||
return false; \
|
||||
name *other2 = static_cast<name*>(other); \
|
||||
return other2->m_Param1 == m_Param1;\
|
||||
} \
|
||||
virtual void Dump() { \
|
||||
std::cout << " " << #name << "; Param1=" << m_Param1 << std::endl; } \
|
||||
const char *GetName() { return #name; } \
|
||||
}
|
||||
|
||||
#define MAKE_STATE_2(name, p1_type, p2_type) struct name : State { \
|
||||
@ -132,13 +166,14 @@ namespace
|
||||
p2_type m_Param2; \
|
||||
name(p1_type param1, p2_type param2) : m_Param1(param1), m_Param2(param2) {} \
|
||||
virtual bool IsEqual(State *other) { \
|
||||
name *other2 = dynamic_cast<name*>(other); \
|
||||
if (!other2) \
|
||||
if (MakeHash(GetName()) != MakeHash(other->GetName())) \
|
||||
return false; \
|
||||
name *other2 = static_cast<name*>(other); \
|
||||
return other2->m_Param1 == m_Param1 && other2->m_Param2 == m_Param2;\
|
||||
} \
|
||||
virtual void Dump() { \
|
||||
std::cout << " " << #name << "; Param1=" << m_Param1 << "; Param2=" << m_Param2 << std::endl; } \
|
||||
const char *GetName() { return #name; } \
|
||||
}
|
||||
|
||||
#define MAKE_STATE_3(name, p1_type, p2_type, p3_type) struct name : State { \
|
||||
@ -147,13 +182,31 @@ namespace
|
||||
p3_type m_Param3; \
|
||||
name(p1_type param1, p2_type param2, p3_type param3) : m_Param1(param1), m_Param2(param2), m_Param3(param3) {} \
|
||||
virtual bool IsEqual(State *other) { \
|
||||
name *other2 = dynamic_cast<name*>(other); \
|
||||
if (!other2) \
|
||||
if (MakeHash(GetName()) != MakeHash(other->GetName())) \
|
||||
return false; \
|
||||
name *other2 = static_cast<name*>(other); \
|
||||
return other2->m_Param1 == m_Param1 && other2->m_Param2 == m_Param2 && other2->m_Param3 == m_Param3;\
|
||||
} \
|
||||
virtual void Dump() { \
|
||||
std::cout << " " << #name << "; Param1=" << m_Param1 << "; Param2=" << m_Param2 << "; Param3=" << m_Param3 << std::endl; } \
|
||||
const char *GetName() { return #name; } \
|
||||
}
|
||||
|
||||
#define MAKE_STATE_4(name, p1_type, p2_type, p3_type, p4_type) struct name : State { \
|
||||
p1_type m_Param1; \
|
||||
p2_type m_Param2; \
|
||||
p3_type m_Param3; \
|
||||
p4_type m_Param4; \
|
||||
name(p1_type param1, p2_type param2, p3_type param3, p4_type param4) : m_Param1(param1), m_Param2(param2), m_Param3(param3), m_Param4(param4) {} \
|
||||
virtual bool IsEqual(State *other) { \
|
||||
if (MakeHash(GetName()) != MakeHash(other->GetName())) \
|
||||
return false; \
|
||||
name *other2 = static_cast<name*>(other); \
|
||||
return other2->m_Param1 == m_Param1 && other2->m_Param2 == m_Param2 && other2->m_Param3 == m_Param3 && other2->m_Param4 == m_Param4;\
|
||||
} \
|
||||
virtual void Dump() { \
|
||||
std::cout << " " << #name << "; Param1=" << m_Param1 << "; Param2=" << m_Param2 << "; Param3=" << m_Param3 << "; Param4=" << m_Param4 << std::endl; } \
|
||||
const char *GetName() { return #name; } \
|
||||
}
|
||||
|
||||
#define CHECK_COND(c, err) if (!(c)) { error = err; return false; }
|
||||
|
||||
1229
sourcehook/test/testhookmangen.cpp
Normal file
1229
sourcehook/test/testhookmangen.cpp
Normal file
File diff suppressed because it is too large
Load Diff
2192
sourcehook/test/testhookmangen.h
Normal file
2192
sourcehook/test/testhookmangen.h
Normal file
File diff suppressed because it is too large
Load Diff
584
sourcehook/test/testhookmangen.hxx
Normal file
584
sourcehook/test/testhookmangen.hxx
Normal file
@ -0,0 +1,584 @@
|
||||
struct CAutoReleaseHookMan
|
||||
{
|
||||
SourceHook::HookManagerPubFunc m_Ptr;
|
||||
CAutoReleaseHookMan(SourceHook::HookManagerPubFunc ptr) : m_Ptr(ptr)
|
||||
{
|
||||
}
|
||||
~CAutoReleaseHookMan()
|
||||
{
|
||||
g_HMAGPtr->ReleaseHookMan(m_Ptr);
|
||||
}
|
||||
};
|
||||
|
||||
// Strip &
|
||||
template <class T> struct StripRef
|
||||
{
|
||||
typedef T type;
|
||||
};
|
||||
|
||||
template <class T> struct StripRef<T&>
|
||||
{
|
||||
typedef T type;
|
||||
};
|
||||
|
||||
// Address of constructor/destructor
|
||||
// (using wrappers)
|
||||
template <class T>
|
||||
class Ctor_Thunk
|
||||
{
|
||||
public:
|
||||
void NormalConstructor()
|
||||
{
|
||||
new(this) T;
|
||||
}
|
||||
|
||||
void CopyConstructor(const T &other)
|
||||
{
|
||||
new(this) T(other);
|
||||
}
|
||||
|
||||
void Destructor()
|
||||
{
|
||||
reinterpret_cast<T*>(this)->~T();
|
||||
}
|
||||
|
||||
const T& AssignOp(const T &other)
|
||||
{
|
||||
return (*reinterpret_cast<T*>(this) = other);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
template <class T>
|
||||
void *FindFuncAddr(T mfp)
|
||||
{
|
||||
union
|
||||
{
|
||||
T a;
|
||||
void *b;
|
||||
} u;
|
||||
u.a = mfp;
|
||||
return u.b;
|
||||
}
|
||||
|
||||
// Reference carrier
|
||||
template <class T> struct MyRefCarrier
|
||||
{
|
||||
typedef T type;
|
||||
};
|
||||
|
||||
template <class T> struct MyRefCarrier<T&>
|
||||
{
|
||||
class type
|
||||
{
|
||||
T *m_StoredRef;
|
||||
public:
|
||||
type() : m_StoredRef(NULL)
|
||||
{
|
||||
}
|
||||
type(T& ref) : m_StoredRef(&ref)
|
||||
{
|
||||
}
|
||||
|
||||
T& operator= (T& ref)
|
||||
{
|
||||
m_StoredRef = &ref;
|
||||
return ref;
|
||||
}
|
||||
|
||||
operator T& () const
|
||||
{
|
||||
return *m_StoredRef;
|
||||
}
|
||||
|
||||
bool operator== (const typename MyRefCarrier<T&>::type &other)
|
||||
{
|
||||
return m_StoredRef == other.m_StoredRef;
|
||||
}
|
||||
|
||||
friend std::ostream& operator <<(std::ostream &os,const typename MyRefCarrier<T&>::type &obj)
|
||||
{
|
||||
os << *obj.m_StoredRef;
|
||||
return os;
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
#if SH_COMP==SH_COMP_GCC
|
||||
#define NO_OPTIMIZE __attribute__((noinline))
|
||||
#else
|
||||
#define NO_OPTIMIZE
|
||||
#endif
|
||||
|
||||
// Return value maker
|
||||
template <class T>
|
||||
struct MakeRet
|
||||
{
|
||||
static T Do(int a)
|
||||
{
|
||||
return a;
|
||||
}
|
||||
};
|
||||
|
||||
template <int SIZE>
|
||||
struct MakeRet< POD<SIZE> >
|
||||
{
|
||||
static POD<SIZE> Do(int a)
|
||||
{
|
||||
POD<SIZE> x;
|
||||
memset(reinterpret_cast<void*>(x.x), a, SIZE);
|
||||
return x;
|
||||
}
|
||||
};
|
||||
|
||||
// Stores parameter status
|
||||
template <class T>
|
||||
bool EqualToMyFmtString(T sth)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool EqualToMyFmtString(std::string &sth)
|
||||
{
|
||||
if (sth == "Hello %s%d%s")
|
||||
sth = "Hello BA1L!";
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@[$1,0,$a:
|
||||
|
||||
template<int dummy@[$2,1,$1:, class p$2@]>
|
||||
struct ParamState$1
|
||||
{
|
||||
@[$2,1,$1:typename MyRefCarrier<p$2>::type m_$2; @]
|
||||
|
||||
bool operator==(const ParamState$1<dummy@[$2,1,$1:, p$2@]> &other)
|
||||
{
|
||||
return true
|
||||
@[$2,1,$1: && m_$1 == other.m_$1@]
|
||||
;
|
||||
}
|
||||
ParamState$1(@[$2,1,$1:p$2 a$2, @]...) @[$1!=0::@] @[$2,1,$1|, :m_$2(a$2)@]
|
||||
{
|
||||
@[$2,1,$1:
|
||||
EqualToMyFmtString(m_$2);
|
||||
@]
|
||||
}
|
||||
|
||||
ParamState$1<dummy@[$2,1,$1:, p$2@]> & operator() (int incrsteps)
|
||||
{
|
||||
@[$1!=0:int i;@]
|
||||
@[$2,1,$1:
|
||||
for (i = 0; i < incrsteps; ++i)
|
||||
Increment<typename StripRef< p$2 >::type >::Incr(m_$2);
|
||||
@]
|
||||
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
@[$1!=0:template<@[$2,1,$1|, :class p$2@]>@]
|
||||
std::ostream& operator <<(std::ostream &os,const ParamState$1<0@[$2,1,$1:, p$2@]> &obj)
|
||||
{
|
||||
@[$1!=0:os@] @[$2,1,$1:<< obj.m_$2@];
|
||||
return os;
|
||||
}
|
||||
|
||||
@]
|
||||
|
||||
#define CAT2(a, b) a##b
|
||||
#define CAT3(a, b, c) a##b##c
|
||||
#define CAT4(a, b, c, d) a##b##c##d
|
||||
|
||||
// hook1: pre ignore
|
||||
// hook2: pre supercede
|
||||
// hook3: post ignore
|
||||
// hook4: post supercede
|
||||
|
||||
|
||||
@[$1,0,$a:
|
||||
|
||||
#define THGM_MAKE_TEST$1_void(id@[$2,1,$1:, param$2@]) \
|
||||
struct TestClass##id; \
|
||||
typedef ParamState$1<0@[$2,1,$1:, param$2@] > ParamState_m##id; \
|
||||
MAKE_STATE_2(State_Func##id, TestClass##id* /*thisptr*/, ParamState_m##id ); \
|
||||
MAKE_STATE_4(State_Deleg_##id, int /*delegnumber*/, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \
|
||||
\
|
||||
struct TestClass##id \
|
||||
{ \
|
||||
static bool ms_DoRecall; \
|
||||
\
|
||||
virtual void Func(@[$2,1,$1|, :param$2 p$2@]) \
|
||||
{ \
|
||||
g_Inside_LeafFunc = true; \
|
||||
ADD_STATE(State_Func##id(this, ParamState_m##id(@[$2,1,$1|, :p$2@]))); \
|
||||
g_Inside_LeafFunc = false; \
|
||||
} \
|
||||
\
|
||||
struct Delegate : public MyDelegate \
|
||||
{ \
|
||||
int m_DelegNumber; \
|
||||
Delegate(int num) : m_DelegNumber(num) { } \
|
||||
\
|
||||
virtual void Call(@[$2,1,$1|, :param$2 p$2@]) \
|
||||
{ \
|
||||
g_Inside_LeafFunc = true; \
|
||||
ADD_STATE(State_Deleg_##id(m_DelegNumber, META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(@[$2,1,$1|, :p$2@]))); \
|
||||
g_Inside_LeafFunc = false; \
|
||||
if (ms_DoRecall) \
|
||||
{ \
|
||||
@[$2,1,$1:Increment<StripRef< param$2 >::type>::Incr(p$2);@] \
|
||||
RETURN_META_NEWPARAMS((m_DelegNumber & 1) ? MRES_IGNORED : MRES_SUPERCEDE, &TestClass##id::Func, (@[$2,1,$1|, :p$2@])); \
|
||||
} \
|
||||
else \
|
||||
RETURN_META((m_DelegNumber & 1) ? MRES_IGNORED : MRES_SUPERCEDE); \
|
||||
} \
|
||||
}; \
|
||||
}; \
|
||||
\
|
||||
bool TestClass##id::ms_DoRecall = false; \
|
||||
SourceHook::CProtoInfoBuilder protoinfo_##id(SourceHook::ProtoInfo::CallConv_ThisCall);
|
||||
|
||||
|
||||
#define THGM_MAKE_TEST$1(id, ret_type@[$2,1,$1:, param$2@]) \
|
||||
struct TestClass##id; \
|
||||
typedef ret_type RetType##id; \
|
||||
typedef ParamState$1<0@[$2,1,$1:, param$2@] > ParamState_m##id; \
|
||||
MAKE_STATE_2(State_Func##id, TestClass##id* /*thisptr*/, ParamState_m##id ); \
|
||||
MAKE_STATE_4(State_Deleg_##id, int /*delegnumber*/, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \
|
||||
\
|
||||
struct TestClass##id \
|
||||
{ \
|
||||
static bool ms_DoRecall; \
|
||||
\
|
||||
virtual ret_type Func(@[$2,1,$1|, :param$2 p$2@]) \
|
||||
{ \
|
||||
g_Inside_LeafFunc = true; \
|
||||
ADD_STATE(State_Func##id(this, ParamState_m##id(@[$2,1,$1|, :p$2@]))); \
|
||||
g_Inside_LeafFunc = false; \
|
||||
\
|
||||
return MakeRet< ret_type >::Do(0); \
|
||||
} \
|
||||
\
|
||||
struct Delegate : public MyDelegate \
|
||||
{ \
|
||||
int m_DelegNumber; \
|
||||
Delegate(int num) : m_DelegNumber(num) { } \
|
||||
\
|
||||
virtual ret_type Call(@[$2,1,$1|, :param$2 p$2@]) \
|
||||
{ \
|
||||
g_Inside_LeafFunc = true; \
|
||||
ADD_STATE(State_Deleg_##id(m_DelegNumber, META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(@[$2,1,$1|, :p$2@]))); \
|
||||
g_Inside_LeafFunc = false; \
|
||||
if (ms_DoRecall) \
|
||||
{ \
|
||||
@[$2,1,$1:Increment<StripRef< param$2 >::type>::Incr(p$2);@] \
|
||||
RETURN_META_VALUE_NEWPARAMS((m_DelegNumber & 1) ? MRES_IGNORED : MRES_SUPERCEDE, MakeRet< ret_type >::Do(m_DelegNumber), &TestClass##id::Func, (@[$2,1,$1|, :p$2@])); \
|
||||
} \
|
||||
else \
|
||||
RETURN_META_VALUE((m_DelegNumber & 1) ? MRES_IGNORED : MRES_SUPERCEDE, MakeRet< ret_type >::Do(m_DelegNumber)); \
|
||||
} \
|
||||
}; \
|
||||
}; \
|
||||
\
|
||||
bool TestClass##id::ms_DoRecall = false; \
|
||||
SourceHook::CProtoInfoBuilder protoinfo_##id(SourceHook::ProtoInfo::CallConv_ThisCall);
|
||||
|
||||
#define THGM_MAKE_TEST$1_vafmt_void(id@[$2,1,$1:, param$2@]) \
|
||||
struct TestClass##id; \
|
||||
typedef ParamState@($1+1)<0@[$2,1,$1:, param$2@], std::string > ParamState_m##id; \
|
||||
MAKE_STATE_2(State_Func##id, TestClass##id* /*thisptr*/, ParamState_m##id ); \
|
||||
MAKE_STATE_4(State_Deleg_##id, int /*delegnumber*/, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \
|
||||
\
|
||||
struct TestClass##id \
|
||||
{ \
|
||||
static bool ms_DoRecall; \
|
||||
\
|
||||
virtual void Func(@[$2,1,$1:param$2 p$2, @]const char *fmt, ...) \
|
||||
{ \
|
||||
g_Inside_LeafFunc = true; \
|
||||
\
|
||||
char buf[9999]; \
|
||||
va_list ap; \
|
||||
va_start(ap, fmt); \
|
||||
vsnprintf(buf, 9998, fmt, ap); \
|
||||
buf[9998] = 0; \
|
||||
va_end(ap); \
|
||||
\
|
||||
ADD_STATE(State_Func##id(this, ParamState_m##id(@[$2,1,$1:p$2, @]std::string(buf)))); \
|
||||
g_Inside_LeafFunc = false; \
|
||||
} \
|
||||
\
|
||||
struct Delegate : public MyDelegate \
|
||||
{ \
|
||||
int m_DelegNumber; \
|
||||
Delegate(int num) : m_DelegNumber(num) { } \
|
||||
\
|
||||
virtual void Call(@[$2,1,$1:param$2 p$2, @]const char *buf) \
|
||||
{ \
|
||||
g_Inside_LeafFunc = true; \
|
||||
ADD_STATE(State_Deleg_##id(m_DelegNumber, META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(@[$2,1,$1:p$2, @]buf))); \
|
||||
g_Inside_LeafFunc = false; \
|
||||
if (ms_DoRecall) \
|
||||
{ \
|
||||
@[$2,1,$1:Increment<StripRef< param$2 >::type>::Incr(p$2);@] \
|
||||
RETURN_META_NEWPARAMS((m_DelegNumber & 1) ? MRES_IGNORED : MRES_SUPERCEDE, &TestClass##id::Func, (@[$2,1,$1:p$2, @]"%s!", buf)); \
|
||||
} \
|
||||
else \
|
||||
RETURN_META((m_DelegNumber & 1) ? MRES_IGNORED : MRES_SUPERCEDE); \
|
||||
} \
|
||||
}; \
|
||||
}; \
|
||||
\
|
||||
bool TestClass##id::ms_DoRecall = false; \
|
||||
SourceHook::CProtoInfoBuilder protoinfo_##id(SourceHook::ProtoInfo::CallConv_ThisCall | SourceHook::ProtoInfo::CallConv_HasVafmt);
|
||||
|
||||
#define THGM_MAKE_TEST$1_vafmt(id, ret_type@[$2,1,$1:, param$2@]) \
|
||||
struct TestClass##id; \
|
||||
typedef ret_type RetType##id; \
|
||||
typedef ParamState@($1+1)<0@[$2,1,$1:, param$2@], std::string > ParamState_m##id; \
|
||||
MAKE_STATE_2(State_Func##id, TestClass##id* /*thisptr*/, ParamState_m##id ); \
|
||||
MAKE_STATE_4(State_Deleg_##id, int /*delegnumber*/, TestClass##id* /*ifptr*/, int /*deleg thisptr*/, ParamState_m##id ); \
|
||||
\
|
||||
struct TestClass##id \
|
||||
{ \
|
||||
static bool ms_DoRecall; \
|
||||
\
|
||||
virtual ret_type Func(@[$2,1,$1:param$2 p$2, @]const char *fmt, ...) \
|
||||
{ \
|
||||
g_Inside_LeafFunc = true; \
|
||||
\
|
||||
char buf[9999]; \
|
||||
va_list ap; \
|
||||
va_start(ap, fmt); \
|
||||
vsnprintf(buf, 9998, fmt, ap); \
|
||||
buf[9998] = 0; \
|
||||
va_end(ap); \
|
||||
\
|
||||
ADD_STATE(State_Func##id(this, ParamState_m##id(@[$2,1,$1:p$2, @]std::string(buf)))); \
|
||||
\
|
||||
return MakeRet< ret_type >::Do(0); \
|
||||
} \
|
||||
\
|
||||
struct Delegate : public MyDelegate \
|
||||
{ \
|
||||
int m_DelegNumber; \
|
||||
Delegate(int num) : m_DelegNumber(num) { } \
|
||||
\
|
||||
virtual ret_type Call(@[$2,1,$1:param$2 p$2, @]const char *buf) \
|
||||
{ \
|
||||
g_Inside_LeafFunc = true; \
|
||||
ADD_STATE(State_Deleg_##id(m_DelegNumber, META_IFACEPTR(TestClass##id), PtrBuf(this), ParamState_m##id(@[$2,1,$1:p$2, @]buf))); \
|
||||
g_Inside_LeafFunc = false; \
|
||||
if (ms_DoRecall) \
|
||||
{ \
|
||||
@[$2,1,$1:Increment<StripRef< param$2 >::type>::Incr(p$2);@] \
|
||||
RETURN_META_VALUE_NEWPARAMS((m_DelegNumber & 1) ? MRES_IGNORED : MRES_SUPERCEDE, MakeRet< ret_type >::Do(m_DelegNumber), &TestClass##id::Func, (@[$2,1,$1:p$2, @]"%s!", buf)); \
|
||||
} \
|
||||
else \
|
||||
RETURN_META_VALUE((m_DelegNumber & 1) ? MRES_IGNORED : MRES_SUPERCEDE, MakeRet< ret_type >::Do(m_DelegNumber)); \
|
||||
} \
|
||||
}; \
|
||||
}; \
|
||||
\
|
||||
bool TestClass##id::ms_DoRecall = false; \
|
||||
SourceHook::CProtoInfoBuilder protoinfo_##id(SourceHook::ProtoInfo::CallConv_ThisCall | SourceHook::ProtoInfo::CallConv_HasVafmt);
|
||||
|
||||
#define THGM_SETUP_PI$1(id@[$2,1,$1:, p$2_type, p$2_passtype, p$2_flags@]) \
|
||||
void setuppi_##id() \
|
||||
{ \
|
||||
@[$2,1,$1: \
|
||||
protoinfo_##id.AddParam(sizeof(p$2_type), p$2_passtype, p$2_flags, \
|
||||
(p$2_flags & SourceHook::PassInfo::PassFlag_OCtor) ? FindFuncAddr(&Ctor_Thunk<StripRef< p$2_type >::type>::NormalConstructor) : NULL, \
|
||||
(p$2_flags & SourceHook::PassInfo::PassFlag_CCtor) ? FindFuncAddr(&Ctor_Thunk<StripRef< p$2_type >::type>::CopyConstructor) : NULL, \
|
||||
(p$2_flags & SourceHook::PassInfo::PassFlag_ODtor) ? FindFuncAddr(&Ctor_Thunk<StripRef< p$2_type >::type>::Destructor) : NULL, \
|
||||
(p$2_flags & SourceHook::PassInfo::PassFlag_AssignOp) ? FindFuncAddr(&Ctor_Thunk<StripRef< p$2_type >::type>::AssignOp) : NULL \
|
||||
); \
|
||||
@] \
|
||||
}
|
||||
|
||||
@]
|
||||
|
||||
#define THGM_SETUP_RI(id, ret_type, ret_passtype, ret_flags) \
|
||||
void setupri_##id() \
|
||||
{ \
|
||||
protoinfo_##id.SetReturnType(sizeof(ret_type), ret_passtype, ret_flags, \
|
||||
(ret_flags & SourceHook::PassInfo::PassFlag_OCtor) ? FindFuncAddr(&Ctor_Thunk<StripRef< ret_type >::type>::NormalConstructor) : NULL, \
|
||||
(ret_flags & SourceHook::PassInfo::PassFlag_CCtor) ? FindFuncAddr(&Ctor_Thunk<StripRef< ret_type >::type>::CopyConstructor) : NULL, \
|
||||
(ret_flags & SourceHook::PassInfo::PassFlag_ODtor) ? FindFuncAddr(&Ctor_Thunk<StripRef< ret_type >::type>::Destructor) : NULL, \
|
||||
(ret_flags & SourceHook::PassInfo::PassFlag_AssignOp) ? FindFuncAddr(&Ctor_Thunk<StripRef< ret_type >::type>::AssignOp) : NULL \
|
||||
); \
|
||||
}
|
||||
|
||||
#define THGM_ADD_HOOK(id, num) \
|
||||
CAT4(hook, num, _, id) = g_SHPtr->AddHook(g_PLID, SourceHook::ISourceHook::Hook_Normal, reinterpret_cast<void*>(pTest##id), \
|
||||
0, myhookman##id, PtrBufPtr(new TestClass##id::Delegate(num)), num >= 3);
|
||||
|
||||
#define THGM_REMOVE_HOOK(id, num) \
|
||||
g_SHPtr->RemoveHookByID(CAT4(hook, num, _, id));
|
||||
|
||||
#define THGM_CALLS_void(id, call_params) \
|
||||
pTest##id->Func call_params; \
|
||||
SH_CALL(pTest##id, &TestClass##id::Func) call_params;
|
||||
|
||||
#define THGM_DO_TEST_void(id, call_params) \
|
||||
setuppi_##id(); \
|
||||
SourceHook::HookManagerPubFunc myhookman##id = g_HMAGPtr->MakeHookMan(protoinfo_##id, 0, 0); \
|
||||
CAutoReleaseHookMan arhm_##id(myhookman##id); \
|
||||
int hook1_##id, hook2_##id, hook3_##id, hook4_##id; \
|
||||
\
|
||||
TestClass##id::ms_DoRecall = false; \
|
||||
TestClass##id *pTest##id = new TestClass##id; \
|
||||
CAutoPtrDestruction<TestClass##id> apd##id(pTest##id); \
|
||||
\
|
||||
/* no hooks - no hooks */ \
|
||||
PtrBuf_Clear(); \
|
||||
THGM_CALLS_void(id, call_params); \
|
||||
CHECK_STATES((&g_States, \
|
||||
new State_Func##id(pTest##id, ParamState_m##id call_params), \
|
||||
new State_Func##id(pTest##id, ParamState_m##id call_params), \
|
||||
NULL), "Test" #id " Part1"); \
|
||||
\
|
||||
/* hook1 - hook3 */ \
|
||||
PtrBuf_Clear(); \
|
||||
THGM_ADD_HOOK(id, 1); \
|
||||
THGM_ADD_HOOK(id, 3); \
|
||||
THGM_CALLS_void(id, call_params); \
|
||||
CHECK_STATES((&g_States, \
|
||||
new State_Deleg_##id(1, pTest##id, 0, ParamState_m##id call_params), \
|
||||
new State_Func##id(pTest##id, ParamState_m##id call_params), \
|
||||
new State_Deleg_##id(3, pTest##id, 1, ParamState_m##id call_params), \
|
||||
new State_Func##id(pTest##id, ParamState_m##id call_params), \
|
||||
NULL), "Test" #id " Part4"); \
|
||||
THGM_REMOVE_HOOK(id, 1); \
|
||||
THGM_REMOVE_HOOK(id, 3); \
|
||||
\
|
||||
/* hook1, hook2 - hook3 */ \
|
||||
PtrBuf_Clear(); \
|
||||
THGM_ADD_HOOK(id, 1); \
|
||||
THGM_ADD_HOOK(id, 2); \
|
||||
THGM_ADD_HOOK(id, 3); \
|
||||
THGM_CALLS_void(id, call_params); \
|
||||
CHECK_STATES((&g_States, \
|
||||
new State_Deleg_##id(1, pTest##id, 0, ParamState_m##id call_params), \
|
||||
new State_Deleg_##id(2, pTest##id, 1, ParamState_m##id call_params), \
|
||||
new State_Deleg_##id(3, pTest##id, 2, ParamState_m##id call_params), \
|
||||
new State_Func##id(pTest##id, ParamState_m##id call_params), \
|
||||
NULL), "Test" #id " Part5"); \
|
||||
/* hook1, hook2 - hook3, hook4 */ \
|
||||
THGM_ADD_HOOK(id, 4); \
|
||||
THGM_CALLS_void(id, call_params); \
|
||||
CHECK_STATES((&g_States, \
|
||||
new State_Deleg_##id(1, pTest##id, 0, ParamState_m##id call_params), \
|
||||
new State_Deleg_##id(2, pTest##id, 1, ParamState_m##id call_params), \
|
||||
new State_Deleg_##id(3, pTest##id, 2, ParamState_m##id call_params), \
|
||||
new State_Deleg_##id(4, pTest##id, 3, ParamState_m##id call_params), \
|
||||
new State_Func##id(pTest##id, ParamState_m##id call_params), \
|
||||
NULL), "Test" #id " Part6"); \
|
||||
\
|
||||
/* hook1 - hook3, hook4, with recalls! */ \
|
||||
\
|
||||
TestClass##id::ms_DoRecall = true; \
|
||||
THGM_REMOVE_HOOK(id, 2); \
|
||||
THGM_CALLS_void(id, call_params); \
|
||||
CHECK_STATES((&g_States, \
|
||||
new State_Deleg_##id(1, pTest##id, 0, ParamState_m##id call_params(0)), \
|
||||
new State_Func##id(pTest##id, ParamState_m##id call_params(1)), \
|
||||
new State_Deleg_##id(3, pTest##id, 2, ParamState_m##id call_params(1)), \
|
||||
new State_Deleg_##id(4, pTest##id, 3, ParamState_m##id call_params(2)), \
|
||||
/* sh_call one */ \
|
||||
new State_Func##id(pTest##id, ParamState_m##id call_params), \
|
||||
NULL), "Test" #id " Part7"); \
|
||||
THGM_REMOVE_HOOK(id, 1); \
|
||||
THGM_REMOVE_HOOK(id, 3); \
|
||||
THGM_REMOVE_HOOK(id, 4);
|
||||
|
||||
template<class T>
|
||||
T ComparableRef(T x)
|
||||
{
|
||||
return x;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
T* ComparableRef(T& x)
|
||||
{
|
||||
return &x;
|
||||
}
|
||||
|
||||
#define THGM_CALLS(id, call_params, exp_ret_norm, exp_ret_shcall, err) \
|
||||
CHECK_COND(ComparableRef<RetType##id>(pTest##id->Func call_params) == ComparableRef<RetType##id>(MakeRet< RetType##id >::Do(exp_ret_norm)), err " /retcallnorm"); \
|
||||
CHECK_COND(ComparableRef<RetType##id>(SH_CALL(pTest##id, &TestClass##id::Func) call_params) == ComparableRef<RetType##id>(MakeRet< RetType##id >::Do(exp_ret_shcall)), err " /retcallshcall");
|
||||
|
||||
#define THGM_DO_TEST(id, call_params) \
|
||||
setuppi_##id(); \
|
||||
setupri_##id(); \
|
||||
SourceHook::HookManagerPubFunc myhookman##id = g_HMAGPtr->MakeHookMan(protoinfo_##id, 0, 0); \
|
||||
CAutoReleaseHookMan arhm_##id(myhookman##id); \
|
||||
int hook1_##id, hook2_##id, hook3_##id, hook4_##id; \
|
||||
\
|
||||
TestClass##id::ms_DoRecall = false; \
|
||||
TestClass##id *pTest##id = new TestClass##id; \
|
||||
CAutoPtrDestruction<TestClass##id> apd##id(pTest##id); \
|
||||
\
|
||||
/* no hooks - no hooks */ \
|
||||
PtrBuf_Clear(); \
|
||||
THGM_CALLS(id, call_params, 0, 0, "Part1"); \
|
||||
CHECK_STATES((&g_States, \
|
||||
new State_Func##id(pTest##id, ParamState_m##id call_params), \
|
||||
new State_Func##id(pTest##id, ParamState_m##id call_params), \
|
||||
NULL), "Test" #id " Part1"); \
|
||||
\
|
||||
/* hook1 - hook3 */ \
|
||||
PtrBuf_Clear(); \
|
||||
THGM_ADD_HOOK(id, 1); \
|
||||
THGM_ADD_HOOK(id, 3); \
|
||||
THGM_CALLS(id, call_params, 0, 0, "Part4"); \
|
||||
CHECK_STATES((&g_States, \
|
||||
new State_Deleg_##id(1, pTest##id, 0, ParamState_m##id call_params), \
|
||||
new State_Func##id(pTest##id, ParamState_m##id call_params), \
|
||||
new State_Deleg_##id(3, pTest##id, 1, ParamState_m##id call_params), \
|
||||
new State_Func##id(pTest##id, ParamState_m##id call_params), \
|
||||
NULL), "Test" #id " Part4"); \
|
||||
THGM_REMOVE_HOOK(id, 1); \
|
||||
THGM_REMOVE_HOOK(id, 3); \
|
||||
\
|
||||
/* hook1, hook2 - hook3 */ \
|
||||
PtrBuf_Clear(); \
|
||||
THGM_ADD_HOOK(id, 1); \
|
||||
THGM_ADD_HOOK(id, 2); \
|
||||
THGM_ADD_HOOK(id, 3); \
|
||||
THGM_CALLS(id, call_params, 2, 0, "Part5"); \
|
||||
CHECK_STATES((&g_States, \
|
||||
new State_Deleg_##id(1, pTest##id, 0, ParamState_m##id call_params), \
|
||||
new State_Deleg_##id(2, pTest##id, 1, ParamState_m##id call_params), \
|
||||
new State_Deleg_##id(3, pTest##id, 2, ParamState_m##id call_params), \
|
||||
new State_Func##id(pTest##id, ParamState_m##id call_params), \
|
||||
NULL), "Test" #id " Part5"); \
|
||||
/* hook1, hook2 - hook3, hook4 */ \
|
||||
THGM_ADD_HOOK(id, 4); \
|
||||
THGM_CALLS(id, call_params, 4, 0, "Part6"); \
|
||||
CHECK_STATES((&g_States, \
|
||||
new State_Deleg_##id(1, pTest##id, 0, ParamState_m##id call_params), \
|
||||
new State_Deleg_##id(2, pTest##id, 1, ParamState_m##id call_params), \
|
||||
new State_Deleg_##id(3, pTest##id, 2, ParamState_m##id call_params), \
|
||||
new State_Deleg_##id(4, pTest##id, 3, ParamState_m##id call_params), \
|
||||
new State_Func##id(pTest##id, ParamState_m##id call_params), \
|
||||
NULL), "Test" #id " Part6"); \
|
||||
\
|
||||
/* hook1 - hook3, hook4, with recalls! */ \
|
||||
\
|
||||
TestClass##id::ms_DoRecall = true; \
|
||||
THGM_REMOVE_HOOK(id, 2); \
|
||||
THGM_CALLS(id, call_params, 4, 0, "Part7"); \
|
||||
CHECK_STATES((&g_States, \
|
||||
new State_Deleg_##id(1, pTest##id, 0, ParamState_m##id call_params(0)), \
|
||||
new State_Func##id(pTest##id, ParamState_m##id call_params(1)), \
|
||||
new State_Deleg_##id(3, pTest##id, 2, ParamState_m##id call_params(1)), \
|
||||
new State_Deleg_##id(4, pTest##id, 3, ParamState_m##id call_params(2)), \
|
||||
/* sh_call one */ \
|
||||
new State_Func##id(pTest##id, ParamState_m##id call_params), \
|
||||
NULL), "Test" #id " Part7"); \
|
||||
THGM_REMOVE_HOOK(id, 1); \
|
||||
THGM_REMOVE_HOOK(id, 3); \
|
||||
THGM_REMOVE_HOOK(id, 4);
|
||||
@ -49,6 +49,7 @@
|
||||
|
||||
#define MMIFACE_SOURCEHOOK "ISourceHook" /**< ISourceHook Pointer */
|
||||
#define MMIFACE_PLMANAGER "IPluginManager" /**< SourceMM Plugin Functions */
|
||||
#define MMIFACE_SH_HOOKMANAUTOGEN "IHookManagerAutoGen" /**< SourceHook::IHookManagerAutoGen Pointer */
|
||||
#define IFACE_MAXNUM 999 /**< Maximum interface version */
|
||||
|
||||
namespace SourceMM
|
||||
|
||||
@ -17,7 +17,7 @@ HL2PUB = $(HL2SDK)/public
|
||||
HL2LIB = $(HL2SDK)/linux_sdk
|
||||
|
||||
OBJECTS = metamod.cpp metamod_util.cpp metamod_console.cpp metamod_oslink.cpp metamod_plugins.cpp \
|
||||
sourcehook.cpp episode1/console.cpp episode1/provider_ep1.cpp episode1/vsp_listener.cpp
|
||||
sourcehook.cpp sourcehook_hookmangen.cpp episode1/console.cpp episode1/provider_ep1.cpp episode1/vsp_listener.cpp
|
||||
|
||||
LINK = $(HL2LIB)/tier1_i486.a vstdlib_i486.so tier0_i486.so -static-libgcc
|
||||
|
||||
@ -56,6 +56,7 @@ all:
|
||||
ln -sf $(SRCDS)/bin/vstdlib_i486.so vstdlib_i486.so
|
||||
ln -sf $(SRCDS)/bin/tier0_i486.so tier0_i486.so
|
||||
ln -sf $(SMM_ROOT)/sourcehook/sourcehook.cpp sourcehook.cpp
|
||||
ln -sf $(SMM_ROOT)/sourcehook/sourcehook_hookmangen.cpp sourcehook_hookmangen.cpp
|
||||
$(MAKE) -f Makefile.ep1 sourcemm
|
||||
rm -rf $(BINARY)
|
||||
ln -sf $(BIN_DIR)/$(BINARY) $(BINARY)
|
||||
|
||||
@ -17,7 +17,7 @@ HL2PUB = $(HL2SDK)/public
|
||||
HL2LIB = $(HL2SDK)/linux_sdk
|
||||
|
||||
OBJECTS = metamod.cpp metamod_util.cpp metamod_console.cpp metamod_oslink.cpp metamod_plugins.cpp \
|
||||
sourcehook.cpp episode2/console.cpp episode2/provider_ep2.cpp episode2/vsp_listener.cpp
|
||||
sourcehook.cpp sourcehook_hookmangen.cpp episode2/console.cpp episode2/provider_ep2.cpp episode2/vsp_listener.cpp
|
||||
|
||||
LINK = $(HL2SDK)/linux_sdk/tier1_i486.a vstdlib_i486.so tier0_i486.so -static-libgcc
|
||||
|
||||
@ -56,6 +56,7 @@ all:
|
||||
ln -sf $(SRCDS)/bin/vstdlib_i486.so vstdlib_i486.so
|
||||
ln -sf $(SRCDS)/bin/tier0_i486.so tier0_i486.so
|
||||
ln -sf $(SMM_ROOT)/sourcehook/sourcehook.cpp sourcehook.cpp
|
||||
ln -sf $(SMM_ROOT)/sourcehook/sourcehook_hookmangen.cpp sourcehook_hookmangen.cpp
|
||||
$(MAKE) -f Makefile.ep2 sourcemm
|
||||
rm -rf $(BINARY)
|
||||
ln -sf $(BIN_DIR)/$(BINARY) $(BINARY)
|
||||
|
||||
@ -331,6 +331,11 @@
|
||||
RelativePath="..\..\..\sourcehook\sourcehook.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\sourcehook\sourcehook_hookmangen.cpp"
|
||||
>
|
||||
</File>
|
||||
|
||||
</Filter>
|
||||
</Files>
|
||||
<Globals>
|
||||
|
||||
@ -327,6 +327,10 @@
|
||||
RelativePath="..\..\..\sourcehook\sourcehook.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\sourcehook\sourcehook_hookmangen.cpp"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
</Files>
|
||||
<Globals>
|
||||
|
||||
@ -94,6 +94,7 @@ CreateInterfaceFn physics_factory = NULL;
|
||||
CreateInterfaceFn filesystem_factory = NULL;
|
||||
CGlobalVars *gpGlobals = NULL;
|
||||
CSourceHookImpl g_SourceHook;
|
||||
CHookManagerAutoGen g_SH_HookManagerAutoGen(&g_SourceHook);
|
||||
ISourceHook *g_SHPtr = &g_SourceHook;
|
||||
PluginId g_PLID = Pl_Console;
|
||||
META_RES last_meta_res;
|
||||
@ -1090,6 +1091,14 @@ void *MetamodSource::MetaFactory(const char *iface, int *ret, PluginId *id)
|
||||
}
|
||||
return static_cast<void *>(static_cast<ISmmPluginManager *>(&g_PluginMngr));
|
||||
}
|
||||
else if (strcmp(iface, MMIFACE_SH_HOOKMANAUTOGEN) == 0)
|
||||
{
|
||||
if (ret)
|
||||
{
|
||||
*ret = IFACE_OK;
|
||||
}
|
||||
return static_cast<void *>(static_cast<SourceHook::IHookManagerAutoGen *>(&g_SH_HookManagerAutoGen));
|
||||
}
|
||||
|
||||
CPluginManager::CPlugin *pl;
|
||||
List<IMetamodListener *>::iterator event;
|
||||
|
||||
@ -37,6 +37,7 @@
|
||||
#include <interface.h>
|
||||
#include <eiface.h>
|
||||
#include <sourcehook/sourcehook_impl.h>
|
||||
#include <sourcehook/sourcehook_hookmangen.h>
|
||||
#include <sourcehook/sourcehook.h>
|
||||
#include <ISmmPlugin.h>
|
||||
#include "metamod_provider.h"
|
||||
|
||||
Loading…
Reference in New Issue
Block a user