New auto-hookfunc-gen friendly interface

! breaks binary compatibility !

--HG--
extra : convert_revision : svn%3Ac2935e3e-5518-0410-8daf-afa5dab7d4e3/trunk%40465
This commit is contained in:
Pavol Marko 2007-10-07 22:10:07 +00:00
parent ffb560abea
commit 47984a6cb3
28 changed files with 3553 additions and 9861 deletions

File diff suppressed because it is too large Load Diff

View File

@ -402,188 +402,6 @@ namespace SourceHook
MFI_Impl<sizeof(mfp2)>::GetFuncInfo(mfp2, out);
}
template<class X, class Y, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8>
inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8), MemFuncInfo &out)
{
RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8) = mfp;
MFI_Impl<sizeof(mfp2)>::GetFuncInfo(mfp2, out);
}
template<class X, class Y, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8>
inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8) const, MemFuncInfo &out)
{
RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8) const = mfp;
MFI_Impl<sizeof(mfp2)>::GetFuncInfo(mfp2, out);
}
template<class X, class Y, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8, class Param9>
inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9), MemFuncInfo &out)
{
RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9) = mfp;
MFI_Impl<sizeof(mfp2)>::GetFuncInfo(mfp2, out);
}
template<class X, class Y, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8, class Param9>
inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9) const, MemFuncInfo &out)
{
RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9) const = mfp;
MFI_Impl<sizeof(mfp2)>::GetFuncInfo(mfp2, out);
}
template<class X, class Y, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8, class Param9, class Param10>
inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10), MemFuncInfo &out)
{
RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10) = mfp;
MFI_Impl<sizeof(mfp2)>::GetFuncInfo(mfp2, out);
}
template<class X, class Y, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8, class Param9, class Param10>
inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10) const, MemFuncInfo &out)
{
RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10) const = mfp;
MFI_Impl<sizeof(mfp2)>::GetFuncInfo(mfp2, out);
}
template<class X, class Y, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8, class Param9, class Param10, class Param11>
inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11), MemFuncInfo &out)
{
RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11) = mfp;
MFI_Impl<sizeof(mfp2)>::GetFuncInfo(mfp2, out);
}
template<class X, class Y, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8, class Param9, class Param10, class Param11>
inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11) const, MemFuncInfo &out)
{
RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11) const = mfp;
MFI_Impl<sizeof(mfp2)>::GetFuncInfo(mfp2, out);
}
template<class X, class Y, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8, class Param9, class Param10, class Param11, class Param12>
inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12), MemFuncInfo &out)
{
RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12) = mfp;
MFI_Impl<sizeof(mfp2)>::GetFuncInfo(mfp2, out);
}
template<class X, class Y, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8, class Param9, class Param10, class Param11, class Param12>
inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12) const, MemFuncInfo &out)
{
RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12) const = mfp;
MFI_Impl<sizeof(mfp2)>::GetFuncInfo(mfp2, out);
}
template<class X, class Y, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8, class Param9, class Param10, class Param11, class Param12, class Param13>
inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13), MemFuncInfo &out)
{
RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13) = mfp;
MFI_Impl<sizeof(mfp2)>::GetFuncInfo(mfp2, out);
}
template<class X, class Y, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8, class Param9, class Param10, class Param11, class Param12, class Param13>
inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13) const, MemFuncInfo &out)
{
RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13) const = mfp;
MFI_Impl<sizeof(mfp2)>::GetFuncInfo(mfp2, out);
}
template<class X, class Y, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8, class Param9, class Param10, class Param11, class Param12, class Param13, class Param14>
inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14), MemFuncInfo &out)
{
RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14) = mfp;
MFI_Impl<sizeof(mfp2)>::GetFuncInfo(mfp2, out);
}
template<class X, class Y, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8, class Param9, class Param10, class Param11, class Param12, class Param13, class Param14>
inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14) const, MemFuncInfo &out)
{
RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14) const = mfp;
MFI_Impl<sizeof(mfp2)>::GetFuncInfo(mfp2, out);
}
template<class X, class Y, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8, class Param9, class Param10, class Param11, class Param12, class Param13, class Param14, class Param15>
inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15), MemFuncInfo &out)
{
RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15) = mfp;
MFI_Impl<sizeof(mfp2)>::GetFuncInfo(mfp2, out);
}
template<class X, class Y, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8, class Param9, class Param10, class Param11, class Param12, class Param13, class Param14, class Param15>
inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15) const, MemFuncInfo &out)
{
RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15) const = mfp;
MFI_Impl<sizeof(mfp2)>::GetFuncInfo(mfp2, out);
}
template<class X, class Y, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8, class Param9, class Param10, class Param11, class Param12, class Param13, class Param14, class Param15, class Param16>
inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, Param16), MemFuncInfo &out)
{
RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, Param16) = mfp;
MFI_Impl<sizeof(mfp2)>::GetFuncInfo(mfp2, out);
}
template<class X, class Y, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8, class Param9, class Param10, class Param11, class Param12, class Param13, class Param14, class Param15, class Param16>
inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, Param16) const, MemFuncInfo &out)
{
RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, Param16) const = mfp;
MFI_Impl<sizeof(mfp2)>::GetFuncInfo(mfp2, out);
}
template<class X, class Y, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8, class Param9, class Param10, class Param11, class Param12, class Param13, class Param14, class Param15, class Param16, class Param17>
inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, Param16, Param17), MemFuncInfo &out)
{
RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, Param16, Param17) = mfp;
MFI_Impl<sizeof(mfp2)>::GetFuncInfo(mfp2, out);
}
template<class X, class Y, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8, class Param9, class Param10, class Param11, class Param12, class Param13, class Param14, class Param15, class Param16, class Param17>
inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, Param16, Param17) const, MemFuncInfo &out)
{
RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, Param16, Param17) const = mfp;
MFI_Impl<sizeof(mfp2)>::GetFuncInfo(mfp2, out);
}
template<class X, class Y, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8, class Param9, class Param10, class Param11, class Param12, class Param13, class Param14, class Param15, class Param16, class Param17, class Param18>
inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, Param16, Param17, Param18), MemFuncInfo &out)
{
RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, Param16, Param17, Param18) = mfp;
MFI_Impl<sizeof(mfp2)>::GetFuncInfo(mfp2, out);
}
template<class X, class Y, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8, class Param9, class Param10, class Param11, class Param12, class Param13, class Param14, class Param15, class Param16, class Param17, class Param18>
inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, Param16, Param17, Param18) const, MemFuncInfo &out)
{
RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, Param16, Param17, Param18) const = mfp;
MFI_Impl<sizeof(mfp2)>::GetFuncInfo(mfp2, out);
}
template<class X, class Y, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8, class Param9, class Param10, class Param11, class Param12, class Param13, class Param14, class Param15, class Param16, class Param17, class Param18, class Param19>
inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, Param16, Param17, Param18, Param19), MemFuncInfo &out)
{
RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, Param16, Param17, Param18, Param19) = mfp;
MFI_Impl<sizeof(mfp2)>::GetFuncInfo(mfp2, out);
}
template<class X, class Y, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8, class Param9, class Param10, class Param11, class Param12, class Param13, class Param14, class Param15, class Param16, class Param17, class Param18, class Param19>
inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, Param16, Param17, Param18, Param19) const, MemFuncInfo &out)
{
RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, Param16, Param17, Param18, Param19) const = mfp;
MFI_Impl<sizeof(mfp2)>::GetFuncInfo(mfp2, out);
}
template<class X, class Y, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8, class Param9, class Param10, class Param11, class Param12, class Param13, class Param14, class Param15, class Param16, class Param17, class Param18, class Param19, class Param20>
inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, Param16, Param17, Param18, Param19, Param20), MemFuncInfo &out)
{
RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, Param16, Param17, Param18, Param19, Param20) = mfp;
MFI_Impl<sizeof(mfp2)>::GetFuncInfo(mfp2, out);
}
template<class X, class Y, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8, class Param9, class Param10, class Param11, class Param12, class Param13, class Param14, class Param15, class Param16, class Param17, class Param18, class Param19, class Param20>
inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, Param16, Param17, Param18, Param19, Param20) const, MemFuncInfo &out)
{
RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, Param16, Param17, Param18, Param19, Param20) const = mfp;
MFI_Impl<sizeof(mfp2)>::GetFuncInfo(mfp2, out);
}
// GCC & MSVC 7.1 need this, MSVC 7.0 doesn't like it
#if SH_COMP != SH_COMP_MSVC || _MSC_VER > 1300
@ -709,201 +527,6 @@ namespace SourceHook
}
template<class X, class Y, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8>
inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, ...), MemFuncInfo &out)
{
RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, ...) = mfp;
MFI_Impl<sizeof(mfp2)>::GetFuncInfo(mfp2, out);
}
template<class X, class Y, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8>
inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, ...) const, MemFuncInfo &out)
{
RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, ...) const = mfp;
MFI_Impl<sizeof(mfp2)>::GetFuncInfo(mfp2, out);
}
template<class X, class Y, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8, class Param9>
inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, ...), MemFuncInfo &out)
{
RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, ...) = mfp;
MFI_Impl<sizeof(mfp2)>::GetFuncInfo(mfp2, out);
}
template<class X, class Y, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8, class Param9>
inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, ...) const, MemFuncInfo &out)
{
RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, ...) const = mfp;
MFI_Impl<sizeof(mfp2)>::GetFuncInfo(mfp2, out);
}
template<class X, class Y, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8, class Param9, class Param10>
inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, ...), MemFuncInfo &out)
{
RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, ...) = mfp;
MFI_Impl<sizeof(mfp2)>::GetFuncInfo(mfp2, out);
}
template<class X, class Y, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8, class Param9, class Param10>
inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, ...) const, MemFuncInfo &out)
{
RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, ...) const = mfp;
MFI_Impl<sizeof(mfp2)>::GetFuncInfo(mfp2, out);
}
template<class X, class Y, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8, class Param9, class Param10, class Param11>
inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, ...), MemFuncInfo &out)
{
RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, ...) = mfp;
MFI_Impl<sizeof(mfp2)>::GetFuncInfo(mfp2, out);
}
template<class X, class Y, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8, class Param9, class Param10, class Param11>
inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, ...) const, MemFuncInfo &out)
{
RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, ...) const = mfp;
MFI_Impl<sizeof(mfp2)>::GetFuncInfo(mfp2, out);
}
template<class X, class Y, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8, class Param9, class Param10, class Param11, class Param12>
inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, ...), MemFuncInfo &out)
{
RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, ...) = mfp;
MFI_Impl<sizeof(mfp2)>::GetFuncInfo(mfp2, out);
}
template<class X, class Y, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8, class Param9, class Param10, class Param11, class Param12>
inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, ...) const, MemFuncInfo &out)
{
RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, ...) const = mfp;
MFI_Impl<sizeof(mfp2)>::GetFuncInfo(mfp2, out);
}
template<class X, class Y, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8, class Param9, class Param10, class Param11, class Param12, class Param13>
inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, ...), MemFuncInfo &out)
{
RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, ...) = mfp;
MFI_Impl<sizeof(mfp2)>::GetFuncInfo(mfp2, out);
}
template<class X, class Y, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8, class Param9, class Param10, class Param11, class Param12, class Param13>
inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, ...) const, MemFuncInfo &out)
{
RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, ...) const = mfp;
MFI_Impl<sizeof(mfp2)>::GetFuncInfo(mfp2, out);
}
template<class X, class Y, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8, class Param9, class Param10, class Param11, class Param12, class Param13, class Param14>
inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, ...), MemFuncInfo &out)
{
RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, ...) = mfp;
MFI_Impl<sizeof(mfp2)>::GetFuncInfo(mfp2, out);
}
template<class X, class Y, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8, class Param9, class Param10, class Param11, class Param12, class Param13, class Param14>
inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, ...) const, MemFuncInfo &out)
{
RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, ...) const = mfp;
MFI_Impl<sizeof(mfp2)>::GetFuncInfo(mfp2, out);
}
template<class X, class Y, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8, class Param9, class Param10, class Param11, class Param12, class Param13, class Param14, class Param15>
inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, ...), MemFuncInfo &out)
{
RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, ...) = mfp;
MFI_Impl<sizeof(mfp2)>::GetFuncInfo(mfp2, out);
}
template<class X, class Y, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8, class Param9, class Param10, class Param11, class Param12, class Param13, class Param14, class Param15>
inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, ...) const, MemFuncInfo &out)
{
RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, ...) const = mfp;
MFI_Impl<sizeof(mfp2)>::GetFuncInfo(mfp2, out);
}
template<class X, class Y, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8, class Param9, class Param10, class Param11, class Param12, class Param13, class Param14, class Param15, class Param16>
inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, Param16, ...), MemFuncInfo &out)
{
RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, Param16, ...) = mfp;
MFI_Impl<sizeof(mfp2)>::GetFuncInfo(mfp2, out);
}
template<class X, class Y, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8, class Param9, class Param10, class Param11, class Param12, class Param13, class Param14, class Param15, class Param16>
inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, Param16, ...) const, MemFuncInfo &out)
{
RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, Param16, ...) const = mfp;
MFI_Impl<sizeof(mfp2)>::GetFuncInfo(mfp2, out);
}
template<class X, class Y, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8, class Param9, class Param10, class Param11, class Param12, class Param13, class Param14, class Param15, class Param16, class Param17>
inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, Param16, Param17, ...), MemFuncInfo &out)
{
RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, Param16, Param17, ...) = mfp;
MFI_Impl<sizeof(mfp2)>::GetFuncInfo(mfp2, out);
}
template<class X, class Y, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8, class Param9, class Param10, class Param11, class Param12, class Param13, class Param14, class Param15, class Param16, class Param17>
inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, Param16, Param17, ...) const, MemFuncInfo &out)
{
RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, Param16, Param17, ...) const = mfp;
MFI_Impl<sizeof(mfp2)>::GetFuncInfo(mfp2, out);
}
template<class X, class Y, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8, class Param9, class Param10, class Param11, class Param12, class Param13, class Param14, class Param15, class Param16, class Param17, class Param18>
inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, Param16, Param17, Param18, ...), MemFuncInfo &out)
{
RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, Param16, Param17, Param18, ...) = mfp;
MFI_Impl<sizeof(mfp2)>::GetFuncInfo(mfp2, out);
}
template<class X, class Y, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8, class Param9, class Param10, class Param11, class Param12, class Param13, class Param14, class Param15, class Param16, class Param17, class Param18>
inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, Param16, Param17, Param18, ...) const, MemFuncInfo &out)
{
RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, Param16, Param17, Param18, ...) const = mfp;
MFI_Impl<sizeof(mfp2)>::GetFuncInfo(mfp2, out);
}
template<class X, class Y, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8, class Param9, class Param10, class Param11, class Param12, class Param13, class Param14, class Param15, class Param16, class Param17, class Param18, class Param19>
inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, Param16, Param17, Param18, Param19, ...), MemFuncInfo &out)
{
RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, Param16, Param17, Param18, Param19, ...) = mfp;
MFI_Impl<sizeof(mfp2)>::GetFuncInfo(mfp2, out);
}
template<class X, class Y, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8, class Param9, class Param10, class Param11, class Param12, class Param13, class Param14, class Param15, class Param16, class Param17, class Param18, class Param19>
inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, Param16, Param17, Param18, Param19, ...) const, MemFuncInfo &out)
{
RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, Param16, Param17, Param18, Param19, ...) const = mfp;
MFI_Impl<sizeof(mfp2)>::GetFuncInfo(mfp2, out);
}
template<class X, class Y, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8, class Param9, class Param10, class Param11, class Param12, class Param13, class Param14, class Param15, class Param16, class Param17, class Param18, class Param19, class Param20>
inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, Param16, Param17, Param18, Param19, Param20, ...), MemFuncInfo &out)
{
RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, Param16, Param17, Param18, Param19, Param20, ...) = mfp;
MFI_Impl<sizeof(mfp2)>::GetFuncInfo(mfp2, out);
}
template<class X, class Y, class RetType, class Param1, class Param2, class Param3, class Param4, class Param5, class Param6, class Param7, class Param8, class Param9, class Param10, class Param11, class Param12, class Param13, class Param14, class Param15, class Param16, class Param17, class Param18, class Param19, class Param20>
inline void GetFuncInfo(Y *ptr, RetType(X::*mfp)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, Param16, Param17, Param18, Param19, Param20, ...) const, MemFuncInfo &out)
{
RetType(Y::*mfp2)(Param1, Param2, Param3, Param4, Param5, Param6, Param7, Param8, Param9, Param10, Param11, Param12, Param13, Param14, Param15, Param16, Param17, Param18, Param19, Param20, ...) const = mfp;
MFI_Impl<sizeof(mfp2)>::GetFuncInfo(mfp2, out);
}
#endif

File diff suppressed because it is too large Load Diff

View File

@ -97,6 +97,12 @@ namespace SourceHook
m_Size++;
}
void push_front(const T &obj)
{
insert(begin(), obj);
}
size_t size() const
{
return m_Size;
@ -122,6 +128,10 @@ namespace SourceHook
{
return (m_Size == 0);
}
T & front()
{
return m_Head->next->obj;
}
T & back()
{
return m_Head->prev->obj;
@ -207,6 +217,11 @@ namespace SourceHook
{
return (m_This == where.m_This);
}
operator bool()
{
return m_This != NULL;
}
private:
ListNode *m_This;
};

View File

@ -12,17 +12,28 @@
#define __SH_STACK_H__
#include <stddef.h>
#define SH_STACK_DEFAULT_SIZE 4
#include "sh_vector.h"
namespace SourceHook
{
// Vector
// May _never_ reallocate used memory!
template <class T> class CStack
{
T *m_Elements;
size_t m_AllocatedSize;
static const int SECTOR_SIZE = 16;
CVector<T *> m_Sectors; // Stores sectors
size_t m_UsedSize;
void clear()
{
for (CVector<T*>::iterator sect_iter = m_Sectors.begin(); sect_iter != m_Sectors.end(); ++sect_iter)
{
delete [] *sect_iter;
}
m_Sectors.clear();
}
public:
friend class iterator;
class iterator
@ -44,21 +55,21 @@ namespace SourceHook
T &operator *()
{
return m_pParent->m_Elements[m_Index];
return m_pParent->at(m_Index);
}
const T &operator *() const
{
return m_pParent->m_Elements[m_Index];
return m_pParent->at(m_Index);
}
T * operator->()
{
return m_pParent->m_Elements + m_Index;
return &(m_pParent->at(m_Index));
}
const T * operator->() const
{
return m_pParent->m_Elements + m_Index;
return &(m_pParent->at(m_Index));
}
iterator & operator++() // preincrement
@ -97,71 +108,76 @@ namespace SourceHook
return !(*this == right);
}
};
CStack() : m_Elements(new T[SH_STACK_DEFAULT_SIZE]),
m_AllocatedSize(SH_STACK_DEFAULT_SIZE),
m_UsedSize(0)
{
}
CStack(size_t size) : m_Elements(new T[size]),
m_AllocatedSize(size),
m_UsedSize(0)
CStack() : m_UsedSize(0)
{
}
CStack(const CStack &other) : m_Elements(NULL),
m_AllocatedSize(0),
m_UsedSize(0)
CStack(const CStack &other)
{
reserve(other.m_AllocatedSize);
for (CVector<T*>::iterator sect_iter = other.m_Sectors.begin();
sect_iter != other.m_Sectors.end(); ++sect_iter)
{
m_Sectors.push_back(new T[SECTOR_SIZE]);
for (size_t i = 0; i < SECTOR_SIZE; ++i)
m_Sectors.back()[i] = (*sect_iter)[i];
}
m_UsedSize = other.m_UsedSize;
for (size_t i = 0; i < m_UsedSize; ++i)
m_Elements[i] = other.m_Elements[i];
}
CStack & operator =(const CStack &other)
{
clear();
for (CVector<T*>::iterator sect_iter = other.m_Sectors.begin();
sect_iter != other.m_Sectors.end(); ++sect_iter)
{
m_Sectors.push_back(new T[SECTOR_SIZE]);
for (size_t i = 0; i < SECTOR_SIZE; ++i)
m_Sectors.back()[i] = (*sect_iter)[i];
}
m_UsedSize = other.m_UsedSize;
return *this;
}
~CStack()
{
if (m_Elements)
delete [] m_Elements;
clear();
}
void operator=(const CStack &other)
T &at(size_t x)
{
if (m_AllocatedSize < other.m_AllocatedSize)
{
if (m_Elements)
delete [] m_Elements;
m_Elements = new T[other.m_AllocatedSize];
m_AllocatedSize = other.m_AllocatedSize;
}
m_UsedSize = other.m_UsedSize;
for (size_t i = 0; i < m_UsedSize; ++i)
m_Elements[i] = other.m_Elements[i];
return m_Sectors[x / SECTOR_SIZE][x % SECTOR_SIZE];
}
const T &at(size_t x) const
{
return m_Sectors[x / SECTOR_SIZE][x % SECTOR_SIZE];
}
bool push(const T &val)
{
if (m_UsedSize + 1 == m_AllocatedSize)
if ((m_UsedSize / SECTOR_SIZE) >= m_Sectors.size())
{
// zOHNOES! REALLOCATE!
m_AllocatedSize *= 2;
T *newElements = new T[m_AllocatedSize];
if (!newElements)
{
m_AllocatedSize /= 2;
return false;
}
if (m_Elements)
{
for (size_t i = 0; i < m_UsedSize; ++i)
newElements[i] = m_Elements[i];
delete [] m_Elements;
}
m_Elements = newElements;
// New sector
m_Sectors.push_back(new T[SECTOR_SIZE]);
}
m_Elements[m_UsedSize++] = val;
at(m_UsedSize) = val;
++m_UsedSize;
return true;
}
T *make_next()
{
if ((m_UsedSize / SECTOR_SIZE) >= m_Sectors.size())
{
// New sector
m_Sectors.push_back(new T[SECTOR_SIZE]);
}
return &(at(m_UsedSize++));
}
void pop()
{
--m_UsedSize;
@ -174,22 +190,22 @@ namespace SourceHook
T &front()
{
return m_Elements[m_UsedSize - 1];
return at(m_UsedSize-1);
}
const T &front() const
{
return m_Elements[m_UsedSize - 1];
return at(m_UsedSize-1);
}
T &second()
{
return m_Elements[m_UsedSize - 2];
return at(m_UsedSize-2);
}
const T &second() const
{
return m_Elements[m_UsedSize - 2];
return at(m_UsedSize-2);
}
iterator begin()
@ -205,32 +221,10 @@ namespace SourceHook
{
return m_UsedSize;
}
size_t capacity()
{
return m_AllocatedSize;
}
bool empty()
{
return m_UsedSize == 0 ? true : false;
}
bool reserve(size_t size)
{
if (size > m_AllocatedSize)
{
T *newElements = new T[size];
if (!newElements)
return false;
if (m_Elements)
{
for (size_t i = 0; i < m_UsedSize; ++i)
newElements[i] = m_Elements[i];
delete [] m_Elements;
}
m_Elements = newElements;
m_AllocatedSize = size;
}
return true;
}
};
}; //namespace SourceHook

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -23,6 +23,8 @@
IMPLEMENTATION INFO
---------------------------------------
:TODO: update ???
Protos ("Prototypes")
The purpose of protos is to provide the amount of type information about a function
which is required to be able to execute a function call without corrupting the stack.
@ -170,648 +172,168 @@ New SH_CALL
the original function. Everything works fine. This works even for VP hooks.
*/
#include "sourcehook_impl_cproto.h"
#include "sourcehook_impl_chook.h"
#include "sourcehook_impl_ciface.h"
#include "sourcehook_impl_cvfnptr.h"
#include "sourcehook_impl_chookmaninfo.h"
#include "sourcehook_impl_chookmancont.h"
#include "sourcehook_impl_chookidman.h"
namespace SourceHook
{
/**
* @brief The SourceHook implementation class
* @brief The SourceHook implementation
*/
class CSourceHookImpl : public ISourceHook
namespace Impl
{
private:
class CProto
{
char *m_Proto;
static bool Equal(const char *p1, const char *p2);
char *DupProto(const char *src);
void FreeProto(char *prot);
public:
CProto() : m_Proto(NULL)
{
}
CProto(const char *szProto) : m_Proto(DupProto(szProto))
{
}
CProto(const CProto &other) : m_Proto(DupProto(other.m_Proto))
{
}
~CProto()
{
FreeProto(m_Proto);
m_Proto = NULL;
}
void operator = (const char *szProto)
{
m_Proto = DupProto(szProto);
}
void operator = (const CProto &other)
{
m_Proto = DupProto(other.m_Proto);
}
bool operator == (const char *szProto) const
{
return Equal(szProto, m_Proto);
}
bool operator == (const CProto &other) const
{
return Equal(other.m_Proto, m_Proto);
}
const char *GetProto() const
{
return m_Proto;
}
};
/**
* @brief A hook can be removed if you have this information
*/
struct RemoveHookInfo
{
RemoveHookInfo(Plugin pplug, void *piface, int tpo, HookManagerPubFunc phookman,
ISHDelegate *phandler, bool ppost)
: plug(pplug), iface(piface), thisptr_offs(tpo),
hookman(phookman), handler(phandler), post(ppost)
{
}
Plugin plug;
void *iface;
int thisptr_offs;
HookManagerPubFunc hookman;
ISHDelegate *handler;
bool post;
};
struct RemoveHookManInfo
{
RemoveHookManInfo(Plugin pplug, HookManagerPubFunc phookman)
: plug(pplug), hookman(phookman)
{
}
Plugin plug;
HookManagerPubFunc hookman;
};
// Associates hook ids with info about the hooks
// Also used to keep track of used hook ids
class CHookIDManager
class CHookManContainerList : public List<CHookManagerContainer>
{
public:
struct Entry
{
bool isfree;
// hookman info
CProto proto;
int vtbl_offs;
int vtbl_idx;
// vfnptr
void *vfnptr;
// iface
void* adjustediface;
// hook
Plugin plug;
int thisptr_offs;
ISHDelegate *handler;
bool post;
Entry(const CProto &pprt, int pvo, int pvi, void *pvp, void *pai, Plugin pplug, int pto,
ISHDelegate *ph, bool ppost)
: isfree(false), proto(pprt), vtbl_offs(pvo), vtbl_idx(pvi), vfnptr(pvp),
adjustediface(pai), plug(pplug), thisptr_offs(pto), handler(ph), post(ppost)
{
}
Entry()
{
}
};
private:
// Internally, hookid 1 is stored as m_Entries[0]
CVector<Entry> m_Entries;
public:
CHookIDManager();
int New(const CProto &proto, int vtbl_offs, int vtbl_idx, void *vfnptr, void *adjustediface,
Plugin plug, int thisptr_offs, ISHDelegate *handler, bool post);
bool Remove(int hookid);
const Entry * QueryHook(int hookid);
// Finds all hooks with the given info, and fills the hookids into output.
void FindAllHooks(CVector<int> &output, const CProto &proto, int vtbl_offs, int vtbl_idx,
void *adjustediface, Plugin plug, int thisptr_offs, ISHDelegate *handler, bool post);
// Removes all hooks with a specified vfnptr
bool RemoveAll(void *vfnptr);
CHookManagerContainer &GetContainer(int vtbloffs, int vtblidx, const CProto &proto);
void RemoveHookMans(Plugin plug);
void RemoveHookMans(Plugin plug, HookManagerPubFunc pubFunc);
};
struct HookInfo
struct CHookContext : IHookContext
{
ISHDelegate *handler; //!< Pointer to the handler
bool paused; //!< If true, the hook should not be executed
Plugin plug; //!< The owner plugin
int thisptr_offs; //!< This pointer offset
int hookid; //!< Unique ID given by CHookIDManager
bool operator==(int otherid)
enum State
{
return hookid == otherid;
}
};
State_Born,
State_Pre,
State_PreVP,
State_Post,
State_PostVP,
State_OrigCall,
State_Dead,
class CHookList : public IHookList
{
public:
List<HookInfo> *m_VPList; // left-hand list for ListCatIterator -> for VP hooks
List<HookInfo> m_List;
friend class CIter;
class CIter : public IHookList::IIter
{
friend class CHookList;
CHookList *m_pList;
void SkipPaused();
public:
ListCatIterator<HookInfo> m_Iter;
CIter(CHookList *pList);
virtual ~CIter();
void GoToBegin();
void Set(CIter *pOther);
bool End();
void Next();
ISHDelegate *Handler();
int ThisPtrOffs();
void Clear();
CIter *m_pNext; // When stored in m_FreeIters and m_UsedIters
CIter *m_pPrev; // Only used when stored in m_UsedIters
// Special
State_Ignore,
State_Recall_Pre,
State_Recall_PreVP,
State_Recall_Post,
State_Recall_PostVP
};
CIter *m_FreeIters;
CIter *m_UsedIters; // The last returned and not-yet-released iter is always m_UsedIters
// For recalls
bool m_Recall;
bool m_RQFlag;
void SetRecallState(); // Sets the list into a state where the next returned
// iterator (from GetIter) will be a copy of the last
// returned iterator, incremented by one. This is used in Recalls.
// The hook resets this state automatically on:
// GetIter, ReleaseIter
void RQFlagReset() { m_RQFlag = false; }
bool RQFlagGet() { return m_RQFlag; }
CHookList();
CHookList(const CHookList &other);
virtual ~CHookList();
void operator=(const CHookList &other);
IIter *GetIter();
void ReleaseIter(IIter *pIter);
void SetVPList(List<HookInfo> *newList);
void ClearVPList();
};
// I know, data hiding... But I'm a lazy bastard!
class CIface : public IIface
{
public:
void *m_Ptr;
CHookList m_PreHooks;
CHookList m_PostHooks;
public:
CIface(void *ptr);
virtual ~CIface();
void *GetPtr();
IHookList *GetPreHooks();
IHookList *GetPostHooks();
bool operator==(void *ptr)
{
return m_Ptr == ptr;
}
bool operator!=(void *ptr)
{
return m_Ptr != ptr;
}
};
class CVfnPtr : public IVfnPtr
{
public:
typedef List<CIface> IfaceList;
typedef IfaceList::iterator IfaceListIter;
void *m_Ptr;
void *m_OrigEntry;
IfaceList m_Ifaces;
void **m_pOneIgnore;
public:
CVfnPtr(void *ptr, void **pOneIgnore);
virtual ~CVfnPtr();
void *GetVfnPtr();
void *GetOrigEntry();
virtual IIface *FindIface(void *ptr);
bool operator==(void *ptr)
{
return m_Ptr == ptr;
}
};
class CHookManagerInfo : public IHookManagerInfo
{
public:
typedef List<CVfnPtr> VfnPtrList;
typedef VfnPtrList::iterator VfnPtrListIter;
Plugin m_Plug;
HookManagerPubFunc m_Func;
int m_VtblOffs;
int m_VtblIdx;
const char *m_Proto;
void *m_HookfuncVfnptr;
VfnPtrList m_VfnPtrs;
int m_HookManVersion;
public:
CHookManagerInfo();
virtual ~CHookManagerInfo();
IVfnPtr *FindVfnPtr(void *vfnptr);
void SetInfo(int vtbl_offs, int vtbl_idx, const char *proto);
void SetHookfuncVfnptr(void *hookfunc_vfnptr);
void SetVersion(int version);
bool operator < (const CHookManagerInfo &other)
{
return m_HookManVersion < other.m_HookManVersion;
}
struct Descriptor
{
Descriptor(Plugin pplug, HookManagerPubFunc ppubFunc) : plug(pplug), pubFunc(ppubFunc)
{
}
Plugin plug;
HookManagerPubFunc pubFunc;
};
bool operator == (const Descriptor desc)
{
return m_Func == desc.pubFunc && m_Plug == desc.plug;
}
};
typedef List<CHookManagerInfo> HookManInfoList;
class CHookManagerContainer : public HookManInfoList
{
public:
// HMCI (Hook Manager Container Identification)
class HMCI
{
CProto m_Proto;
int m_VtableOffset;
int m_VtableIndex;
public:
HMCI(const char *proto, int vtbloffs, int vtblidx) :
m_Proto(proto), m_VtableOffset(vtbloffs), m_VtableIndex(vtblidx)
{
}
~HMCI()
{
}
bool operator==(const HMCI &other) const
{
return
other.m_VtableIndex == m_VtableIndex &&
other.m_Proto == m_Proto &&
other.m_VtableOffset == m_VtableOffset;
}
const CProto &GetProto() const
{
return m_Proto;
}
int GetVtableOffset() const
{
return m_VtableOffset;
}
int GetVtableIndex() const
{
return m_VtableIndex;
}
};
HMCI m_HCMI;
public:
CHookManagerContainer(const HMCI &hmci) : m_HCMI(hmci)
{
}
bool operator == (const HMCI &other) const
{
return m_HCMI == other;
}
void AddHookManager(Plugin plug, const CHookManagerInfo &hookman);
};
class CCallClassImpl : public DeprecatedCallClass<void>
{
public:
typedef SourceHook::CVector<void*> OrigFuncs;
typedef SourceHook::THash<int, OrigFuncs> OrigVTables;
void *m_Ptr; //!< Pointer to the actual object
size_t m_ObjSize; //!< Size of the instance
OrigVTables m_VT; //!< Info about vtables & functions
int m_RefCounter;
CCallClassImpl(void *ptr, size_t size);
virtual ~CCallClassImpl();
bool operator==(void *other)
{
return m_Ptr == other;
}
void *GetThisPtr();
void *GetOrigFunc(int vtbloffs, int vtblidx);
void ApplyCallClassPatch(int vtbl_offs, int vtbl_idx, void *orig_entry);
void RemoveCallClassPatch(int vtbl_offs, int vtbl_idx);
};
/**
* @brief A list of CallClass structures
*/
typedef List<CCallClassImpl> Impl_CallClassList;
Impl_CallClassList m_CallClasses; //!< A list of already generated callclasses
/**
* @brief A list of CHookManagerContainers
*/
typedef List<CHookManagerContainer> HookManContList;
HookManContList m_HookMans; //!< A list of hook managers
struct HookLoopInfo
{
enum RecallType
{
Recall_No=0,
Recall_Pre,
Recall_Post1,
Recall_Post2
};
int m_State;
List<CHook>::iterator m_Iter;
CVfnPtr *pVfnPtr;
CIface *pIface;
META_RES *pStatus;
META_RES *pPrevRes;
META_RES *pCurRes;
META_RES temporaryStatus; //!< Stored during Post1 recall phase
bool shouldContinue;
RecallType recall; //!< Specifies which kind of recall we're in.
IIface *pCurIface;
void *pThisPtr;
const void *pOrigRet;
void *pOverrideRet;
void **pIfacePtrPtr;
void *pIfacePtr;
bool m_CallOrig;
void SkipPaused(List<CHook>::iterator &iter, List<CHook> &list)
{
while (iter != list.end() && iter->IsPaused())
++iter;
}
public:
void HookRemoved(List<CHook>::iterator oldhookiter, List<CHook>::iterator nexthookiter);
void IfaceRemoved(CIface *iface);
void VfnPtrRemoved(CVfnPtr *vfnptr);
ISHDelegate *GetNext();
void *GetOverrideRetPtr();
const void *GetOrigRetPtr();
bool ShouldCallOrig();
};
typedef CStack<HookLoopInfo> HookLoopInfoStack;
void ApplyCallClassPatches(CCallClassImpl &cc);
void ApplyCallClassPatches(void *ifaceptr, int vtbl_offs, int vtbl_idx, void *orig_entry);
void RemoveCallClassPatches(void *ifaceptr, int vtbl_offs, int vtbl_idx);
typedef CStack<CHookContext> HookContextStack;
void SetPluginPaused(Plugin plug, bool paused);
class CSourceHookImpl : public ISourceHook
{
private:
CHookManContainerList m_HookManContainers;
CHookIDManager m_HookIDMan;
HookContextStack m_ContextStack;
HookLoopInfoStack m_HLIStack;
CHookIDManager m_HookIDMan;
bool SetHookPaused(int hookid, bool paused);
public:
CSourceHookImpl();
virtual ~CSourceHookImpl();
void *m_OneIgnore; //:TODO:
bool m_IgnoreActive;
public:
CSourceHookImpl();
virtual ~CSourceHookImpl();
/**
* @brief Returns the interface version
*/
int GetIfaceVersion();
/**
* @brief Returns the interface version
*/
int GetIfaceVersion();
/**
* @brief Returns the implemnetation version
*/
int GetImplVersion();
/**
* @brief Returns the implemnetation version
*/
int GetImplVersion();
int AddHook(Plugin plug, AddHookMode mode, void *iface, int thisptr_offs, HookManagerPubFunc myHookMan,
ISHDelegate *handler, bool post);
/**
* @brief Make sure that a plugin is not used by any other plugins anymore, and unregister all its hook managers
*/
void UnloadPlugin(Plugin plug);
bool RemoveHook(Plugin plug, void *iface, int thisptr_offs, HookManagerPubFunc myHookMan,
ISHDelegate *handler, bool post);
/**
* @brief Shut down the whole system, unregister all hook managers
*/
void CompleteShutdown();
bool RemoveHookByID(int hookid);
/**
* @brief Add a hook.
*
* @return True if the function succeeded, false otherwise
*
* @param plug The unique identifier of the plugin that calls this function
* @param iface The interface pointer
* @param ifacesize The size of the class iface points to
* @param myHookMan A hook manager function that should be capable of handling the function
* @param handler A pointer to a FastDelegate containing the hook handler
* @param post Set to true if you want a post handler
*/
bool AddHook(Plugin plug, void *iface, int thisptr_offs, HookManagerPubFunc myHookMan, ISHDelegate *handler, bool post);
bool PauseHookByID(int hookid);
bool UnpauseHookByID(int hookid);
/**
* @brief Removes a hook.
*
* @return True if the function succeeded, false otherwise
*
* @param plug The unique identifier of the plugin that calls this function
* @param iface The interface pointer
* @param thisptr_offs This pointer adjuster
* @param myHookMan A hook manager function that should be capable of handling the function
* @param handler A pointer to a FastDelegate containing the hook handler
* @param post Set to true if you want a post handler
*/
bool RemoveHook(Plugin plug, void *iface, int thisptr_offs, HookManagerPubFunc myHookMan, ISHDelegate *handler, bool post);
void SetRes(META_RES res); //!< Sets the meta result
META_RES GetPrevRes(); //!< Gets the meta result of the
//!< previously calledhandler
META_RES GetStatus(); //!< Gets the highest meta result
const void *GetOrigRet(); //!< Gets the original result.
//!< If not in post function, undefined
const void *GetOverrideRet(); //!< Gets the override result.
//!< If none is specified, NULL
void *GetIfacePtr(); //!< Gets the interface pointer
/**
* @brief Removes a hook.
*
* @ return True if the function succeeded, false otherwise
*
* @param info A RemoveHookInfo structure, describing the hook
*/
bool RemoveHook(RemoveHookInfo info);
void *GetOverrideRetPtr(); //!< Used for setting the override return value
/**
* @brief Checks whether a plugin has (a) hook manager(s) that is/are currently used by other plugins
*
* @param plug The unique identifier of the plugin in question
*/
bool IsPluginInUse(Plugin plug);
/**
* @brief Make sure that a plugin is not used by any other plugins anymore, and unregister all its hook managers
*/
void UnloadPlugin(Plugin plug);
/**
* @brief Pauses all hooks of a plugin
*
* @param plug The unique identifier of the plugin
*/
void PausePlugin(Plugin plug);
void RemoveHookManager(Plugin plug, HookManagerPubFunc pubFunc);
/**
* @brief Unpauses all hooks of a plugin
*
* @param plug The unique identifier of the plugin
*/
void UnpausePlugin(Plugin plug);
void SetIgnoreHooks(void *vfnptr);
void ResetIgnoreHooks(void *vfnptr);
/**
* @brief Return a pointer to a callclass. Generate a new one if required.
*
* @param iface The interface pointer
* @param size Size of the class instance
*/
DeprecatedCallClass<void> *GetCallClass(void *iface, size_t size);
void DoRecall();
/**
* @brief Release a callclass
*
* @param ptr Pointer to the callclass
*/
virtual void ReleaseCallClass(DeprecatedCallClass<void> *ptr);
IHookContext *SetupHookLoop(IHookManagerInfo *hi, void *vfnptr, void *thisptr, void **origentry, META_RES *statusPtr,
META_RES *prevResPtr, META_RES *curResPtr, const void *origRetPtr, void *overrideRetPtr);
virtual void SetRes(META_RES res); //!< Sets the meta result
virtual META_RES GetPrevRes(); //!< Gets the meta result of the previously called handler
virtual META_RES GetStatus(); //!< Gets the highest meta result
virtual const void *GetOrigRet(); //!< Gets the original result. If not in post function, undefined
virtual const void *GetOverrideRet(); //!< Gets the override result. If none is specified, NULL
virtual void *GetIfacePtr(); //!< Gets the interface pointer
void EndContext(IHookContext *pCtx);
//////////////////////////////////////////////////////////////////////////
// For hook managers
void HookLoopBegin(IIface *pIface); //!< Should be called when a hook loop begins
void HookLoopEnd(); //!< Should be called when a hook loop exits
void SetCurResPtr(META_RES *mres); //!< Sets pointer to the current meta result
void SetPrevResPtr(META_RES *mres); //!< Sets pointer to previous meta result
void SetStatusPtr(META_RES *mres); //!< Sets pointer to the status variable
void SetIfacePtrPtr(void **pp); //!< Sets pointer to the interface this pointer
void SetOrigRetPtr(const void *ptr); //!< Sets the original return pointer
void SetOverrideRetPtr(void *ptr); //!< Sets the override result pointer
bool ShouldContinue(); //!< Returns false if the hook loop should exit
/**
* @brief Shut down the whole system, unregister all hook managers
*/
void CompleteShutdown();
/**
* @brief Remove a hook manager. Auto-removes all hooks attached to it from plugin plug.
*
* @param plug The owner of the hook manager
* @param pubFunc The hook manager's info function
*/
virtual void RemoveHookManager(Plugin plug, HookManagerPubFunc pubFunc);
virtual void RemoveHookManager(RemoveHookManInfo info);
/**
* @brief Pauses all hooks of a plugin
*
* @param plug The unique identifier of the plugin
*/
void PausePlugin(Plugin plug);
virtual void DoRecall(); //!< Initiates a recall sequence
virtual void *GetOverrideRetPtr(); //!< Returns the pointer set by SetOverrideRetPtr
virtual void *SetupHookLoop(META_RES *statusPtr, META_RES *prevResPtr, META_RES *curResPtr,
void **ifacePtrPtr, const void *origRetPtr, void *overrideRetPtr);
/**
* @brief Add a (VP) hook.
*
* @return non-zero hook id on success, 0 otherwise
*
* @param plug The unique identifier of the plugin that calls this function
* @param mode Can be either Hook_Normal or Hook_VP (vtable-wide hook)
* @param iface The interface pointer
* The representative interface pointer for VP hooks
* The vtable pointer for direct VP hooks !!!
* @param ifacesize The size of the class iface points to
* @param myHookMan A hook manager function that should be capable of handling the function
* @param handler A pointer to a FastDelegate containing the hook handler
* @param post Set to true if you want a post handler
*/
virtual int AddHookNew(Plugin plug, AddHookMode mode, void *iface, int thisptr_offs, HookManagerPubFunc myHookMan,
ISHDelegate *handler, bool post);
/**
* @brief Remove a VP hook by ID.
*
* @return true on success, false otherwise
*
* @param plug The unique identifier of the plugin that calls this function
* @param hookid The hook id (returned by AddHookNew)
*/
virtual bool RemoveHookByID(Plugin plug, int hookid);
/**
* @brief Makes sure that hooks are going to be ignored on the next call of vfnptr
*
* @param plug The unique identifier of the plugin that calls this function
* @param vfnptr The virtual function pointer of the function in question
*/
virtual void SetIgnoreHooks(Plugin plug, void *vfnptr);
/**
* @brief Reverses SetIgnoreHooks' effect
*
* @param plug The unique identifier of the plugin that calls this function
* @param vfnptr The virtual function pointer of the function in question
*/
virtual void ResetIgnoreHooks(Plugin plug, void *vfnptr);
/**
* @brief Finds the original entry of a virtual function pointer
*
* @param vfnptr The virtual function pointer
* @return The original entry if the virtual function pointer has been patched; NULL otherwise.
*/
virtual void *GetOrigVfnPtrEntry(void *vfnptr);
};
/**
* @brief Unpauses all hooks of a plugin
*
* @param plug The unique identifier of the plugin
*/
void UnpausePlugin(Plugin plug);
};
}
}
#endif

View File

@ -0,0 +1,105 @@
/* ======== SourceHook ========
* Copyright (C) 2004-2007 Metamod:Source Development Team
* No warranties of any kind
*
* License: zlib/libpng
*
* Author(s): Pavol "PM OnoTo" Marko
* ============================
*/
#ifndef __SOURCEHOOK_IMPL_CHOOK_H__
#define __SOURCEHOOK_IMPL_CHOOK_H__
namespace SourceHook
{
namespace Impl
{
class CHook
{
// *** Data ***
Plugin m_OwnerPlugin;
int m_ThisPointerOffset;
ISHDelegate *m_pHandler;
int m_HookID;
bool m_Paused;
public:
// *** Descriptor ***
struct Descriptor
{
Plugin m_OwnerPlugin;
int m_ThisPointerOffset;
ISHDelegate *m_pHandler;
Descriptor(Plugin ownerPlugin, int thisPtrOffset, ISHDelegate *pHandler)
: m_OwnerPlugin(ownerPlugin), m_ThisPointerOffset(thisPtrOffset),
m_pHandler(pHandler)
{
}
};
// *** Interface ***
inline CHook(Plugin ownerPlugin, int thisPtrOffset, ISHDelegate *pHandler, int hookid, bool paused=false);
inline bool operator==(const Descriptor &other) const;
inline bool operator==(int hookid) const;
inline Plugin GetOwnerPlugin() const;
inline int GetThisPointerOffset() const;
inline ISHDelegate *GetHandler() const;
inline void SetPaused(bool value);
inline bool IsPaused() const;
inline int GetID() const;
};
// *** Implementation ***
inline CHook::CHook(Plugin ownerPlugin, int thisPtrOffset, ISHDelegate *pHandler, int hookid, bool paused)
: m_OwnerPlugin(ownerPlugin), m_ThisPointerOffset(thisPtrOffset),
m_pHandler(pHandler), m_HookID(hookid), m_Paused(paused)
{
}
inline bool CHook::operator==(const Descriptor &other) const
{
return m_OwnerPlugin == other.m_OwnerPlugin
&& m_ThisPointerOffset == other.m_ThisPointerOffset
&& m_pHandler == other.m_pHandler;
}
inline bool CHook::operator==(int hookid) const
{
return m_HookID == hookid;
}
inline Plugin CHook::GetOwnerPlugin() const
{
return m_OwnerPlugin;
}
inline int CHook::GetThisPointerOffset() const
{
return m_ThisPointerOffset;
}
inline ISHDelegate *CHook::GetHandler() const
{
return m_pHandler;
}
inline void CHook::SetPaused(bool value)
{
m_Paused = value;
}
inline bool CHook::IsPaused() const
{
return m_Paused;
}
inline int CHook::GetID() const
{
return m_HookID;
}
}
}
#endif

View File

@ -0,0 +1,80 @@
/* ======== SourceHook ========
* Copyright (C) 2004-2007 Metamod:Source Development Team
* No warranties of any kind
*
* License: zlib/libpng
*
* Author(s): Pavol "PM OnoTo" Marko
* ============================
*/
#ifndef __SOURCEHOOK_IMPL_CHOOKIDMAN_H__
#define __SOURCEHOOK_IMPL_CHOOKIDMAN_H__
#include "sh_vector.h"
namespace SourceHook
{
namespace Impl
{
// Associates hook ids with info about the hooks
// Also used to keep track of used hook ids
class CHookIDManager
{
public:
struct Entry
{
bool isfree;
// hookman info
CProto proto;
int vtbl_offs;
int vtbl_idx;
// vfnptr
void *vfnptr;
// iface
void* adjustediface;
// hook
Plugin plug;
int thisptr_offs;
ISHDelegate *handler;
bool post;
Entry(const CProto &pprt, int pvo, int pvi, void *pvp, void *pai, Plugin pplug, int pto,
ISHDelegate *ph, bool ppost)
: isfree(false), proto(pprt), vtbl_offs(pvo), vtbl_idx(pvi), vfnptr(pvp),
adjustediface(pai), plug(pplug), thisptr_offs(pto), handler(ph), post(ppost)
{
}
Entry()
{
}
};
private:
// Internally, hookid 1 is stored as m_Entries[0]
CVector<Entry> m_Entries;
public:
CHookIDManager();
int New(const CProto &proto, int vtbl_offs, int vtbl_idx, void *vfnptr, void *adjustediface,
Plugin plug, int thisptr_offs, ISHDelegate *handler, bool post);
bool Remove(int hookid);
const Entry * QueryHook(int hookid);
// Finds all hooks with the given info, and fills the hookids into output.
void FindAllHooks(CVector<int> &output, const CProto &proto, int vtbl_offs, int vtbl_idx,
void *adjustediface, Plugin plug, int thisptr_offs, ISHDelegate *handler, bool post);
// Removes all hooks with a specified vfnptr
bool RemoveAll(void *vfnptr);
void FindAllHooks(CVector<int> &output);
void FindAllHooks(CVector<int> &output, Plugin plug);
};
}
}
#endif

View File

@ -0,0 +1,111 @@
/* ======== SourceHook ========
* Copyright (C) 2004-2007 Metamod:Source Development Team
* No warranties of any kind
*
* License: zlib/libpng
*
* Author(s): Pavol "PM OnoTo" Marko
* ============================
*/
#ifndef __SOURCEHOOK_IMPL_CHOOKMANICONT_H__
#define __SOURCEHOOK_IMPL_CHOOKMANICONT_H__
#include "sh_list.h"
namespace SourceHook
{
namespace Impl
{
class CHookManagerContainer : public List<CHookManager>
{
// *** Data ***
int m_VtblOffs;
int m_VtblIdx;
CProto m_Proto;
public:
// *** Descriptor ***
struct Descriptor
{
int m_VtblOffs;
int m_VtblIdx;
const CProto &m_Proto; // we can assume that a Descriptor won't live for a long time
Descriptor(int vtblOffs, int vtblIdx, const CProto &proto)
: m_VtblOffs(vtblOffs), m_VtblIdx(vtblIdx), m_Proto(proto)
{
}
};
// *** Interface ***
inline CHookManagerContainer(int vtblOffs, int vtblIdx, const CProto &proto);
inline CHookManagerContainer(const CHookManager &hookMan);
inline bool operator==(const Descriptor &other) const;
inline operator bool() const;
inline int GetVtblOffs() const;
inline int GetVtblIdx() const;
inline const CProto &GetProto() const;
bool AddHookManager(const CHookManager &hookMan);
inline CHookManager &GetActiveHookManager();
inline const CHookManager &GetActiveHookManager() const;
void RemoveHookMans(Plugin plug, HookManagerPubFunc pubFunc = NULL);
};
// *** Implementation ***
inline CHookManagerContainer::CHookManagerContainer(int vtblOffs, int vtblIdx, const CProto &proto)
: m_VtblOffs(vtblOffs), m_VtblIdx(vtblIdx), m_Proto(proto)
{
}
inline CHookManagerContainer::CHookManagerContainer(const CHookManager &hookMan)
: m_VtblOffs(hookMan.GetVtblOffs()), m_VtblIdx(hookMan.GetVtblIdx()), m_Proto(hookMan.GetProto())
{
push_back(hookMan);
}
inline bool CHookManagerContainer::operator==(const Descriptor &other) const
{
return m_VtblOffs == other.m_VtblOffs
&& m_VtblIdx == other.m_VtblIdx
&& m_Proto == other.m_Proto;
}
inline CHookManagerContainer::operator bool() const
{
return !empty();
}
inline int CHookManagerContainer::GetVtblOffs() const
{
return m_VtblOffs;
}
inline int CHookManagerContainer::GetVtblIdx() const
{
return m_VtblIdx;
}
inline const CProto &CHookManagerContainer::GetProto() const
{
return m_Proto;
}
inline CHookManager &CHookManagerContainer::GetActiveHookManager()
{
begin()->Register();
return *begin();
}
const CHookManager &CHookManagerContainer::GetActiveHookManager() const
{
begin()->Register();
return *begin();
}
}
}
#endif

View File

@ -0,0 +1,160 @@
/* ======== SourceHook ========
* Copyright (C) 2004-2007 Metamod:Source Development Team
* No warranties of any kind
*
* License: zlib/libpng
*
* Author(s): Pavol "PM OnoTo" Marko
* ============================
*/
#ifndef __SOURCEHOOK_IMPL_CHOOKMANINFO_H__
#define __SOURCEHOOK_IMPL_CHOOKMANINFO_H__
#include "sh_list.h"
#include "sourcehook_impl_cproto.h"
namespace SourceHook
{
namespace Impl
{
class CHookManager : public IHookManagerInfo
{
// *** Data ***
Plugin m_OwnerPlugin;
HookManagerPubFunc m_PubFunc;
int m_VtblOffs;
int m_VtblIdx;
CProto m_Proto;
int m_Version;
void *m_HookfuncVfnptr;
List<CVfnPtr> m_VfnPtrList;
public:
// *** Descriptor ***
struct Descriptor
{
Plugin m_OwnerPlugin;
HookManagerPubFunc m_PubFunc;
Descriptor(Plugin ownerPlugin, HookManagerPubFunc pubFunc)
: m_OwnerPlugin(ownerPlugin), m_PubFunc(pubFunc)
{
}
};
// *** Interface ***
inline CHookManager(Plugin ownerPlugin, HookManagerPubFunc pubFunc);
inline bool operator==(const Descriptor &other) const;
inline bool operator==(const CHookManager &other) const;
inline operator bool() const;
inline Plugin GetOwnerPlugin() const;
inline int GetVtblOffs() const;
inline int GetVtblIdx() const;
inline const CProto &GetProto() const;
inline int GetVersion() const;
inline void *GetHookFunc() const;
inline HookManagerPubFunc GetPubFunc() const;
inline List<CVfnPtr> &GetVfnPtrList();
inline const List<CVfnPtr> &GetVfnPtrList() const;
inline void Register();
inline void Unregister();
CVfnPtr &GetVfnPtr(void *vfnptr);
// *** IHookManagerInfo interface ***
void SetInfo(int hookman_version, int vtbloffs, int vtblidx,
ProtoInfo *proto, void *hookfunc_vfnptr);
};
// *** Implementation ***
inline CHookManager::CHookManager(Plugin ownerPlugin, HookManagerPubFunc pubFunc)
: m_OwnerPlugin(ownerPlugin), m_PubFunc(pubFunc), m_Version(-1)
{
// Query pubfunc
// -> Should call SetInfo and set all the other variables!
if (m_PubFunc(false, this) != 0)
{
// Error!
m_Version = -1;
}
}
inline CHookManager::operator bool() const
{
return m_Version != -1;
}
inline bool CHookManager::operator==(const Descriptor &other) const
{
return m_OwnerPlugin == other.m_OwnerPlugin
&& m_PubFunc == other.m_PubFunc;
}
inline bool CHookManager::operator==(const CHookManager &other) const
{
return m_OwnerPlugin == other.m_OwnerPlugin
&& m_PubFunc == other.m_PubFunc;
}
inline Plugin CHookManager::GetOwnerPlugin() const
{
return m_OwnerPlugin;
}
inline int CHookManager::GetVtblOffs() const
{
return m_VtblOffs;
}
inline int CHookManager::GetVtblIdx() const
{
return m_VtblIdx;
}
inline const CProto &CHookManager::GetProto() const
{
return m_Proto;
}
inline int CHookManager::GetVersion() const
{
return m_Version;
}
inline void *CHookManager::GetHookFunc() const
{
return *reinterpret_cast<void**>(m_HookfuncVfnptr);
}
inline HookManagerPubFunc CHookManager::GetPubFunc() const
{
return m_PubFunc;
}
inline List<CVfnPtr> &CHookManager::GetVfnPtrList()
{
return m_VfnPtrList;
}
inline const List<CVfnPtr> &CHookManager::GetVfnPtrList() const
{
return m_VfnPtrList;
}
inline void CHookManager::Register()
{
m_PubFunc(true, this);
}
inline void CHookManager::Unregister()
{
m_PubFunc(true, NULL);
}
}
}
#endif

View File

@ -0,0 +1,80 @@
/* ======== SourceHook ========
* Copyright (C) 2004-2007 Metamod:Source Development Team
* No warranties of any kind
*
* License: zlib/libpng
*
* Author(s): Pavol "PM OnoTo" Marko
* ============================
*/
#ifndef __SOURCEHOOK_IMPL_CIFACE_H__
#define __SOURCEHOOK_IMPL_CIFACE_H__
#include "sh_list.h"
namespace SourceHook
{
namespace Impl
{
class CIface
{
// *** Data ***
void *m_Ptr;
List<CHook> m_PreHooks;
List<CHook> m_PostHooks;
public:
// *** Descriptor ***
typedef void* Descriptor;
// *** Interface ***
inline CIface(void *ptr);
inline bool operator==(const Descriptor &other);
inline void *GetPtr() const;
inline List<CHook> &GetPreHookList();
inline List<CHook> &GetPostHookList();
inline const List<CHook> &GetPreHookList() const;
inline const List<CHook> &GetPostHookList() const;
};
// *** Implementation ***
inline CIface::CIface(void *ptr)
: m_Ptr(ptr)
{
}
inline bool CIface::operator==(const Descriptor &other)
{
return m_Ptr == other;
}
inline void *CIface::GetPtr() const
{
return m_Ptr;
}
inline List<CHook> &CIface::GetPreHookList()
{
return m_PreHooks;
}
inline List<CHook> &CIface::GetPostHookList()
{
return m_PostHooks;
}
inline const List<CHook> &CIface::GetPreHookList() const
{
return m_PreHooks;
}
inline const List<CHook> &CIface::GetPostHookList() const
{
return m_PostHooks;
}
}
}
#endif

View File

@ -0,0 +1,76 @@
/* ======== SourceHook ========
* Copyright (C) 2004-2007 Metamod:Source Development Team
* No warranties of any kind
*
* License: zlib/libpng
*
* Author(s): Pavol "PM OnoTo" Marko
* ============================
*/
#ifndef __SOURCEHOOK_IMPL_CPROTO_H__
#define __SOURCEHOOK_IMPL_CPROTO_H__
namespace SourceHook
{
namespace Impl
{
class CProto
{
ProtoInfo *m_Proto;
static bool Equal(const ProtoInfo *p1, const ProtoInfo *p2);
static ProtoInfo *DupProto(const ProtoInfo *src);
static void FreeProto(ProtoInfo *prot);
public:
CProto() : m_Proto(NULL)
{
}
CProto(const ProtoInfo *pProto) : m_Proto(DupProto(pProto))
{
}
CProto(const CProto &other) : m_Proto(DupProto(other.m_Proto))
{
}
~CProto()
{
FreeProto(m_Proto);
m_Proto = NULL;
}
void operator = (const ProtoInfo *pProto)
{
if (m_Proto)
FreeProto(m_Proto);
m_Proto = DupProto(pProto);
}
void operator = (const CProto &other)
{
if (m_Proto)
FreeProto(m_Proto);
m_Proto = DupProto(other.m_Proto);
}
bool operator == (const ProtoInfo *pProto) const
{
return Equal(pProto, m_Proto);
}
bool operator == (const CProto &other) const
{
return Equal(other.m_Proto, m_Proto);
}
const ProtoInfo *GetProto() const
{
return m_Proto;
}
};
}
}
#endif

View File

@ -0,0 +1,91 @@
/* ======== SourceHook ========
* Copyright (C) 2004-2007 Metamod:Source Development Team
* No warranties of any kind
*
* License: zlib/libpng
*
* Author(s): Pavol "PM OnoTo" Marko
* ============================
*/
#ifndef __SOURCEHOOK_IMPL_CVFNPTR_H__
#define __SOURCEHOOK_IMPL_CVFNPTR_H__
#include "sh_list.h"
namespace SourceHook
{
namespace Impl
{
class CVfnPtr
{
// *** Data ***
void *m_Ptr;
void *m_OrigEntry;
List<CIface> m_IfaceList;
public:
// *** Descriptor ***
typedef void* Descriptor;
// *** Interface ***
inline CVfnPtr(void *ptr);
inline bool operator==(const Descriptor &other);
inline void *GetPtr() const;
inline void *GetOrigEntry() const;
inline List<CIface> &GetIfaceList();
inline const List<CIface> &GetIfaceList() const;
inline CIface *FindIface(void *iface);
CIface &GetIface(void *iface);
bool Patch(void *newValue);
inline bool Revert();
};
// *** Implementation ***
inline CVfnPtr::CVfnPtr(void *ptr)
: m_Ptr(ptr), m_OrigEntry(*reinterpret_cast<void**>(m_Ptr))
{
}
inline bool CVfnPtr::operator==(const Descriptor &other)
{
return m_Ptr == other;
}
inline void *CVfnPtr::GetPtr() const
{
return m_Ptr;
}
inline void *CVfnPtr::GetOrigEntry() const
{
return m_OrigEntry;
}
inline List<CIface> &CVfnPtr::GetIfaceList()
{
return m_IfaceList;
}
inline const List<CIface> &CVfnPtr::GetIfaceList() const
{
return m_IfaceList;
}
inline bool CVfnPtr::Revert()
{
return Patch(m_OrigEntry);
}
inline CIface *CVfnPtr::FindIface(void *iface)
{
List<CIface>::iterator iter = m_IfaceList.find(iface);
if (iter == m_IfaceList.end())
return NULL;
else
return &(*iter);
}
}
}
#endif

View File

@ -25,7 +25,7 @@ class Test
TestProto m_Func;
std::string m_Name;
static SourceHook::List<Test *> ms_Tests;
static SourceHook::CVector<Test *> ms_Tests;
public:
Test(TestProto func, const char *name) : m_Func(func), m_Name(name)
{
@ -50,7 +50,7 @@ public:
static void DoTests()
{
int passed=0, failed=0;
for (SourceHook::List<Test*>::iterator iter = ms_Tests.begin(); iter != ms_Tests.end(); ++iter)
for (SourceHook::CVector<Test*>::iterator iter = ms_Tests.begin(); iter != ms_Tests.end(); ++iter)
{
if ((**iter)())
++passed;
@ -62,7 +62,7 @@ public:
}
};
SourceHook::List<Test *> Test::ms_Tests;
SourceHook::CVector<Test *> Test::ms_Tests;
#define DO_TEST(x) \
bool Test##x(std::string &error); \
@ -73,7 +73,7 @@ DO_TEST(Basic);
DO_TEST(VafmtAndOverload);
DO_TEST(ThisPtrOffs);
DO_TEST(PlugSys);
DO_TEST(Bail);
//DO_TEST(Bail);
DO_TEST(Reentr);
DO_TEST(Manual);
DO_TEST(Recall);
@ -98,35 +98,30 @@ int main(int argc, char *argv[])
SourceHook::ISourceHook *Test_Factory()
{
return new SourceHook::CSourceHookImpl();
return new SourceHook::Impl::CSourceHookImpl();
}
void Test_Delete(SourceHook::ISourceHook *shptr)
{
delete static_cast<SourceHook::CSourceHookImpl *>(shptr);
delete static_cast<SourceHook::Impl::CSourceHookImpl *>(shptr);
}
void Test_CompleteShutdown(SourceHook::ISourceHook *shptr)
{
static_cast<SourceHook::CSourceHookImpl *>(shptr)->CompleteShutdown();
}
bool Test_IsPluginInUse(SourceHook::ISourceHook *shptr, SourceHook::Plugin plug)
{
return static_cast<SourceHook::CSourceHookImpl *>(shptr)->IsPluginInUse(plug);
static_cast<SourceHook::Impl::CSourceHookImpl *>(shptr)->CompleteShutdown();
}
void Test_UnloadPlugin(SourceHook::ISourceHook *shptr, SourceHook::Plugin plug)
{
static_cast<SourceHook::CSourceHookImpl *>(shptr)->UnloadPlugin(plug);
static_cast<SourceHook::Impl::CSourceHookImpl *>(shptr)->UnloadPlugin(plug);
}
void Test_PausePlugin(SourceHook::ISourceHook *shptr, SourceHook::Plugin plug)
{
static_cast<SourceHook::CSourceHookImpl *>(shptr)->PausePlugin(plug);
static_cast<SourceHook::Impl::CSourceHookImpl *>(shptr)->PausePlugin(plug);
}
void Test_UnpausePlugin(SourceHook::ISourceHook *shptr, SourceHook::Plugin plug)
{
static_cast<SourceHook::CSourceHookImpl *>(shptr)->UnpausePlugin(plug);
static_cast<SourceHook::Impl::CSourceHookImpl *>(shptr)->UnpausePlugin(plug);
}

View File

@ -23,6 +23,7 @@
FavorSizeOrSpeed="0"
AdditionalIncludeDirectories=".."
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;SH_DEBUG"
GeneratePreprocessedFile="0"
StringPooling="TRUE"
MinimalRebuild="TRUE"
BasicRuntimeChecks="3"
@ -299,18 +300,15 @@
<Filter
Name="Header Files"
Filter="h;hpp;hxx;hm;inl;inc">
<File
RelativePath="..\..\FastDelegate.h">
</File>
<File
RelativePath="..\..\sh_list.h">
</File>
<File
RelativePath="..\..\sh_listcat.h">
</File>
<File
RelativePath="..\..\sh_memfuncinfo.h">
</File>
<File
RelativePath="..\..\sh_memory.h">
</File>
<File
RelativePath="..\..\sh_stack.h">
</File>
@ -329,6 +327,27 @@
<File
RelativePath="..\..\sourcehook_impl.h">
</File>
<File
RelativePath="..\..\sourcehook_impl_chook.h">
</File>
<File
RelativePath="..\..\sourcehook_impl_chookidman.h">
</File>
<File
RelativePath="..\..\sourcehook_impl_chookmancont.h">
</File>
<File
RelativePath="..\..\sourcehook_impl_chookmaninfo.h">
</File>
<File
RelativePath="..\..\sourcehook_impl_ciface.h">
</File>
<File
RelativePath="..\..\sourcehook_impl_cproto.h">
</File>
<File
RelativePath="..\..\sourcehook_impl_cvfnptr.h">
</File>
<File
RelativePath="..\sourcehook_test.h">
</File>

View File

@ -21,7 +21,6 @@ struct CSHPtrAutoDestruction
// Access to CSourceHookImpl functions
void Test_CompleteShutdown(SourceHook::ISourceHook *shptr);
bool Test_IsPluginInUse(SourceHook::ISourceHook *shptr, SourceHook::Plugin plug);
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);

View File

@ -338,11 +338,6 @@ namespace
}
};
// GCC's optimizer is too good. I had to add this in order to make it execute a virtual table lookup!
class Whatever : public Test
{
};
SH_DECL_HOOK1(Test, F299, SH_NOATTRIB, 0, bool, const char *);
SH_DECL_HOOK0_void(Test, F1, SH_NOATTRIB, 0);
SH_DECL_HOOK0_void(Test, F2, SH_NOATTRIB, 0);
@ -421,36 +416,43 @@ bool TestBasic(std::string &error)
g_PLID = 1337;
HandlersF1 f1_handlers;
Whatever test;
Test test;
Test *pTest = &test;
// 1) SH_CALL it and call it normally
// 1) Get a call class and call the member through it and normally
SourceHook::CallClass<Test> *cc = SH_GET_CALLCLASS(pTest);
return true;
SH_CALL(pTest, &Test::F1)();
ADD_STATE(State_F1_CallClassGenerated);
SH_CALL(cc, &Test::F1)();
pTest->F1();
CHECK_STATES((&g_States,
new State_F1_CallClassGenerated,
new State_F1_Called,
new State_F1_Called,
NULL), "Part 1");
// 2) Request a call class again
SourceHook::CallClass<Test> *cc2 = SH_GET_CALLCLASS(pTest);
ADD_STATE(State_F1_CallClassGenerated);
SH_CALL(pTest, &Test::F1)();
SH_CALL(pTest, &Test::F1)();
SH_CALL(cc, &Test::F1)();
SH_CALL(cc2, &Test::F1)();
pTest->F1();
SH_CALL(pTest, &Test::F1)();
SH_RELEASE_CALLCLASS(cc2);
ADD_STATE(State_F1_CallClassReleased);
SH_CALL(cc, &Test::F1)();
pTest->F1();
CHECK_STATES((&g_States,
new State_F1_CallClassGenerated,
new State_F1_Called,
new State_F1_Called,
new State_F1_Called,
new State_F1_CallClassReleased,
new State_F1_Called,
new State_F1_Called,
NULL), "Part 2");
@ -460,7 +462,7 @@ bool TestBasic(std::string &error)
g_F1Pre_WhatToDo = MRES_SUPERCEDE;
ADD_STATE(State_F1_HookAdded(SH_ADD_HOOK_MEMFUNC(Test, F1, pTest, &f1_handlers, &HandlersF1::Pre, false) ? true : false));
SH_CALL(pTest, &Test::F1)();
SH_CALL(cc, &Test::F1)();
pTest->F1();
CHECK_STATES((&g_States,
@ -469,26 +471,30 @@ bool TestBasic(std::string &error)
new State_F1_PreHandler_Called(&f1_handlers),
NULL), "Part 3");
// 4) Test source-level compat with callclasses
SourceHook::CallClass<Test> *pCC = SH_GET_CALLCLASS(pTest);
// 4) Rerequest the callclass
SH_RELEASE_CALLCLASS(cc);
SH_CALL(pCC, &Test::F1)();
ADD_STATE(State_F1_CallClassReleased);
cc2 = SH_GET_CALLCLASS(pTest);
ADD_STATE(State_F1_CallClassGenerated);
SH_CALL(cc, &Test::F1)();
pTest->F1();
SH_RELEASE_CALLCLASS(pCC);
CHECK_STATES((&g_States,
new State_F1_CallClassReleased,
new State_F1_CallClassGenerated,
new State_F1_Called,
new State_F1_PreHandler_Called(&f1_handlers),
NULL), "Part 4");
// 5) Check ignore / supercede
g_F1Pre_WhatToDo = MRES_SUPERCEDE;
SH_CALL(pTest, &Test::F1)();
SH_CALL(cc, &Test::F1)();
pTest->F1();
g_F1Pre_WhatToDo = MRES_IGNORED;
SH_CALL(pTest, &Test::F1)();
SH_CALL(cc, &Test::F1)();
pTest->F1();
CHECK_STATES((&g_States,
@ -504,7 +510,7 @@ bool TestBasic(std::string &error)
SH_REMOVE_HOOK_MEMFUNC(Test, F1, pTest, &f1_handlers, &HandlersF1::Pre, false);
ADD_STATE(State_F1_HookRemoved);
SH_CALL(pTest, &Test::F1)();
SH_CALL(cc, &Test::F1)();
pTest->F1();
CHECK_STATES((&g_States,
@ -517,7 +523,7 @@ bool TestBasic(std::string &error)
g_F1Post_WhatToDo = MRES_IGNORED;
ADD_STATE(State_F1_HookAdded(SH_ADD_HOOK(Test, F1, pTest, SH_MEMBER(&f1_handlers, &HandlersF1::Post), true) ? true : false));
SH_CALL(pTest, &Test::F1)();
SH_CALL(cc, &Test::F1)();
pTest->F1();
CHECK_STATES((&g_States,
@ -531,11 +537,11 @@ bool TestBasic(std::string &error)
g_F1Pre_WhatToDo = MRES_IGNORED;
ADD_STATE(State_F1_HookAdded(SH_ADD_HOOK(Test, F1, pTest, SH_MEMBER(&f1_handlers, &HandlersF1::Pre), false) ? true : false));
SH_CALL(pTest, &Test::F1)();
SH_CALL(cc, &Test::F1)();
pTest->F1();
g_F1Pre_WhatToDo = MRES_SUPERCEDE;
SH_CALL(pTest, &Test::F1)();
SH_CALL(cc, &Test::F1)();
pTest->F1();
CHECK_STATES((&g_States,
@ -555,7 +561,7 @@ bool TestBasic(std::string &error)
SH_REMOVE_HOOK(Test, F1, pTest, SH_MEMBER(&f1_handlers, &HandlersF1::Post), true);
ADD_STATE(State_F1_HookRemoved);
SH_CALL(pTest, &Test::F1)();
SH_CALL(cc, &Test::F1)();
pTest->F1();
CHECK_STATES((&g_States,
@ -570,7 +576,7 @@ bool TestBasic(std::string &error)
g_F299Pre_WhatToRet = false;
ADD_STATE(State_F299Ret(pTest->F299("hi")));
ADD_STATE(State_F299Ret(SH_CALL(pTest, &Test::F299)("hi")));
ADD_STATE(State_F299Ret(SH_CALL(cc, &Test::F299)("hi")));
CHECK_STATES((&g_States,
new State_F299_Called("hi"),
@ -582,7 +588,7 @@ bool TestBasic(std::string &error)
// (one add staticfunc in old format)
SH_ADD_HOOK_STATICFUNC(Test, F299, pTest, F299_Pre, false);
ADD_STATE(State_F299Ret(pTest->F299("hi")));
ADD_STATE(State_F299Ret(SH_CALL(pTest, &Test::F299)("hi")));
ADD_STATE(State_F299Ret(SH_CALL(cc, &Test::F299)("hi")));
CHECK_STATES((&g_States,
new State_F299_PreHandlerCalled("hi"),
@ -594,7 +600,7 @@ bool TestBasic(std::string &error)
SH_ADD_HOOK(Test, F299, pTest, SH_STATIC(F299_Post), true);
ADD_STATE(State_F299Ret(pTest->F299("hi")));
ADD_STATE(State_F299Ret(SH_CALL(pTest, &Test::F299)("hi")));
ADD_STATE(State_F299Ret(SH_CALL(cc, &Test::F299)("hi")));
CHECK_STATES((&g_States,
new State_F299_PreHandlerCalled("hi"),
@ -607,7 +613,7 @@ bool TestBasic(std::string &error)
g_F299Pre_WhatToDo = MRES_OVERRIDE;
ADD_STATE(State_F299Ret(pTest->F299("hi")));
ADD_STATE(State_F299Ret(SH_CALL(pTest, &Test::F299)("hi")));
ADD_STATE(State_F299Ret(SH_CALL(cc, &Test::F299)("hi")));
CHECK_STATES((&g_States,
new State_F299_PreHandlerCalled("hi"),
@ -620,7 +626,7 @@ bool TestBasic(std::string &error)
g_F299Pre_WhatToDo = MRES_SUPERCEDE;
ADD_STATE(State_F299Ret(pTest->F299("hi")));
ADD_STATE(State_F299Ret(SH_CALL(pTest, &Test::F299)("hi")));
ADD_STATE(State_F299Ret(SH_CALL(cc, &Test::F299)("hi")));
CHECK_STATES((&g_States,
new State_F299_PreHandlerCalled("hi"),
@ -633,7 +639,7 @@ bool TestBasic(std::string &error)
// (one remove staticfunc in old format)
SH_REMOVE_HOOK_STATICFUNC(Test, F299, pTest, F299_Pre, false);
ADD_STATE(State_F299Ret(pTest->F299("hi")));
ADD_STATE(State_F299Ret(SH_CALL(pTest, &Test::F299)("hi")));
ADD_STATE(State_F299Ret(SH_CALL(cc, &Test::F299)("hi")));
CHECK_STATES((&g_States,
new State_F299_Called("hi"),
@ -645,7 +651,7 @@ bool TestBasic(std::string &error)
SH_REMOVE_HOOK(Test, F299, pTest, SH_STATIC(F299_Post), true);
ADD_STATE(State_F299Ret(pTest->F299("hi")));
ADD_STATE(State_F299Ret(SH_CALL(pTest, &Test::F299)("hi")));
ADD_STATE(State_F299Ret(SH_CALL(cc, &Test::F299)("hi")));
CHECK_STATES((&g_States,
new State_F299_Called("hi"),
@ -654,6 +660,14 @@ bool TestBasic(std::string &error)
new State_F299Ret(true),
NULL), "Part 10.7");
// 11) Release callclass
SH_RELEASE_CALLCLASS(cc);
ADD_STATE(State_F1_CallClassReleased);
CHECK_STATES((&g_States,
new State_F1_CallClassReleased,
NULL), "Part 11");
// 11 1/2) Test removing hook by id

View File

@ -50,11 +50,6 @@ namespace
}
};
// GCC's optimizer is too good. I had to add this in order to make it execute a virtual table lookup!
class Whatever : public IGaben
{
};
SH_DECL_HOOK0_void(IGaben, EatYams, SH_NOATTRIB, 0);
SH_DECL_HOOK1(IGaben, EatYams, const, 1, bool, const char *);
SH_DECL_HOOK2_void_vafmt(IGaben, Vafmt1, SH_NOATTRIB, 0, bool, int);
@ -94,24 +89,25 @@ namespace
bool TestVafmtAndOverload(std::string &error)
{
int h1, h2, h3, h4;
GET_SHPTR(g_SHPtr);
g_PLID = 1337;
Whatever gabgab;
IGaben gabgab;
IGaben *pGab = &gabgab;
// Part 1
SH_CALL(pGab, static_cast<void (IGaben::*)()>(&IGaben::EatYams))();
SH_CALL(pGab, static_cast<bool (IGaben::*)(const char *) const>(&IGaben::EatYams))("Here!");
SH_ADD_HOOK(IGaben, EatYams, pGab, EatYams0_Handler, false);
SH_ADD_HOOK(IGaben, EatYams, pGab, EatYams1_Handler, false);
h1 = SH_ADD_HOOK(IGaben, EatYams, pGab, EatYams0_Handler, false);
h2 = SH_ADD_HOOK(IGaben, EatYams, pGab, EatYams1_Handler, false);
pGab->EatYams();
pGab->EatYams("Here!");
SH_REMOVE_HOOK(IGaben, EatYams, pGab, EatYams0_Handler, false);
SH_REMOVE_HOOK(IGaben, EatYams, pGab, EatYams1_Handler, false);
SH_REMOVE_HOOK_ID(h1);
SH_REMOVE_HOOK_ID(h2);
CHECK_STATES((&g_States,
new State_EatYams_Called(0),
@ -136,10 +132,10 @@ bool TestVafmtAndOverload(std::string &error)
NULL), "Part 2");
// Part 3
SH_ADD_HOOK(IGaben, Vafmt1, pGab, Vafmt1_PreHandler, false);
SH_ADD_HOOK(IGaben, Vafmt1, pGab, Vafmt1_PostHandler, true);
SH_ADD_HOOK(IGaben, Vafmt2, pGab, Vafmt2_PreHandler, false);
SH_ADD_HOOK(IGaben, Vafmt2, pGab, Vafmt2_PostHandler, true);
h1 = SH_ADD_HOOK(IGaben, Vafmt1, pGab, Vafmt1_PreHandler, false);
h2 = SH_ADD_HOOK(IGaben, Vafmt1, pGab, Vafmt1_PostHandler, true);
h3 = SH_ADD_HOOK(IGaben, Vafmt2, pGab, Vafmt2_PreHandler, false);
h4 = SH_ADD_HOOK(IGaben, Vafmt2, pGab, Vafmt2_PostHandler, true);
pGab->Vafmt1(true, 55, "Hello %s%d%s", "BA", 1, "L");
pGab->Vafmt2("Hello %s%d%s", "BA", 1, "LOPAN");
@ -155,10 +151,10 @@ bool TestVafmtAndOverload(std::string &error)
NULL), "Part 3");
// Part 4
SH_REMOVE_HOOK(IGaben, Vafmt1, pGab, Vafmt1_PreHandler, false);
SH_REMOVE_HOOK(IGaben, Vafmt1, pGab, Vafmt1_PostHandler, true);
SH_REMOVE_HOOK(IGaben, Vafmt2, pGab, Vafmt2_PreHandler, false);
SH_REMOVE_HOOK(IGaben, Vafmt2, pGab, Vafmt2_PostHandler, true);
SH_REMOVE_HOOK_ID(h1);
SH_REMOVE_HOOK_ID(h2);
SH_REMOVE_HOOK_ID(h3);
SH_REMOVE_HOOK_ID(h4);
pGab->Vafmt1(true, 55, "Hello %s%d%s", "BA", 1, "L");
pGab->Vafmt2("Hello %s%d%s", "BA", 1, "LOPAN");

View File

@ -47,8 +47,6 @@ namespace
}
};
class DerivedDerived : public Derived { };
SH_DECL_HOOK0_void(Derived, Func1, SH_NOATTRIB, 0);
SH_DECL_HOOK0_void(Derived, Func2, SH_NOATTRIB, 0);
SH_DECL_HOOK0_void(Derived, Func3, SH_NOATTRIB, 0);
@ -74,7 +72,7 @@ bool TestThisPtrOffs(std::string &error)
GET_SHPTR(g_SHPtr);
g_PLID = 1337;
DerivedDerived inst;
Derived inst;
Derived *pD = &inst;
Base1 *pB1 = pD;
Base2 *pB2 = pD;
@ -87,10 +85,11 @@ bool TestThisPtrOffs(std::string &error)
// Get a callclass for pD
// Verify whether the this pointers are correct
// Also call them normally to make sure that we aren't messing it up ;)
SourceHook::CallClass<Derived> *pD_CC = SH_GET_CALLCLASS(pD);
SH_CALL(pD, &Derived::Func1)();
SH_CALL(pD, &Derived::Func2)();
SH_CALL(pD, &Derived::Func3)();
SH_CALL(pD_CC, &Derived::Func1)();
SH_CALL(pD_CC, &Derived::Func2)();
SH_CALL(pD_CC, &Derived::Func3)();
pD->Func1();
pD->Func2();
pD->Func3();
@ -104,8 +103,8 @@ bool TestThisPtrOffs(std::string &error)
new State_Func3_Called(pD),
NULL), "Part 1");
SH_CALL(pD, &Base1::Func1)();
SH_CALL(pD, &Base2::Func2)();
SH_CALL(pD_CC, &Base1::Func1)();
SH_CALL(pD_CC, &Base2::Func2)();
CHECK_STATES((&g_States,
new State_Func1_Called(pB1),
@ -115,8 +114,11 @@ bool TestThisPtrOffs(std::string &error)
// 2)
// Get callclasses for the other ones and verify it as well
SH_CALL(pB1, &Base1::Func1)();
SH_CALL(pB2, &Base2::Func2)();
SourceHook::CallClass<Base1> *pB1_CC = SH_GET_CALLCLASS(pB1);
SourceHook::CallClass<Base2> *pB2_CC = SH_GET_CALLCLASS(pB2);
SH_CALL(pB1_CC, &Base1::Func1)();
SH_CALL(pB2_CC, &Base2::Func2)();
CHECK_STATES((&g_States,
new State_Func1_Called(pB1),
@ -210,11 +212,11 @@ bool TestThisPtrOffs(std::string &error)
new State_Func3_Called(pD),
NULL), "Part 5.1");
SH_CALL(pD, &Derived::Func1)();
SH_CALL(pD, &Derived::Func2)();
SH_CALL(pD, &Derived::Func3)();
SH_CALL(pB1, &Base1::Func1)();
SH_CALL(pB2, &Base2::Func2)();
SH_CALL(pD_CC, &Derived::Func1)();
SH_CALL(pD_CC, &Derived::Func2)();
SH_CALL(pD_CC, &Derived::Func3)();
SH_CALL(pB1_CC, &Base1::Func1)();
SH_CALL(pB2_CC, &Base2::Func2)();
CHECK_STATES((&g_States,
new State_Func1_Called(pB1),
@ -228,5 +230,9 @@ bool TestThisPtrOffs(std::string &error)
SH_REMOVE_HOOK(Derived, Func2, pD, SH_STATIC(Handler_Func2), false);
SH_REMOVE_HOOK(Derived, Func3, pD, SH_STATIC(Handler_Func3), false);
SH_RELEASE_CALLCLASS(pB1_CC);
SH_RELEASE_CALLCLASS(pB2_CC);
SH_RELEASE_CALLCLASS(pD_CC);
return true;
}

View File

@ -19,8 +19,6 @@ namespace
MAKE_STATE(State_Func2H_Called);
MAKE_STATE(State_Func3H_Called);
MAKE_STATE_2(State_PluginInUse, int, bool);
class Test
{
public:
@ -40,14 +38,9 @@ namespace
}
};
// GCC's optimizer is too good. I had to add this in order to make it execute a virtual table lookup!
class Whatever : public Test
{
};
SH_DECL_HOOK0_void(Test, Func1, SH_NOATTRIB, 0);
SH_DECL_HOOK0_void(Test, Func2, SH_NOATTRIB, 0);
SH_DECL_HOOK0_void(Test, Func3, SH_NOATTRIB, 0);
SH_DECL_HOOK0_void(Test, Func1, SH_NOATTRIB, 1);
SH_DECL_HOOK0_void(Test, Func2, SH_NOATTRIB, 1);
SH_DECL_HOOK0_void(Test, Func3, SH_NOATTRIB, 1);
void Handler_Func1()
{
@ -68,7 +61,7 @@ bool TestPlugSys(std::string &error)
GET_SHPTR(g_SHPtr);
g_PLID = 1;
Whatever inst;
Test inst;
Test *pInst = &inst;
// 1)
@ -143,18 +136,6 @@ bool TestPlugSys(std::string &error)
new State_Func3_Called,
NULL), "Part 2.1");
ADD_STATE(State_PluginInUse(1, Test_IsPluginInUse(g_SHPtr, 1)));
ADD_STATE(State_PluginInUse(2, Test_IsPluginInUse(g_SHPtr, 2)));
ADD_STATE(State_PluginInUse(3, Test_IsPluginInUse(g_SHPtr, 3)));
ADD_STATE(State_PluginInUse(4, Test_IsPluginInUse(g_SHPtr, 4)));
CHECK_STATES((&g_States,
new State_PluginInUse(1, true),
new State_PluginInUse(2, true),
new State_PluginInUse(3, true),
new State_PluginInUse(4, false),
NULL), "Part 2.2");
// Unload plugins one by one
Test_UnloadPlugin(g_SHPtr, 3);
@ -174,18 +155,6 @@ bool TestPlugSys(std::string &error)
new State_Func3_Called,
NULL), "Part 2.3.1");
ADD_STATE(State_PluginInUse(1, Test_IsPluginInUse(g_SHPtr, 1)));
ADD_STATE(State_PluginInUse(2, Test_IsPluginInUse(g_SHPtr, 2)));
ADD_STATE(State_PluginInUse(3, Test_IsPluginInUse(g_SHPtr, 3)));
ADD_STATE(State_PluginInUse(4, Test_IsPluginInUse(g_SHPtr, 4)));
CHECK_STATES((&g_States,
new State_PluginInUse(1, true),
new State_PluginInUse(2, true),
new State_PluginInUse(3, false),
new State_PluginInUse(4, false),
NULL), "Part 2.3.2");
Test_UnloadPlugin(g_SHPtr, 2);
pInst->Func1();
@ -201,18 +170,6 @@ bool TestPlugSys(std::string &error)
new State_Func3_Called,
NULL), "Part 2.4.1");
ADD_STATE(State_PluginInUse(1, Test_IsPluginInUse(g_SHPtr, 1)));
ADD_STATE(State_PluginInUse(2, Test_IsPluginInUse(g_SHPtr, 2)));
ADD_STATE(State_PluginInUse(3, Test_IsPluginInUse(g_SHPtr, 3)));
ADD_STATE(State_PluginInUse(4, Test_IsPluginInUse(g_SHPtr, 4)));
CHECK_STATES((&g_States,
new State_PluginInUse(1, true),
new State_PluginInUse(2, false),
new State_PluginInUse(3, false),
new State_PluginInUse(4, false),
NULL), "Part 2.4.2");
Test_UnloadPlugin(g_SHPtr, 1);
pInst->Func1();
@ -225,18 +182,6 @@ bool TestPlugSys(std::string &error)
new State_Func3_Called,
NULL), "Part 2.5.1");
ADD_STATE(State_PluginInUse(1, Test_IsPluginInUse(g_SHPtr, 1)));
ADD_STATE(State_PluginInUse(2, Test_IsPluginInUse(g_SHPtr, 2)));
ADD_STATE(State_PluginInUse(3, Test_IsPluginInUse(g_SHPtr, 3)));
ADD_STATE(State_PluginInUse(4, Test_IsPluginInUse(g_SHPtr, 4)));
CHECK_STATES((&g_States,
new State_PluginInUse(1, false),
new State_PluginInUse(2, false),
new State_PluginInUse(3, false),
new State_PluginInUse(4, false),
NULL), "Part 2.5.2");
// 3)
// Add hooks from "different plugins", then pause the plugins
@ -279,18 +224,6 @@ bool TestPlugSys(std::string &error)
new State_Func3_Called,
NULL), "Part 3.1");
ADD_STATE(State_PluginInUse(1, Test_IsPluginInUse(g_SHPtr, 1)));
ADD_STATE(State_PluginInUse(2, Test_IsPluginInUse(g_SHPtr, 2)));
ADD_STATE(State_PluginInUse(3, Test_IsPluginInUse(g_SHPtr, 3)));
ADD_STATE(State_PluginInUse(4, Test_IsPluginInUse(g_SHPtr, 4)));
CHECK_STATES((&g_States,
new State_PluginInUse(1, true),
new State_PluginInUse(2, true),
new State_PluginInUse(3, true),
new State_PluginInUse(4, false),
NULL), "Part 3.2");
// Unload plugins one by one
Test_PausePlugin(g_SHPtr, 3);
@ -310,18 +243,6 @@ bool TestPlugSys(std::string &error)
new State_Func3_Called,
NULL), "Part 3.3.1");
ADD_STATE(State_PluginInUse(1, Test_IsPluginInUse(g_SHPtr, 1)));
ADD_STATE(State_PluginInUse(2, Test_IsPluginInUse(g_SHPtr, 2)));
ADD_STATE(State_PluginInUse(3, Test_IsPluginInUse(g_SHPtr, 3)));
ADD_STATE(State_PluginInUse(4, Test_IsPluginInUse(g_SHPtr, 4)));
CHECK_STATES((&g_States,
new State_PluginInUse(1, true),
new State_PluginInUse(2, true),
new State_PluginInUse(3, true),
new State_PluginInUse(4, false),
NULL), "Part 3.3.2");
Test_PausePlugin(g_SHPtr, 2);
pInst->Func1();
@ -337,18 +258,6 @@ bool TestPlugSys(std::string &error)
new State_Func3_Called,
NULL), "Part 3.4.1");
ADD_STATE(State_PluginInUse(1, Test_IsPluginInUse(g_SHPtr, 1)));
ADD_STATE(State_PluginInUse(2, Test_IsPluginInUse(g_SHPtr, 2)));
ADD_STATE(State_PluginInUse(3, Test_IsPluginInUse(g_SHPtr, 3)));
ADD_STATE(State_PluginInUse(4, Test_IsPluginInUse(g_SHPtr, 4)));
CHECK_STATES((&g_States,
new State_PluginInUse(1, true),
new State_PluginInUse(2, true),
new State_PluginInUse(3, true),
new State_PluginInUse(4, false),
NULL), "Part 3.4.2");
Test_PausePlugin(g_SHPtr, 1);
pInst->Func1();
@ -361,34 +270,10 @@ bool TestPlugSys(std::string &error)
new State_Func3_Called,
NULL), "Part 3.5.1");
ADD_STATE(State_PluginInUse(1, Test_IsPluginInUse(g_SHPtr, 1)));
ADD_STATE(State_PluginInUse(2, Test_IsPluginInUse(g_SHPtr, 2)));
ADD_STATE(State_PluginInUse(3, Test_IsPluginInUse(g_SHPtr, 3)));
ADD_STATE(State_PluginInUse(4, Test_IsPluginInUse(g_SHPtr, 4)));
CHECK_STATES((&g_States,
new State_PluginInUse(1, true),
new State_PluginInUse(2, true),
new State_PluginInUse(3, true),
new State_PluginInUse(4, false),
NULL), "Part 3.5.2");
Test_UnpausePlugin(g_SHPtr, 1);
Test_UnpausePlugin(g_SHPtr, 2);
Test_UnpausePlugin(g_SHPtr, 3);
ADD_STATE(State_PluginInUse(1, Test_IsPluginInUse(g_SHPtr, 1)));
ADD_STATE(State_PluginInUse(2, Test_IsPluginInUse(g_SHPtr, 2)));
ADD_STATE(State_PluginInUse(3, Test_IsPluginInUse(g_SHPtr, 3)));
ADD_STATE(State_PluginInUse(4, Test_IsPluginInUse(g_SHPtr, 4)));
CHECK_STATES((&g_States,
new State_PluginInUse(1, true),
new State_PluginInUse(2, true),
new State_PluginInUse(3, true),
new State_PluginInUse(4, false),
NULL), "Part 3.6");
pInst->Func1();
pInst->Func2();
pInst->Func3();

View File

@ -52,11 +52,6 @@ namespace
{
ADD_STATE(State_Func5_Called(reinterpret_cast<void*>(this)));
}
};
// GCC's optimizer is too good. I had to add this in order to make it execute a virtual table lookup!
class Whatever : public TheWall
{
};
SH_DECL_HOOK0_void(TheWall, Func1, SH_NOATTRIB, 0);
@ -111,9 +106,11 @@ bool TestManual(std::string &error)
GET_SHPTR(g_SHPtr);
g_PLID = 1337;
Whatever inst;
TheWall inst;
TheWall *p = &inst;
SourceHook::ManualCallClass *cc = SH_GET_MCALLCLASS(p, sizeof(void*));
// 1)
// Call each function
p->Func1();
@ -132,14 +129,14 @@ bool TestManual(std::string &error)
// 1.1)
// Now call each function through the manual call class, using the hook decl and manually
SH_MCALL(p, TheWall_Func1)();
SH_MCALL2(p, MFP_Func1(), 0, 0, 0)();
SH_MCALL(p, TheWall_Func2)(200);
SH_MCALL2(p, MFP_Func2(), 1, 0, 0)(200);
ADD_STATE(State_Return(SH_MCALL(p, TheWall_Func3)()));
ADD_STATE(State_Return(SH_MCALL2(p, MFP_Func3(), 2, 0, 0)()));
ADD_STATE(State_Return(SH_MCALL(p, TheWall_Func4)(400)));
ADD_STATE(State_Return(SH_MCALL2(p, MFP_Func4(), 3, 0, 0)(400)));
SH_MCALL(cc, TheWall_Func1)();
SH_MCALL2(cc, MFP_Func1(), 0, 0, 0)();
SH_MCALL(cc, TheWall_Func2)(200);
SH_MCALL2(cc, MFP_Func2(), 1, 0, 0)(200);
ADD_STATE(State_Return(SH_MCALL(cc, TheWall_Func3)()));
ADD_STATE(State_Return(SH_MCALL2(cc, MFP_Func3(), 2, 0, 0)()));
ADD_STATE(State_Return(SH_MCALL(cc, TheWall_Func4)(400)));
ADD_STATE(State_Return(SH_MCALL2(cc, MFP_Func4(), 3, 0, 0)(400)));
CHECK_STATES((&g_States,
new State_Func1_Called(p),
@ -156,17 +153,6 @@ bool TestManual(std::string &error)
new State_Return(4),
NULL), "Part 1.1");
// Compat: really get a manual call class!
SourceHook::ManualCallClass *pCC = SH_GET_MCALLCLASS(p, sizeof(void*));
SH_MCALL(pCC, TheWall_Func1)();
SH_MCALL2(pCC, MFP_Func1(), 0, 0, 0)();
CHECK_STATES((&g_States,
new State_Func1_Called(p),
new State_Func1_Called(p),
NULL), "Part 1.2");
SH_RELEASE_CALLCLASS(pCC);
// 2)
// Hook each function normally, call them
SH_ADD_HOOK(TheWall, Func1, p, SH_STATIC(Handler_Func1), false);
@ -195,14 +181,14 @@ bool TestManual(std::string &error)
// Call them through the mcallclass
// 2.1)
// Now call each function through the manual call class, using the hook decl and manually
SH_MCALL(p, TheWall_Func1)();
SH_MCALL2(p, MFP_Func1(), 0, 0, 0)();
SH_MCALL(p, TheWall_Func2)(200);
SH_MCALL2(p, MFP_Func2(), 1, 0, 0)(200);
ADD_STATE(State_Return(SH_MCALL(p, TheWall_Func3)()));
ADD_STATE(State_Return(SH_MCALL2(p, MFP_Func3(), 2, 0, 0)()));
ADD_STATE(State_Return(SH_MCALL(p, TheWall_Func4)(400)));
ADD_STATE(State_Return(SH_MCALL2(p, MFP_Func4(), 3, 0, 0)(400)));
SH_MCALL(cc, TheWall_Func1)();
SH_MCALL2(cc, MFP_Func1(), 0, 0, 0)();
SH_MCALL(cc, TheWall_Func2)(200);
SH_MCALL2(cc, MFP_Func2(), 1, 0, 0)(200);
ADD_STATE(State_Return(SH_MCALL(cc, TheWall_Func3)()));
ADD_STATE(State_Return(SH_MCALL2(cc, MFP_Func3(), 2, 0, 0)()));
ADD_STATE(State_Return(SH_MCALL(cc, TheWall_Func4)(400)));
ADD_STATE(State_Return(SH_MCALL2(cc, MFP_Func4(), 3, 0, 0)(400)));
CHECK_STATES((&g_States,
new State_Func1_Called(p),
@ -256,14 +242,14 @@ bool TestManual(std::string &error)
// Call them through the mcallclass
// 3.1)
// Now call each function through the manual call class, using the hook decl and manually
SH_MCALL(p, TheWall_Func1)();
SH_MCALL2(p, MFP_Func1(), 0, 0, 0)();
SH_MCALL(p, TheWall_Func2)(200);
SH_MCALL2(p, MFP_Func2(), 1, 0, 0)(200);
ADD_STATE(State_Return(SH_MCALL(p, TheWall_Func3)()));
ADD_STATE(State_Return(SH_MCALL2(p, MFP_Func3(), 2, 0, 0)()));
ADD_STATE(State_Return(SH_MCALL(p, TheWall_Func4)(400)));
ADD_STATE(State_Return(SH_MCALL2(p, MFP_Func4(), 3, 0, 0)(400)));
SH_MCALL(cc, TheWall_Func1)();
SH_MCALL2(cc, MFP_Func1(), 0, 0, 0)();
SH_MCALL(cc, TheWall_Func2)(200);
SH_MCALL2(cc, MFP_Func2(), 1, 0, 0)(200);
ADD_STATE(State_Return(SH_MCALL(cc, TheWall_Func3)()));
ADD_STATE(State_Return(SH_MCALL2(cc, MFP_Func3(), 2, 0, 0)()));
ADD_STATE(State_Return(SH_MCALL(cc, TheWall_Func4)(400)));
ADD_STATE(State_Return(SH_MCALL2(cc, MFP_Func4(), 3, 0, 0)(400)));
CHECK_STATES((&g_States,
new State_Func1_Called(p),

View File

@ -48,11 +48,6 @@ namespace
}
};
// GCC's optimizer is too good. I had to add this in order to make it execute a virtual table lookup!
struct Whatever : Test
{
};
void Handler1_Func1(int a)
{
ADD_STATE(State_H1_Func1(a));
@ -124,7 +119,7 @@ bool TestRecall(std::string &error)
GET_SHPTR(g_SHPtr);
g_PLID = 1337;
Whatever inst;
Test inst;
Test *ptr = &inst;
SH_ADD_HOOK(Test, Func1, ptr, SH_STATIC(Handler1_Func1), false);

View File

@ -82,7 +82,6 @@ namespace
return 1;
}
};
struct C2
{
virtual void F()
@ -168,15 +167,6 @@ namespace
}
};
struct C1_Derived : public C1 {};
struct C2_Derived : public C2 {};
struct C3_Derived : public C3 {};
struct C4_Derived : public C4 {};
struct C5_Derived : public C5 {};
struct C6_Derived : public C6 {};
struct C7_Derived : public C7 {};
struct C8_Derived : public C8 {};
SH_DECL_HOOK0_void(C1, F, SH_NOATTRIB, 0);
SH_DECL_HOOK0(C1, G, SH_NOATTRIB, 0, int);
SH_DECL_HOOK0_void(C2, F, SH_NOATTRIB, 0);
@ -292,14 +282,14 @@ namespace
return 8;
}
C1_Derived g_C1;
C2_Derived g_C2;
C3_Derived g_C3;
C4_Derived g_C4;
C5_Derived g_C5;
C6_Derived g_C6;
C7_Derived g_C7;
C8_Derived g_C8;
C1 g_C1;
C2 g_C2;
C3 g_C3;
C4 g_C4;
C5 g_C5;
C6 g_C6;
C7 g_C7;
C8 g_C8;
}
bool TestReentr(std::string &error)
@ -332,7 +322,7 @@ bool TestReentr(std::string &error)
SH_ADD_HOOK(C7, G, g_pC7, SH_STATIC(Handler_C7_G), false);
SH_ADD_HOOK(C8, F, g_pC8, SH_STATIC(Handler_C8_F), false);
SH_ADD_HOOK(C8, G, g_pC8, SH_STATIC(Handler_C8_G), false);
g_pC1->F();
CHECK_STATES((&g_States,

View File

@ -76,7 +76,6 @@ namespace
return sth.Func();
}
};
class CHelloDerived : public CHello { };
class CHook
{
@ -100,10 +99,12 @@ bool TestRef(std::string &error)
CDerived der;
CDerived2 der2(11);
CDerived2 der3(12);
CHelloDerived hello;
CHello hello;
CHello *pHello = &hello;
CHook hook;
SourceHook::CallClass<CHello> *cc = SH_GET_CALLCLASS(&hello);
ADD_STATE(State_Result(pHello->Func(base)));
ADD_STATE(State_Result(pHello->Func(der)));
ADD_STATE(State_Result(pHello->Func(der2)));
@ -116,10 +117,10 @@ bool TestRef(std::string &error)
new State_Result(12),
NULL), "Part 1");
ADD_STATE(State_Result(SH_CALL(pHello, &CHello::Func)(base)));
ADD_STATE(State_Result(SH_CALL(pHello, &CHello::Func)(der)));
ADD_STATE(State_Result(SH_CALL(pHello, &CHello::Func)(der2)));
ADD_STATE(State_Result(SH_CALL(pHello, &CHello::Func)(der3)));
ADD_STATE(State_Result(SH_CALL(cc, &CHello::Func)(base)));
ADD_STATE(State_Result(SH_CALL(cc, &CHello::Func)(der)));
ADD_STATE(State_Result(SH_CALL(cc, &CHello::Func)(der2)));
ADD_STATE(State_Result(SH_CALL(cc, &CHello::Func)(der3)));
CHECK_STATES((&g_States,
new State_Result(0),
@ -146,10 +147,10 @@ bool TestRef(std::string &error)
new State_Result(20),
NULL), "Part 3");
ADD_STATE(State_Result(SH_CALL(pHello, &CHello::Func)(base)));
ADD_STATE(State_Result(SH_CALL(pHello, &CHello::Func)(der)));
ADD_STATE(State_Result(SH_CALL(pHello, &CHello::Func)(der2)));
ADD_STATE(State_Result(SH_CALL(pHello, &CHello::Func)(der3)));
ADD_STATE(State_Result(SH_CALL(cc, &CHello::Func)(base)));
ADD_STATE(State_Result(SH_CALL(cc, &CHello::Func)(der)));
ADD_STATE(State_Result(SH_CALL(cc, &CHello::Func)(der2)));
ADD_STATE(State_Result(SH_CALL(cc, &CHello::Func)(der3)));
CHECK_STATES((&g_States,
new State_Result(0),

View File

@ -48,10 +48,6 @@ namespace
return m_Var2;
}
};
class Whatever : public Test
{
};
class CHook
{
@ -102,7 +98,7 @@ bool TestRefRet(std::string &error)
GET_SHPTR(g_SHPtr);
g_PLID = 1;
Whatever test;
Test test;
Test *pTest = &test;
CHook hook;
@ -164,7 +160,8 @@ bool TestRefRet(std::string &error)
CHECK_COND(hook.m_Var == 1337, "Part 4.1");
// Through a callclass
int &ret5 = SH_CALL(pTest, &Test::Func1)();
SourceHook::CallClass<Test> *cc1 = SH_GET_CALLCLASS(&test);
int &ret5 = SH_CALL(cc1, &Test::Func1)();
ADD_STATE(State_Func1_Ret(&ret5));
CHECK_STATES((&g_States,
@ -172,6 +169,7 @@ bool TestRefRet(std::string &error)
new State_Func1_Ret(&test.m_Var1),
NULL), "Part 5");
SH_RELEASE_CALLCLASS(cc1);
////////////////////////////////////////////////////////////////////////////////////////
// Func2 tests

View File

@ -5,7 +5,6 @@
// TEST VP HOOKS
// Test vfnptr-wide hooks
// Also contains a test for removing hooks on deleted instances (by id)
namespace
{
@ -31,76 +30,76 @@ namespace
MAKE_STATE_2(State_Func3_Post, IBase *, int);
class IBase
{
public:
virtual void Func1() = 0;
virtual void Func2() = 0;
virtual void Func3(int x) = 0;
{
public:
virtual void Func1() = 0;
virtual void Func2() = 0;
virtual void Func3(int x) = 0;
};
class CDerived1 : public IBase
{
public:
virtual void Func1()
{
ADD_STATE(State_D1_Func1(this));
}
virtual void Func2()
{
ADD_STATE(State_D1_Func2(this));
}
virtual void Func3(int x)
{
ADD_STATE(State_D1_Func3(this, x));
}
{
public:
virtual void Func1()
{
ADD_STATE(State_D1_Func1(this));
}
virtual void Func2()
{
ADD_STATE(State_D1_Func2(this));
}
virtual void Func3(int x)
{
ADD_STATE(State_D1_Func3(this, x));
}
};
class CDerived2 : public IBase
{
public:
virtual void Func1()
{
ADD_STATE(State_D2_Func1(this));
}
virtual void Func2()
{
ADD_STATE(State_D2_Func2(this));
}
virtual void Func3(int x)
{
ADD_STATE(State_D2_Func3(this, x));
}
{
public:
virtual void Func1()
{
ADD_STATE(State_D2_Func1(this));
}
virtual void Func2()
{
ADD_STATE(State_D2_Func2(this));
}
virtual void Func3(int x)
{
ADD_STATE(State_D2_Func3(this, x));
}
};
void Handler_Func1_Pre()
{
ADD_STATE(State_Func1_Pre(META_IFACEPTR(IBase)));
{
ADD_STATE(State_Func1_Pre(META_IFACEPTR(IBase)));
}
void Handler_Func1_Post()
{
ADD_STATE(State_Func1_Post(META_IFACEPTR(IBase)));
{
ADD_STATE(State_Func1_Post(META_IFACEPTR(IBase)));
}
int g_F2_Pre_HookToRemove = 0;
void Handler_Func2_Pre()
{
ADD_STATE(State_Func2_Pre(META_IFACEPTR(IBase)));
SH_REMOVE_HOOK_ID(g_F2_Pre_HookToRemove);
{
ADD_STATE(State_Func2_Pre(META_IFACEPTR(IBase)));
SH_REMOVE_HOOK_ID(g_F2_Pre_HookToRemove);
}
void Handler_Func2_Post()
{
ADD_STATE(State_Func2_Post(META_IFACEPTR(IBase)));
{
ADD_STATE(State_Func2_Post(META_IFACEPTR(IBase)));
}
void Handler_Func3_Pre(int x)
{
ADD_STATE(State_Func3_Pre(META_IFACEPTR(IBase), x));
RETURN_META_NEWPARAMS(MRES_IGNORED, &IBase::Func3, (x+1));
{
ADD_STATE(State_Func3_Pre(META_IFACEPTR(IBase), x));
RETURN_META_NEWPARAMS(MRES_IGNORED, &IBase::Func3, (x+1));
}
void Handler_Func3_Post(int x)
{
ADD_STATE(State_Func3_Post(META_IFACEPTR(IBase), x));
{
ADD_STATE(State_Func3_Post(META_IFACEPTR(IBase), x));
}
SH_DECL_HOOK0_void(IBase, Func1, SH_NOATTRIB, 0);
@ -111,24 +110,24 @@ namespace
}
bool TestVPHooks(std::string &error)
{
{
GET_SHPTR(g_SHPtr);
g_PLID = 1337;
CDerived1 d1i1;
CDerived1 d1i2;
CDerived2 d2i1;
IBase *p_d1i1 = &d1i1;
IBase *p_d1i2 = &d1i2;
IBase *p_d2i1 = &d2i1;
int hook1 = SH_ADD_VPHOOK(IBase, Func1, p_d1i1, SH_STATIC(Handler_Func1_Pre), false);
p_d1i1->Func1();
p_d1i2->Func1();
p_d2i1->Func1();
g_PLID = 1337;
CDerived1 d1i1;
CDerived1 d1i2;
CDerived2 d2i1;
IBase *p_d1i1 = &d1i1;
IBase *p_d1i2 = &d1i2;
IBase *p_d2i1 = &d2i1;
int hook1 = SH_ADD_VPHOOK(IBase, Func1, p_d1i1, SH_STATIC(Handler_Func1_Pre), false);
p_d1i1->Func1();
p_d1i2->Func1();
p_d2i1->Func1();
CHECK_STATES((&g_States,
new State_Func1_Pre(p_d1i1),
new State_D1_Func1(p_d1i1),
@ -137,45 +136,33 @@ bool TestVPHooks(std::string &error)
new State_D1_Func1(p_d1i2),
new State_D2_Func1(p_d2i1),
NULL), "Part 1");
SH_CALL(p_d1i1, &IBase::Func1)();
SH_CALL(p_d1i2, &IBase::Func1)();
SH_CALL(p_d2i1, &IBase::Func1)();
NULL), "Part 1");
SH_REMOVE_HOOK_ID(hook1);
p_d1i1->Func1();
p_d1i2->Func1();
p_d2i1->Func1();
CHECK_STATES((&g_States,
new State_D1_Func1(p_d1i1),
new State_D1_Func1(p_d1i2),
new State_D2_Func1(p_d2i1),
NULL), "Part 1.1");
SH_REMOVE_HOOK_ID(hook1);
p_d1i1->Func1();
p_d1i2->Func1();
p_d2i1->Func1();
CHECK_STATES((&g_States,
new State_D1_Func1(p_d1i1),
new State_D1_Func1(p_d1i2),
new State_D2_Func1(p_d2i1),
NULL), "Part 2");
// Normal hook, then vp hook
int hook2 = SH_ADD_HOOK(IBase, Func1, p_d1i1, SH_STATIC(Handler_Func1_Pre), false);
hook1 = SH_ADD_VPHOOK(IBase, Func1, p_d1i1, SH_STATIC(Handler_Func1_Pre), false);
p_d1i1->Func1();
p_d1i2->Func1();
p_d2i1->Func1();
NULL), "Part 2");
// Normal hook, then vp hook
int hook2 = SH_ADD_HOOK(IBase, Func1, p_d1i1, SH_STATIC(Handler_Func1_Pre), false);
hook1 = SH_ADD_VPHOOK(IBase, Func1, p_d1i1, SH_STATIC(Handler_Func1_Pre), false);
p_d1i1->Func1();
p_d1i2->Func1();
p_d2i1->Func1();
CHECK_STATES((&g_States,
new State_Func1_Pre(p_d1i1),
new State_Func1_Pre(p_d1i1),
@ -185,14 +172,14 @@ bool TestVPHooks(std::string &error)
new State_D1_Func1(p_d1i2),
new State_D2_Func1(p_d2i1),
NULL), "Part 3");
SH_REMOVE_HOOK_ID(hook1);
p_d1i1->Func1();
p_d1i2->Func1();
p_d2i1->Func1();
NULL), "Part 3");
SH_REMOVE_HOOK_ID(hook1);
p_d1i1->Func1();
p_d1i2->Func1();
p_d2i1->Func1();
CHECK_STATES((&g_States,
new State_Func1_Pre(p_d1i1),
new State_D1_Func1(p_d1i1),
@ -200,57 +187,56 @@ bool TestVPHooks(std::string &error)
new State_D1_Func1(p_d1i2),
new State_D2_Func1(p_d2i1),
NULL), "Part 4");
SH_REMOVE_HOOK_ID(hook2);
p_d1i1->Func1();
p_d1i2->Func1();
p_d2i1->Func1();
NULL), "Part 4");
SH_REMOVE_HOOK_ID(hook2);
p_d1i1->Func1();
p_d1i2->Func1();
p_d2i1->Func1();
CHECK_STATES((&g_States,
new State_D1_Func1(p_d1i1),
new State_D1_Func1(p_d1i2),
new State_D2_Func1(p_d2i1),
NULL), "Part 5");
// Test this:
// Normal hook AND vp hook on Func2
// Func2's pre handler removes the VP hook. It has to work anyway :)
hook1 = SH_ADD_VPHOOK(IBase, Func2, p_d1i1, SH_STATIC(Handler_Func2_Pre), false);
hook2 = SH_ADD_HOOK(IBase, Func2, p_d1i1, SH_STATIC(Handler_Func2_Pre), false);
g_F2_Pre_HookToRemove = hook1;
p_d1i1->Func2();
p_d1i1->Func2();
NULL), "Part 5");
// Test this:
// Normal hook AND vp hook on Func2
// Func2's pre handler removes the VP hook.
hook1 = SH_ADD_VPHOOK(IBase, Func2, p_d1i1, SH_STATIC(Handler_Func2_Pre), false);
hook2 = SH_ADD_HOOK(IBase, Func2, p_d1i1, SH_STATIC(Handler_Func2_Pre), false);
g_F2_Pre_HookToRemove = hook1;
p_d1i1->Func2();
p_d1i1->Func2();
CHECK_STATES((&g_States,
new State_Func2_Pre(p_d1i1),
new State_Func2_Pre(p_d1i1),
new State_D1_Func2(p_d1i1),
new State_Func2_Pre(p_d1i1),
new State_D1_Func2(p_d1i1),
NULL), "Part 6");
SH_REMOVE_HOOK_ID(hook1);
// Hook function 3:
// Using manualhook, VP
hook1 = SH_ADD_MANUALVPHOOK(IBase_Func3_Manual, p_d1i1, SH_STATIC(Handler_Func3_Pre), false);
// Normally, VP
hook2 = SH_ADD_VPHOOK(IBase, Func3, p_d1i1, SH_STATIC(Handler_Func3_Pre), false);
// Normally, no VP
int hook3 = SH_ADD_HOOK(IBase, Func3, p_d1i1, SH_STATIC(Handler_Func3_Pre), false);
p_d1i1->Func3(1);
NULL), "Part 6");
SH_REMOVE_HOOK_ID(hook1);
// Hook function 3:
// Using manualhook, VP
hook1 = SH_ADD_MANUALVPHOOK(IBase_Func3_Manual, p_d1i1, SH_STATIC(Handler_Func3_Pre), false);
// Normally, VP
hook2 = SH_ADD_VPHOOK(IBase, Func3, p_d1i1, SH_STATIC(Handler_Func3_Pre), false);
// Normally, no VP
int hook3 = SH_ADD_HOOK(IBase, Func3, p_d1i1, SH_STATIC(Handler_Func3_Pre), false);
p_d1i1->Func3(1);
CHECK_STATES((&g_States,
new State_Func3_Pre(p_d1i1, 1), // manual vp hook
new State_Func3_Pre(p_d1i1, 2), // normal vp hook
@ -258,90 +244,17 @@ bool TestVPHooks(std::string &error)
new State_D1_Func3(p_d1i1, 4), // function
NULL), "Part 7.1");
p_d1i2->Func3(1);
NULL), "Part 7.1");
p_d1i2->Func3(1);
CHECK_STATES((&g_States,
new State_Func3_Pre(p_d1i2, 1), // manual vp hook
new State_Func3_Pre(p_d1i2, 2), // normal vp hook
new State_D1_Func3(p_d1i2, 3), // function
NULL), "Part 7.2");
SH_REMOVE_HOOK_ID(hook1);
SH_REMOVE_HOOK_ID(hook2);
SH_REMOVE_HOOK_ID(hook3);
// Test direct VP hook
p_d1i1->Func1();
p_d1i2->Func1();
// get vtable manually
void *pVtable = *reinterpret_cast<void**>(p_d1i1);
hook1 = SH_ADD_DVPHOOK(IBase, Func1, pVtable, SH_STATIC(Handler_Func1_Pre), false);
p_d1i1->Func1();
p_d1i2->Func1();
CHECK_STATES((&g_States,
new State_D1_Func1(p_d1i1),
new State_D1_Func1(p_d1i2),
new State_Func1_Pre(p_d1i1),
new State_D1_Func1(p_d1i1),
new State_Func1_Pre(p_d1i2),
new State_D1_Func1(p_d1i2),
NULL), "Part 8.1");
SH_REMOVE_HOOK_ID(hook1);
// Now try manual dvp hooks
p_d1i1->Func3(1);
p_d1i2->Func3(1);
hook1 = SH_ADD_MANUALDVPHOOK(IBase_Func3_Manual, pVtable, SH_STATIC(Handler_Func3_Pre), false);
p_d1i1->Func3(1);
p_d1i2->Func3(1);
CHECK_STATES((&g_States,
new State_D1_Func3(p_d1i1, 1),
new State_D1_Func3(p_d1i2, 1),
new State_Func3_Pre(p_d1i1, 1), // manual vp hook
new State_D1_Func3(p_d1i1, 2), // function
new State_Func3_Pre(p_d1i2, 1), // normal vp hook
new State_D1_Func3(p_d1i2, 2), // function
NULL), "Part 8.2");
// Test removing normal hooks even though the instance is deleted
IBase *pOther = new CDerived1;
SH_ADD_HOOK(IBase, Func1, pOther, SH_STATIC(Handler_Func1_Pre), false);
delete pOther;
// The following line may not crash!
SH_REMOVE_HOOK(IBase, Func1, pOther, SH_STATIC(Handler_Func1_Pre), false);
// Now test GetOrigVfnPtrEntry
void *origfuncptr = (*reinterpret_cast<void***>(p_d1i1))[0];
CHECK_COND(SH_GET_ORIG_VFNPTR_ENTRY(p_d1i1, &IBase::Func1) == origfuncptr, "Part 9.1");
SH_ADD_HOOK(IBase, Func1, p_d1i1, SH_STATIC(Handler_Func1_Pre), false);
CHECK_COND(SH_GET_ORIG_VFNPTR_ENTRY(p_d1i1, &IBase::Func1) == origfuncptr, "Part 9.2");
SH_REMOVE_HOOK(IBase, Func1, p_d1i1, SH_STATIC(Handler_Func1_Pre), false);
CHECK_COND(SH_GET_ORIG_VFNPTR_ENTRY(p_d1i1, &IBase::Func1) == origfuncptr, "Part 9.3");
return true;
}
NULL), "Part 7.2");
return true;
}