1
0
mirror of https://github.com/alliedmodders/metamod-source.git synced 2024-12-04 16:24:16 +01:00
HLMetaModOfficial/core/sourcehook/test/testhookmangen.cpp

1231 lines
36 KiB
C++
Raw Normal View History

Some reorganization. --HG-- rename : sourcemm/IPluginManager.h => core/IPluginManager.h rename : sourcemm/ISmmAPI.h => core/ISmmAPI.h rename : sourcemm/ISmmPlugin.h => core/ISmmPlugin.h rename : sourcemm/ISmmPluginExt.h => core/ISmmPluginExt.h rename : sourcemm/LICENSE.txt => core/LICENSE.txt rename : sourcemm/Makefile => core/Makefile rename : sourcemm/changelog.txt => core/changelog.txt rename : sourcemm/episode1/console.cpp => core/episode1/console.cpp rename : sourcemm/episode1/console.h => core/episode1/console.h rename : sourcemm/episode1/convar_smm.h => core/episode1/convar_smm.h rename : sourcemm/episode1/msvc8/sourcemm.sln => core/episode1/msvc8/sourcemm.sln rename : sourcemm/episode1/msvc8/sourcemm.vcproj => core/episode1/msvc8/sourcemm.vcproj rename : sourcemm/episode1/provider_ep1.cpp => core/episode1/provider_ep1.cpp rename : sourcemm/episode1/provider_ep1.h => core/episode1/provider_ep1.h rename : sourcemm/episode1/vsp_listener.cpp => core/episode1/vsp_listener.cpp rename : sourcemm/episode1/vsp_listener.h => core/episode1/vsp_listener.h rename : sourcemm/metamod.cpp => core/metamod.cpp rename : sourcemm/metamod.h => core/metamod.h rename : sourcemm/metamod_console.cpp => core/metamod_console.cpp rename : sourcemm/metamod_console.h => core/metamod_console.h rename : sourcemm/metamod_oslink.cpp => core/metamod_oslink.cpp rename : sourcemm/metamod_oslink.h => core/metamod_oslink.h rename : sourcemm/metamod_plugins.cpp => core/metamod_plugins.cpp rename : sourcemm/metamod_plugins.h => core/metamod_plugins.h rename : sourcemm/metamod_provider.h => core/metamod_provider.h rename : sourcemm/metamod_util.cpp => core/metamod_util.cpp rename : sourcemm/metamod_util.h => core/metamod_util.h rename : sourcemm/episode2/console.cpp => core/provider/console.cpp rename : sourcemm/episode2/console.h => core/provider/console.h rename : sourcemm/episode2/msvc8/sourcemm.sln => core/provider/msvc8/sourcemm.sln rename : sourcemm/episode2/msvc8/sourcemm.vcproj => core/provider/msvc8/sourcemm.vcproj rename : sourcemm/episode2/msvc9/sourcemm.sln => core/provider/msvc9/sourcemm.sln rename : sourcemm/episode2/msvc9/sourcemm.vcproj => core/provider/msvc9/sourcemm.vcproj rename : sourcemm/episode2/provider_ep2.cpp => core/provider/provider_ep2.cpp rename : sourcemm/episode2/provider_ep2.h => core/provider/provider_ep2.h rename : sourcemm/episode2/vsp_listener.cpp => core/provider/vsp_listener.cpp rename : sourcemm/episode2/vsp_listener.h => core/provider/vsp_listener.h rename : sourcehook/FastDelegate.h => core/sourcehook/FastDelegate.h rename : sourcehook/generate/FastDelegate.h => core/sourcehook/generate/FastDelegate.h rename : sourcehook/generate/FastDelegate.hxx => core/sourcehook/generate/FastDelegate.hxx rename : sourcehook/generate/generate => core/sourcehook/generate/generate rename : sourcehook/generate/generate.bat => core/sourcehook/generate/generate.bat rename : sourcehook/generate/sh_memfuncinfo.h => core/sourcehook/generate/sh_memfuncinfo.h rename : sourcehook/generate/sh_memfuncinfo.hxx => core/sourcehook/generate/sh_memfuncinfo.hxx rename : sourcehook/generate/shworker.bin => core/sourcehook/generate/shworker.bin rename : sourcehook/generate/shworker.exe => core/sourcehook/generate/shworker.exe rename : sourcehook/generate/shworker/Makefile => core/sourcehook/generate/shworker/Makefile rename : sourcehook/generate/shworker/fd_hopter.cpp => core/sourcehook/generate/shworker/fd_hopter.cpp rename : sourcehook/generate/shworker/msvc7/shworker.vcproj => core/sourcehook/generate/shworker/msvc7/shworker.vcproj rename : sourcehook/generate/shworker/msvc8/shworker.vcproj => core/sourcehook/generate/shworker/msvc8/shworker.vcproj rename : sourcehook/generate/shworker/shworker.cpp => core/sourcehook/generate/shworker/shworker.cpp rename : sourcehook/generate/sourcehook.h => core/sourcehook/generate/sourcehook.h rename : sourcehook/generate/sourcehook.hxx => core/sourcehook/generate/sourcehook.hxx rename : sourcehook/sh_list.h => core/sourcehook/sh_list.h rename : sourcehook/sh_memfuncinfo.h => core/sourcehook/sh_memfuncinfo.h rename : sourcehook/sh_memory.h => core/sourcehook/sh_memory.h rename : sourcehook/sh_pagealloc.h => core/sourcehook/sh_pagealloc.h rename : sourcehook/sh_stack.h => core/sourcehook/sh_stack.h rename : sourcehook/sh_string.h => core/sourcehook/sh_string.h rename : sourcehook/sh_tinyhash.h => core/sourcehook/sh_tinyhash.h rename : sourcehook/sh_vector.h => core/sourcehook/sh_vector.h rename : sourcehook/sourcehook.cpp => core/sourcehook/sourcehook.cpp rename : sourcehook/sourcehook.h => core/sourcehook/sourcehook.h rename : sourcehook/sourcehook_hookmangen.cpp => core/sourcehook/sourcehook_hookmangen.cpp rename : sourcehook/sourcehook_hookmangen.h => core/sourcehook/sourcehook_hookmangen.h rename : sourcehook/sourcehook_hookmangen_x86.h => core/sourcehook/sourcehook_hookmangen_x86.h rename : sourcehook/sourcehook_impl.h => core/sourcehook/sourcehook_impl.h rename : sourcehook/sourcehook_impl_chook.h => core/sourcehook/sourcehook_impl_chook.h rename : sourcehook/sourcehook_impl_chookidman.h => core/sourcehook/sourcehook_impl_chookidman.h rename : sourcehook/sourcehook_impl_chookmaninfo.h => core/sourcehook/sourcehook_impl_chookmaninfo.h rename : sourcehook/sourcehook_impl_ciface.h => core/sourcehook/sourcehook_impl_ciface.h rename : sourcehook/sourcehook_impl_cproto.h => core/sourcehook/sourcehook_impl_cproto.h rename : sourcehook/sourcehook_impl_cvfnptr.h => core/sourcehook/sourcehook_impl_cvfnptr.h rename : sourcehook/sourcehook_pibuilder.h => core/sourcehook/sourcehook_pibuilder.h rename : sourcehook/test/Makefile => core/sourcehook/test/Makefile rename : sourcehook/test/generate.bat => core/sourcehook/test/generate.bat rename : sourcehook/test/main.cpp => core/sourcehook/test/main.cpp rename : sourcehook/test/msvc7/test.vcproj => core/sourcehook/test/msvc7/test.vcproj rename : sourcehook/test/msvc8/test.vcproj => core/sourcehook/test/msvc8/test.vcproj rename : sourcehook/test/sourcehook_test.h => core/sourcehook/test/sourcehook_test.h rename : sourcehook/test/test1.cpp => core/sourcehook/test/test1.cpp rename : sourcehook/test/test2.cpp => core/sourcehook/test/test2.cpp rename : sourcehook/test/test3.cpp => core/sourcehook/test/test3.cpp rename : sourcehook/test/test4.cpp => core/sourcehook/test/test4.cpp rename : sourcehook/test/testbail.cpp => core/sourcehook/test/testbail.cpp rename : sourcehook/test/testbail.h => core/sourcehook/test/testbail.h rename : sourcehook/test/testbail2.cpp => core/sourcehook/test/testbail2.cpp rename : sourcehook/test/testevents.h => core/sourcehook/test/testevents.h rename : sourcehook/test/testhookmangen.cpp => core/sourcehook/test/testhookmangen.cpp rename : sourcehook/test/testhookmangen.h => core/sourcehook/test/testhookmangen.h rename : sourcehook/test/testhookmangen.hxx => core/sourcehook/test/testhookmangen.hxx rename : sourcehook/test/testlist.cpp => core/sourcehook/test/testlist.cpp rename : sourcehook/test/testmanual.cpp => core/sourcehook/test/testmanual.cpp rename : sourcehook/test/testmulti.cpp => core/sourcehook/test/testmulti.cpp rename : sourcehook/test/testrecall.cpp => core/sourcehook/test/testrecall.cpp rename : sourcehook/test/testreentr.cpp => core/sourcehook/test/testreentr.cpp rename : sourcehook/test/testref.cpp => core/sourcehook/test/testref.cpp rename : sourcehook/test/testrefret.cpp => core/sourcehook/test/testrefret.cpp rename : sourcehook/test/testvphooks.cpp => core/sourcehook/test/testvphooks.cpp rename : sourcemm/svn_version.h => core/svn_version.h rename : sourcemm/svn_version.tpl => core/svn_version.tpl rename : sourcemm/version.rc => core/version.rc
2008-11-14 11:04:02 +01:00
#include <string>
#include "sourcehook.h"
#include "sourcehook_test.h"
#include "testevents.h"
#include "sh_memory.h"
#include "sh_pagealloc.h"
#include "sourcehook_pibuilder.h"
// TESTHOOKMANGEN
// Test automatic hookman generation
// Tests void and non-void functions
// 0 to 6 params:
// integer-type, float-type, plain-old-data struct and objects with ctors/dtors
// both byval and byref
// also tests ignore/supercede
// also tests recalls
// :TODO: test override as well
namespace
{
StateList g_States;
SourceHook::ISourceHook *g_SHPtr;
SourceHook::Plugin g_PLID;
SourceHook::IHookManagerAutoGen *g_HMAGPtr;
// PtrBuf(ptr) gives ptrs unique numbers
// in the order they appear
SourceHook::List<const void*> g_PtrHash;
bool g_Inside_LeafFunc = false; // inside a hook or a func
bool g_Silent_CtorDtor = false; // inside a hook or a func
// POD / Object types
template <int MYSIZE>
struct POD
{
char x[MYSIZE];
bool operator==(const POD<MYSIZE> &other)
{
return memcmp(reinterpret_cast<void*>(x), reinterpret_cast<const void*>(other.x), MYSIZE) == 0;
}
bool operator==(char other)
{
for (int i = 0; i < MYSIZE; ++i)
{
if (x[i] != other)
return false;
}
return true;
}
};
template <int MYSIZE>
std::ostream& operator <<(std::ostream &os, const POD<MYSIZE> &obj)
{
os << "Some POD!";
return os;
}
MAKE_STATE_1(State_ObjOCtor_Called, int /*MYSIZE*/);
MAKE_STATE_1(State_ObjCCtor_Called, int /*MYSIZE*/);
MAKE_STATE_1(State_ObjODtor_Called, int /*MYSIZE*/);
MAKE_STATE_1(State_ObjAssignOp_Called, int /*MYSIZE*/);
template <int MYSIZE>
struct Object
{
char x[MYSIZE];
Object(char initch)
{
memset(reinterpret_cast<void*>(x), initch, MYSIZE);
if (!g_Inside_LeafFunc && !g_Silent_CtorDtor)
ADD_STATE(State_ObjOCtor_Called(MYSIZE));
}
Object()
{
if (!g_Inside_LeafFunc && !g_Silent_CtorDtor)
ADD_STATE(State_ObjOCtor_Called(MYSIZE));
}
Object(const Object<MYSIZE> & other)
{
memcpy(reinterpret_cast<void*>(x), reinterpret_cast<const void*>(other.x), MYSIZE);
if (!g_Inside_LeafFunc && !g_Silent_CtorDtor)
ADD_STATE(State_ObjCCtor_Called(MYSIZE));
}
~Object()
{
if (!g_Inside_LeafFunc && !g_Silent_CtorDtor)
ADD_STATE(State_ObjODtor_Called(MYSIZE));
}
Object & operator = (const Object &other)
{
if (!g_Inside_LeafFunc && !g_Silent_CtorDtor)
ADD_STATE(State_ObjAssignOp_Called(MYSIZE));
memcpy(reinterpret_cast<void*>(x), reinterpret_cast<const void*>(other.x), MYSIZE);
return *this;
}
bool operator==(const Object<MYSIZE> &other)
{
return memcmp(reinterpret_cast<void*>(x), reinterpret_cast<const void*>(other.x), MYSIZE) == 0;
}
};
template <int MYSIZE>
std::ostream& operator <<(std::ostream &os, const Object<MYSIZE> &obj)
{
os << "Some Obj" << static_cast<int>(obj.x[0]);
return os;
}
// Because of some weird bug in MSVC < 1400
#define MAKE_PODRET(size) \
struct PodRet##size \
{ \
POD<size> actPod; \
bool operator==(const PodRet##size &other) { return actPod == other.actPod; } \
bool operator==(char other) { return actPod == other; } \
}; \
std::ostream& operator <<(std::ostream &os, const PodRet##size &obj) \
{ \
os << obj.actPod; \
return os; \
} \
template <> struct MakeRet< PodRet##size > \
{ \
static PodRet##size Do(int a) \
{ \
PodRet##size x; \
memset(reinterpret_cast<void*>(x.actPod.x), a, size); \
return x; \
} \
};
#define MAKE_OBJRET(size) \
struct ObjRet##size \
{ \
Object<size> actObj; \
bool operator==(const ObjRet##size &other) { return actObj == other.actObj; } \
bool operator==(char other) { return actObj == other; } \
}; \
std::ostream& operator <<(std::ostream &os, const ObjRet##size &obj) \
{ \
os << obj.actObj; \
return os; \
} \
template <> struct MakeRet< ObjRet##size > \
{ \
static ObjRet##size Do(int a) NO_OPTIMIZE \
{ \
ObjRet##size *x = new ObjRet##size; /* ptr: otherwise gcc optimizes away the temp obj */ \
CAutoPtrDestruction< ObjRet##size > apd(x); \
memset(reinterpret_cast<void*>(x->actObj.x), a, size); \
return *x; \
} \
};
// "Increment" something: (reproducible change for recall tests)
// integer: ++
// float: += 1.3
// pod/object: x[i]++, 0 <= i < MYSIZE
template <class T>
struct Increment
{
static void Incr(T &what)
{
++what;
}
};
template<>
struct Increment<float>
{
static void Incr(float &what)
{
what += 1.3f;
}
};
template<>
struct Increment<double>
{
static void Incr(double &what)
{
what += 1.3;
}
};
template<int MYSIZE>
struct Increment< POD<MYSIZE> >
{
static void Incr(POD<MYSIZE> &what)
{
for (int i = 0; i < MYSIZE; ++i)
++ what.x[i];
}
};
template<int MYSIZE>
struct Increment< Object<MYSIZE> >
{
static void Incr(Object<MYSIZE> &what)
{
for (int i = 0; i < MYSIZE; ++i)
++ what.x[i];
}
};
template<>
struct Increment<std::string>
{
static void Incr(std::string &what)
{
what += "!";
}
};
#include "testhookmangen.h"
template <class T>
int PtrBuf(T ptr)
{
int a = 0;
const void *vptr = reinterpret_cast<const void*>(ptr);
for (SourceHook::List<const void*>::iterator iter = g_PtrHash.begin(); iter != g_PtrHash.end(); ++iter)
{
if (*iter == vptr)
return a;
else
++a;
}
g_PtrHash.push_back(vptr);
return static_cast<int>(g_PtrHash.size()) - 1;
}
template <class T>
T PtrBufPtr(T ptr)
{
PtrBuf(ptr);
return ptr;
}
void PtrBuf_Clear(int leave_in = 0)
{
for (SourceHook::List<const void*>::iterator iter = g_PtrHash.begin(); iter != g_PtrHash.end();)
{
if (--leave_in < 0)
iter = g_PtrHash.erase(iter);
else
++iter;
}
}
// MyDelegate base class for other delegates
class MyDelegate : public SourceHook::ISHDelegate
{
// Unneeded
// because we don't use old SH_REMOVE_HOOK syntax
virtual bool IsEqual(SourceHook::ISHDelegate *pOtherDeleg)
{
return false;
}
virtual void DeleteThis()
{
delete this;
}
};
THGM_MAKE_TEST0_void(0);
THGM_SETUP_PI0(0);
THGM_MAKE_TEST1_void(1, char);
THGM_SETUP_PI1(1, char, SourceHook::PassInfo::PassType_Basic, SourceHook::PassInfo::PassFlag_ByVal);
THGM_MAKE_TEST1_void(2, short);
THGM_SETUP_PI1(2, short, SourceHook::PassInfo::PassType_Basic, SourceHook::PassInfo::PassFlag_ByVal);
THGM_MAKE_TEST1_void(3, int);
THGM_SETUP_PI1(3, int, SourceHook::PassInfo::PassType_Basic, SourceHook::PassInfo::PassFlag_ByVal);
THGM_MAKE_TEST1_void(4, float);
THGM_SETUP_PI1(4, float, SourceHook::PassInfo::PassType_Float, SourceHook::PassInfo::PassFlag_ByVal);
THGM_MAKE_TEST1_void(5, double);
THGM_SETUP_PI1(5, double, SourceHook::PassInfo::PassType_Float, SourceHook::PassInfo::PassFlag_ByVal);
THGM_MAKE_TEST5_void(6, char, short, int, float, double);
THGM_SETUP_PI5(6,
char, SourceHook::PassInfo::PassType_Basic, SourceHook::PassInfo::PassFlag_ByVal,
short, SourceHook::PassInfo::PassType_Basic, SourceHook::PassInfo::PassFlag_ByVal,
int, SourceHook::PassInfo::PassType_Basic, SourceHook::PassInfo::PassFlag_ByVal,
float, SourceHook::PassInfo::PassType_Float, SourceHook::PassInfo::PassFlag_ByVal,
double, SourceHook::PassInfo::PassType_Float, SourceHook::PassInfo::PassFlag_ByVal
);
THGM_MAKE_TEST2_void(7, char&, double&);
THGM_SETUP_PI2(7,
char&, SourceHook::PassInfo::PassType_Basic, SourceHook::PassInfo::PassFlag_ByRef,
double&, SourceHook::PassInfo::PassType_Float, SourceHook::PassInfo::PassFlag_ByRef
);
THGM_MAKE_TEST1_void(8, POD<7>);
THGM_SETUP_PI1(8, POD<7>, SourceHook::PassInfo::PassType_Object, SourceHook::PassInfo::PassFlag_ByVal);
THGM_MAKE_TEST1_void(9, POD<600>);
THGM_SETUP_PI1(9, POD<600>, SourceHook::PassInfo::PassType_Object, SourceHook::PassInfo::PassFlag_ByVal);
THGM_MAKE_TEST1_void(10, POD<600> &);
THGM_SETUP_PI1(10, POD<600> &, SourceHook::PassInfo::PassType_Object, SourceHook::PassInfo::PassFlag_ByRef);
THGM_MAKE_TEST2_void(11, Object<3>, Object<600>&);
THGM_SETUP_PI2(11,
Object<3>, SourceHook::PassInfo::PassType_Object, SourceHook::PassInfo::PassFlag_ByVal | SourceHook::PassInfo::PassFlag_OCtor | SourceHook::PassInfo::PassFlag_ODtor | SourceHook::PassInfo::PassFlag_CCtor,
Object<600> &, SourceHook::PassInfo::PassType_Object, SourceHook::PassInfo::PassFlag_ByRef | SourceHook::PassInfo::PassFlag_OCtor | SourceHook::PassInfo::PassFlag_ODtor | SourceHook::PassInfo::PassFlag_CCtor
);
THGM_MAKE_TEST0(101, char);
THGM_SETUP_PI0(101);
THGM_SETUP_RI(101, char, SourceHook::PassInfo::PassType_Basic, SourceHook::PassInfo::PassFlag_ByVal);
THGM_MAKE_TEST0(102, short);
THGM_SETUP_PI0(102);
THGM_SETUP_RI(102, short, SourceHook::PassInfo::PassType_Basic, SourceHook::PassInfo::PassFlag_ByVal);
THGM_MAKE_TEST0(103, int);
THGM_SETUP_PI0(103);
THGM_SETUP_RI(103, int, SourceHook::PassInfo::PassType_Basic, SourceHook::PassInfo::PassFlag_ByVal);
THGM_MAKE_TEST0(104, float);
THGM_SETUP_PI0(104);
THGM_SETUP_RI(104, float, SourceHook::PassInfo::PassType_Float, SourceHook::PassInfo::PassFlag_ByVal);
THGM_MAKE_TEST0(105, double);
THGM_SETUP_PI0(105);
THGM_SETUP_RI(105, double, SourceHook::PassInfo::PassType_Float, SourceHook::PassInfo::PassFlag_ByVal);
// pod 1-13
MAKE_PODRET(1);
THGM_MAKE_TEST1(106, PodRet1, int);
THGM_SETUP_PI1(106,
int, SourceHook::PassInfo::PassType_Basic, SourceHook::PassInfo::PassFlag_ByVal
);
THGM_SETUP_RI(106, PodRet1, SourceHook::PassInfo::PassType_Object, SourceHook::PassInfo::PassFlag_ByVal);
MAKE_PODRET(4);
THGM_MAKE_TEST1(107, PodRet4, int);
THGM_SETUP_PI1(107,
int, SourceHook::PassInfo::PassType_Basic, SourceHook::PassInfo::PassFlag_ByVal
);
THGM_SETUP_RI(107, PodRet4, SourceHook::PassInfo::PassType_Object, SourceHook::PassInfo::PassFlag_ByVal);
MAKE_PODRET(8);
THGM_MAKE_TEST1(108, PodRet8, int);
THGM_SETUP_PI1(108,
int, SourceHook::PassInfo::PassType_Basic, SourceHook::PassInfo::PassFlag_ByVal
);
THGM_SETUP_RI(108, PodRet8, SourceHook::PassInfo::PassType_Object, SourceHook::PassInfo::PassFlag_ByVal);
MAKE_PODRET(13);
THGM_MAKE_TEST1(109, PodRet13, int);
THGM_SETUP_PI1(109,
int, SourceHook::PassInfo::PassType_Basic, SourceHook::PassInfo::PassFlag_ByVal
);
THGM_SETUP_RI(109, PodRet13, SourceHook::PassInfo::PassType_Object, SourceHook::PassInfo::PassFlag_ByVal);
MAKE_OBJRET(13);
THGM_MAKE_TEST1(110, ObjRet13, int);
THGM_SETUP_PI1(110,
int, SourceHook::PassInfo::PassType_Basic, SourceHook::PassInfo::PassFlag_ByVal
);
THGM_SETUP_RI(110, ObjRet13, SourceHook::PassInfo::PassType_Object,
SourceHook::PassInfo::PassFlag_ByVal | SourceHook::PassInfo::PassFlag_OCtor | SourceHook::PassInfo::PassFlag_ODtor |
SourceHook::PassInfo::PassFlag_CCtor | SourceHook::PassInfo::PassFlag_AssignOp);
MAKE_OBJRET(111);
ObjRet111 g_O111_0;
ObjRet111 g_O111_1;
ObjRet111 g_O111_2;
ObjRet111 g_O111_3;
ObjRet111 g_O111_4;
template <>
struct MakeRet< ObjRet111& >
{
static ObjRet111 &Do(int a)
{
switch (a)
{
case 0:
return g_O111_0;
case 1:
return g_O111_1;
case 2:
return g_O111_2;
case 3:
return g_O111_3;
default:
return g_O111_4;
}
}
};
THGM_MAKE_TEST0(111, ObjRet111& );
THGM_SETUP_PI0(111);
THGM_SETUP_RI(111, ObjRet111& , SourceHook::PassInfo::PassType_Object,
SourceHook::PassInfo::PassFlag_ByRef | SourceHook::PassInfo::PassFlag_OCtor | SourceHook::PassInfo::PassFlag_ODtor |
SourceHook::PassInfo::PassFlag_CCtor | SourceHook::PassInfo::PassFlag_AssignOp);
THGM_MAKE_TEST3_void(150, int, double, int);
THGM_SETUP_PI3(150,
int, SourceHook::PassInfo::PassType_Basic, SourceHook::PassInfo::PassFlag_ByVal,
double, SourceHook::PassInfo::PassType_Float, SourceHook::PassInfo::PassFlag_ByVal,
int, SourceHook::PassInfo::PassType_Basic, SourceHook::PassInfo::PassFlag_ByVal);
// vafmt tests
THGM_MAKE_TEST0_vafmt_void(200);
THGM_SETUP_PI0(200);
THGM_MAKE_TEST1_vafmt_void(201, char);
THGM_SETUP_PI1(201, char, SourceHook::PassInfo::PassType_Basic, SourceHook::PassInfo::PassFlag_ByVal);
THGM_MAKE_TEST1_vafmt_void(203, int);
THGM_SETUP_PI1(203, int, SourceHook::PassInfo::PassType_Basic, SourceHook::PassInfo::PassFlag_ByVal);
THGM_MAKE_TEST5_vafmt_void(206, char, short, int, float, double);
THGM_SETUP_PI5(206,
char, SourceHook::PassInfo::PassType_Basic, SourceHook::PassInfo::PassFlag_ByVal,
short, SourceHook::PassInfo::PassType_Basic, SourceHook::PassInfo::PassFlag_ByVal,
int, SourceHook::PassInfo::PassType_Basic, SourceHook::PassInfo::PassFlag_ByVal,
float, SourceHook::PassInfo::PassType_Float, SourceHook::PassInfo::PassFlag_ByVal,
double, SourceHook::PassInfo::PassType_Float, SourceHook::PassInfo::PassFlag_ByVal
);
THGM_MAKE_TEST2_vafmt_void(207, char&, double&);
THGM_SETUP_PI2(207,
char&, SourceHook::PassInfo::PassType_Basic, SourceHook::PassInfo::PassFlag_ByRef,
double&, SourceHook::PassInfo::PassType_Float, SourceHook::PassInfo::PassFlag_ByRef
);
THGM_MAKE_TEST1_vafmt_void(208, POD<7>);
THGM_SETUP_PI1(208, POD<7>, SourceHook::PassInfo::PassType_Object, SourceHook::PassInfo::PassFlag_ByVal);
THGM_MAKE_TEST1_vafmt_void(210, POD<600> &);
THGM_SETUP_PI1(210, POD<600> &, SourceHook::PassInfo::PassType_Object, SourceHook::PassInfo::PassFlag_ByRef)
THGM_MAKE_TEST1_vafmt(211, int, int);
THGM_SETUP_PI1(211,
int, SourceHook::PassInfo::PassType_Basic, SourceHook::PassInfo::PassFlag_ByVal
);
THGM_SETUP_RI(211, int, SourceHook::PassInfo::PassType_Basic, SourceHook::PassInfo::PassFlag_ByVal);
THGM_MAKE_TEST1_vafmt(212, double, int);
THGM_SETUP_PI1(212,
int, SourceHook::PassInfo::PassType_Basic, SourceHook::PassInfo::PassFlag_ByVal
);
THGM_SETUP_RI(212, double, SourceHook::PassInfo::PassType_Float, SourceHook::PassInfo::PassFlag_ByVal);
THGM_MAKE_TEST1_vafmt(213, PodRet8, int);
THGM_SETUP_PI1(213,
int, SourceHook::PassInfo::PassType_Basic, SourceHook::PassInfo::PassFlag_ByVal
);
THGM_SETUP_RI(213, PodRet8, SourceHook::PassInfo::PassType_Object, SourceHook::PassInfo::PassFlag_ByVal);
THGM_MAKE_TEST1_vafmt_void(214, Object<133>);
THGM_SETUP_PI1(214, Object<133>, SourceHook::PassInfo::PassType_Object,
SourceHook::PassInfo::PassFlag_ByVal | SourceHook::PassInfo::PassFlag_OCtor | SourceHook::PassInfo::PassFlag_ODtor |
SourceHook::PassInfo::PassFlag_CCtor | SourceHook::PassInfo::PassFlag_AssignOp);
MAKE_STATE(State_Hello_Func4_Called);
MAKE_STATE(State_Hello_Func79_Called);
MAKE_STATE(State_Hello_Func4_PreHook);
MAKE_STATE(State_Hello_Func79_PreHook);
// Test for larger vtable indices
class Hello
{
public:
virtual void Func0() {}
virtual void Func1() {}
virtual void Func2() {}
virtual void Func3() {}
virtual void Func4()
{
ADD_STATE(State_Hello_Func4_Called);
}
virtual void Func5() {}
virtual void Func6() {}
virtual void Func7() {}
virtual void Func8() {}
virtual void Func9() {}
virtual void Func10() {}
virtual void Func11() {}
virtual void Func12() {}
virtual void Func13() {}
virtual void Func14() {}
virtual void Func15() {}
virtual void Func16() {}
virtual void Func17() {}
virtual void Func18() {}
virtual void Func19() {}
virtual void Func20() {}
virtual void Func21() {}
virtual void Func22() {}
virtual void Func23() {}
virtual void Func24() {}
virtual void Func25() {}
virtual void Func26() {}
virtual void Func27() {}
virtual void Func28() {}
virtual void Func29() {}
virtual void Func30() {}
virtual void Func31() {}
virtual void Func32() {}
virtual void Func33() {}
virtual void Func34() {}
virtual void Func35() {}
virtual void Func36() {}
virtual void Func37() {}
virtual void Func38() {}
virtual void Func39() {}
virtual void Func40() {}
virtual void Func41() {}
virtual void Func42() {}
virtual void Func43() {}
virtual void Func44() {}
virtual void Func45() {}
virtual void Func46() {}
virtual void Func47() {}
virtual void Func48() {}
virtual void Func49() {}
virtual void Func50() {}
virtual void Func51() {}
virtual void Func52() {}
virtual void Func53() {}
virtual void Func54() {}
virtual void Func55() {}
virtual void Func56() {}
virtual void Func57() {}
virtual void Func58() {}
virtual void Func59() {}
virtual void Func60() {}
virtual void Func61() {}
virtual void Func62() {}
virtual void Func63() {}
virtual void Func64() {}
virtual void Func65() {}
virtual void Func66() {}
virtual void Func67() {}
virtual void Func68() {}
virtual void Func69() {}
virtual void Func70() {}
virtual void Func71() {}
virtual void Func72() {}
virtual void Func73() {}
virtual void Func74() {}
virtual void Func75() {}
virtual void Func76() {}
virtual void Func77() {}
virtual void Func78() {}
virtual void Func79()
{
ADD_STATE(State_Hello_Func79_Called);
}
};
class Hello_Func4_Deleg : public MyDelegate
{
virtual void Func()
{
ADD_STATE(State_Hello_Func4_PreHook);
}
};
class Hello_Func79_Deleg : public MyDelegate
{
int a;
virtual void Func()
{
ADD_STATE(State_Hello_Func79_PreHook);
}
};
bool Tests1(std::string &error)
{
THGM_DO_TEST_void(0, ());
THGM_DO_TEST_void(1, (100));
THGM_DO_TEST_void(2, (0x1F00));
THGM_DO_TEST_void(3, (0x1F000000));
THGM_DO_TEST_void(4, (0.5f));
THGM_DO_TEST_void(5, (5.5));
THGM_DO_TEST_void(6, (100, 0x1f00, 0x1f000000, 0.5f, 5.5));
return true;
}
bool Tests2(std::string &error)
{
char a = 5;
double b = 233.33;
THGM_DO_TEST_void(7, (a, b));
POD<7> pod7 = MakeRet< POD<7> >::Do(78);
THGM_DO_TEST_void(8, (pod7));
POD<600> pod600 = MakeRet< POD<600> >::Do(34);
THGM_DO_TEST_void(9, (pod600));
THGM_DO_TEST_void(10, (pod600));
// Test11: Special: constructors/destructors
PtrBuf_Clear();
Object<3> *obj3_real = new Object<3>(33);
Object<600> *obj600_real = new Object<600>(21);
Object<3> & obj3 = *obj3_real;
Object<600> & obj600 = *obj600_real;
CHECK_STATES((&g_States,
new State_ObjOCtor_Called(3),
new State_ObjOCtor_Called(600),
NULL), "Test11 Part0");
setuppi_11();
SourceHook::HookManagerPubFunc myhookman11 = g_HMAGPtr->MakeHookMan(protoinfo_11, 0, 0); \
CAutoReleaseHookMan arhm_11(myhookman11); \
int hook1_11, hook2_11, hook3_11, hook4_11;
TestClass11 *pTest11 = new TestClass11;
CAutoPtrDestruction<TestClass11> apd11(pTest11);
/* no hooks - no hooks */
PtrBuf_Clear();
pTest11->Func(obj3, obj600);
g_Inside_LeafFunc = true;
CHECK_STATES((&g_States,
new State_ObjCCtor_Called(3),
new State_Func11(pTest11, ParamState_m11 (obj3, obj600)),
new State_ObjODtor_Called(3),
NULL), "Test" "11" " Part1");
g_Inside_LeafFunc = false;
/* hook1 - no hooks */
THGM_ADD_HOOK(11, 1);
PtrBuf_Clear();
pTest11->Func(obj3, obj600);
g_Inside_LeafFunc = true;
CHECK_STATES((&g_States,
new State_ObjCCtor_Called(3),
new State_ObjCCtor_Called(3),
new State_Deleg_11(1, pTest11, 0, ParamState_m11 (obj3, obj600)),
new State_ObjODtor_Called(3),
new State_ObjCCtor_Called(3),
new State_Func11(pTest11, ParamState_m11 (obj3, obj600)),
new State_ObjODtor_Called(3),
new State_ObjODtor_Called(3),
NULL), "Test" "11" " Part2");
g_Inside_LeafFunc = false;
THGM_REMOVE_HOOK(11, 1);
/* hook1, hook2 - hook3, hook4 */
THGM_ADD_HOOK(11, 1);
THGM_ADD_HOOK(11, 2);
THGM_ADD_HOOK(11, 3);
THGM_ADD_HOOK(11, 4);
PtrBuf_Clear();
pTest11->Func(obj3, obj600);
g_Inside_LeafFunc = true;
CHECK_STATES((&g_States,
new State_ObjCCtor_Called(3),
new State_ObjCCtor_Called(3),
new State_Deleg_11(1, pTest11, 0, ParamState_m11 (obj3, obj600)),
new State_ObjODtor_Called(3),
new State_ObjCCtor_Called(3),
new State_Deleg_11(2, pTest11, 1, ParamState_m11 (obj3, obj600)),
new State_ObjODtor_Called(3),
new State_ObjCCtor_Called(3),
new State_Deleg_11(3, pTest11, 2, ParamState_m11 (obj3, obj600)),
new State_ObjODtor_Called(3),
new State_ObjCCtor_Called(3),
new State_Deleg_11(4, pTest11, 3, ParamState_m11 (obj3, obj600)),
new State_ObjODtor_Called(3),
new State_ObjODtor_Called(3),
NULL), "Test" "11" " Part3");
g_Inside_LeafFunc = false;
/* hook1 - hook3, hook4 WITH RECALLS */
THGM_REMOVE_HOOK(11, 2);
PtrBuf_Clear();
TestClass11::ms_DoRecall = true;
pTest11->Func(obj3, obj600);
g_Inside_LeafFunc = true;
CHECK_STATES((&g_States,
new State_ObjCCtor_Called(3),
new State_ObjCCtor_Called(3),
new State_Deleg_11(1, pTest11, 0 /* first deleg ptr */, ParamState_m11 (obj3, obj600)),
// recall !
// second hookfunc -> new copy
new State_ObjCCtor_Called(3),
// in second hookfunc now
// -> calls orig func
new State_ObjCCtor_Called(3),
new State_Func11(pTest11, ParamState_m11 (obj3, obj600)(1)),
new State_ObjODtor_Called(3),
// calls first posthook
new State_ObjCCtor_Called(3),
new State_Deleg_11(3, pTest11, 1 /* second deleg ptr */, ParamState_m11 (obj3, obj600)(1)),
// recall!
// third hookfunc -> new copy
new State_ObjCCtor_Called(3),
// calls second posthook
new State_ObjCCtor_Called(3),
new State_Deleg_11(4, pTest11, 2 /* third deleg ptr */, ParamState_m11 (obj3, obj600)(2)),
// recall!
// fourth hookfunc -> new copy
new State_ObjCCtor_Called(3),
// has nothing to do though!
// fourth hookfunc done -> ret
new State_ObjODtor_Called(3),
// third hookfunc done -> ret
new State_ObjODtor_Called(3),
// ret from hookhandler which did the recall
new State_ObjODtor_Called(3),
// second hookfunc done -> ret
new State_ObjODtor_Called(3),
// ret from hookhandler which did the recall
new State_ObjODtor_Called(3),
// deleg1's instance
new State_ObjODtor_Called(3),
// first hookfunc done -> ret
new State_ObjODtor_Called(3),
NULL), "Test" "11" " Part4");
g_Inside_LeafFunc = false;
THGM_REMOVE_HOOK(11, 1);
THGM_REMOVE_HOOK(11, 3);
THGM_REMOVE_HOOK(11, 4);
delete obj3_real;
delete obj600_real;
CHECK_STATES((&g_States,
new State_ObjODtor_Called(3),
new State_ObjODtor_Called(600),
NULL), "Test11 Part100");
return true;
}
bool Tests3(std::string &error)
{
THGM_DO_TEST(101, ());
THGM_DO_TEST(102, ());
THGM_DO_TEST(103, ());
THGM_DO_TEST(104, ());
THGM_DO_TEST(105, ());
// pod returns
THGM_DO_TEST(106, (5));
THGM_DO_TEST(107, (5));
THGM_DO_TEST(108, (5));
THGM_DO_TEST(109, (5));
return true;
}
bool Tests4(std::string &error)
{
// Test110: Special: constructors/destructors on return
PtrBuf_Clear();
ObjRet13 *obj13_real = new ObjRet13;
ObjRet13 &obj13 = *obj13_real;
CHECK_STATES((&g_States,
new State_ObjOCtor_Called(13),
NULL), "Test110 Part0");
setuppi_110();
setupri_110();
SourceHook::HookManagerPubFunc myhookman110 = g_HMAGPtr->MakeHookMan(protoinfo_110, 0, 0); \
CAutoReleaseHookMan arhm_110(myhookman110); \
int hook1_110, hook2_110, hook3_110, hook4_110;
TestClass110 *pTest110 = new TestClass110;
CAutoPtrDestruction<TestClass110> apd110(pTest110);
/* no hooks - no hooks */
PtrBuf_Clear();
obj13 = pTest110->Func(5);
g_Inside_LeafFunc = true;
CHECK_STATES((&g_States,
new State_Func110(pTest110, ParamState_m110 (5)),
new State_ObjOCtor_Called(13), // MakeRet: Construction of x
new State_ObjCCtor_Called(13), // Return from MakeRet -> construct temporary object in our stack
new State_ObjODtor_Called(13), // MakeRet: Destruction of x
new State_ObjAssignOp_Called(13), // assign: obj13 = temporary object in our stack
new State_ObjODtor_Called(13), // Func110: destruction of temporary object
NULL), "Test" "110" " Part1");
g_Inside_LeafFunc = false;
/* hook1 - no hooks */
THGM_ADD_HOOK(110, 1);
PtrBuf_Clear();
obj13 = pTest110->Func(5);
g_Inside_LeafFunc = true;
CHECK_STATES((&g_States,
// HookFunc: construct orig_ret/override_ret/plugin_ret objects
new State_ObjOCtor_Called(13),
new State_ObjOCtor_Called(13),
new State_ObjOCtor_Called(13),
// Calling delegate
new State_Deleg_110(1, pTest110, 0, ParamState_m110 (5)),
new State_ObjOCtor_Called(13), // MakeRet: Construction of x
new State_ObjCCtor_Called(13), // Return from MakeRet -> construct temporary object in HookFunc's stack
new State_ObjODtor_Called(13), // MakeRet: Destruction of x
// back in hookfunc
new State_ObjAssignOp_Called(13), // assign: plugin_ret = temporary object in HookFunc's stack
new State_ObjODtor_Called(13), // destruction of temporary object in HookFunc's stack
// Calling orig function Func110
new State_Func110(pTest110, ParamState_m110 (5)),
new State_ObjOCtor_Called(13), // MakeRet: Construction of x
new State_ObjCCtor_Called(13), // Return from MakeRet -> construct temporary object in HookFunc's stack
new State_ObjODtor_Called(13), // MakeRet: Destruction of x
// back in hookfunc
new State_ObjAssignOp_Called(13), // assign: orig_ret = temporary object in HookFunc's stack
new State_ObjODtor_Called(13), // destruction of temporary object in HookFunc's stack
// hookfunc is returning:
new State_ObjCCtor_Called(13), // copy to temp object in our stack
// hookfunc cleans up its stack -> destroys plugin_ret/override_ret/orig_ret
new State_ObjODtor_Called(13),
new State_ObjODtor_Called(13),
new State_ObjODtor_Called(13),
// we are in our function: assign
new State_ObjAssignOp_Called(13), // assign: obj13 = temporary object in our stack
new State_ObjODtor_Called(13), // Func110: destruction of temporary object
NULL), "Test" "11" " Part2");
CHECK_COND(obj13 == 0, "Test" "11" " Part 2.1");
g_Inside_LeafFunc = false;
THGM_REMOVE_HOOK(110, 1);
/* hook1, hook2 - hook3, hook4 */
THGM_ADD_HOOK(110, 1);
THGM_ADD_HOOK(110, 2);
THGM_ADD_HOOK(110, 3);
THGM_ADD_HOOK(110, 4);
PtrBuf_Clear();
obj13 = pTest110->Func(5);
g_Inside_LeafFunc = true;
CHECK_STATES((&g_States,
// HookFunc: construct orig_ret/override_ret/plugin_ret objects
new State_ObjOCtor_Called(13),
new State_ObjOCtor_Called(13),
new State_ObjOCtor_Called(13),
// Calling delegate1
new State_Deleg_110(1, pTest110, 0, ParamState_m110 (5)),
new State_ObjOCtor_Called(13), // MakeRet: Construction of x
new State_ObjCCtor_Called(13), // Return from MakeRet -> construct temporary object in HookFunc's stack
new State_ObjODtor_Called(13), // MakeRet: Destruction of x
// back in hookfunc
new State_ObjAssignOp_Called(13), // assign: plugin_ret = temporary object in HookFunc's stack
new State_ObjODtor_Called(13), // destruction of temporary object in HookFunc's stack
// Calling delegate2
new State_Deleg_110(2, pTest110, 1, ParamState_m110 (5)),
new State_ObjOCtor_Called(13), // MakeRet: Construction of x
new State_ObjCCtor_Called(13), // Return from MakeRet -> construct temporary object in HookFunc's stack
new State_ObjODtor_Called(13), // MakeRet: Destruction of x
// back in hookfunc
new State_ObjAssignOp_Called(13), // assign: plugin_ret = temporary object in HookFunc's stack
new State_ObjODtor_Called(13), // destruction of temporary object in HookFunc's stack
// hookfunc finds out that the hook wanted to SUPERCEDE --> copy to override_Ret
new State_ObjAssignOp_Called(13),
// SUPERCEDE -> orig function is not called
// instead: orig_ret = override_ret
new State_ObjAssignOp_Called(13),
// Calling delegate3
new State_Deleg_110(3, pTest110, 2, ParamState_m110 (5)),
new State_ObjOCtor_Called(13), // MakeRet: Construction of x
new State_ObjCCtor_Called(13), // Return from MakeRet -> construct temporary object in HookFunc's stack
new State_ObjODtor_Called(13), // MakeRet: Destruction of x
// back in hookfunc
new State_ObjAssignOp_Called(13), // assign: plugin_ret = temporary object in HookFunc's stack
new State_ObjODtor_Called(13), // destruction of temporary object in HookFunc's stack
// Calling delegate4
new State_Deleg_110(4, pTest110, 3, ParamState_m110 (5)),
new State_ObjOCtor_Called(13), // MakeRet: Construction of x
new State_ObjCCtor_Called(13), // Return from MakeRet -> construct temporary object in HookFunc's stack
new State_ObjODtor_Called(13), // MakeRet: Destruction of x
// back in hookfunc
new State_ObjAssignOp_Called(13), // assign: plugin_ret = temporary object in HookFunc's stack
new State_ObjODtor_Called(13), // destruction of temporary object in HookFunc's stack
// hookfunc finds out that the hook wanted to SUPERCEDE --> copy to override_Ret (yes really, we overwrite the old value!)
new State_ObjAssignOp_Called(13),
// hookfunc is returning:
new State_ObjCCtor_Called(13), // copy to temp object in our stack
// hookfunc cleans up its stack -> destroys plugin_ret/override_ret/orig_ret
new State_ObjODtor_Called(13),
new State_ObjODtor_Called(13),
new State_ObjODtor_Called(13),
// we are in our function: assign
new State_ObjAssignOp_Called(13), // assign: obj13 = temporary object in our stack
new State_ObjODtor_Called(13), // Func110: destruction of temporary object
NULL), "Test" "11" " Part3");
CHECK_COND(obj13 == 4, "Test" "11" " Part 3.1");
g_Inside_LeafFunc = false;
THGM_REMOVE_HOOK(110, 1);
THGM_REMOVE_HOOK(110, 2);
THGM_REMOVE_HOOK(110, 3);
THGM_REMOVE_HOOK(110, 4);
delete obj13_real;
CHECK_STATES((&g_States,
new State_ObjODtor_Called(13),
NULL), "Test110 Part100");
THGM_DO_TEST_void(150, (5, 5.5, 6));
return true;
}
bool Tests5(std::string &error)
{
// RefRet
THGM_DO_TEST(111, ());
// Vafmt
THGM_DO_TEST_void(200, ("Hello %s%d%s", "BA", 1, "L!"));
THGM_DO_TEST_void(201, (100, "Hello %s%d%s", "BA", 1, "L!"));
THGM_DO_TEST_void(203, (0x1F000000, "Hello %s%d%s", "BA", 1, "L!"));
THGM_DO_TEST_void(206, (100, 0x1f00, 0x1f000000, 0.5f, 5.5, "Hello %s%d%s", "BA", 1, "L!"));
char a = 5;
double b = 233.33;
THGM_DO_TEST_void(207, (a, b, "Hello %s%d%s", "BA", 1, "L!"));
POD<7> pod7 = MakeRet< POD<7> >::Do(78);
THGM_DO_TEST_void(208, (pod7, "Hello %s%d%s", "BA", 1, "L!"));
POD<600> pod600 = MakeRet< POD<600> >::Do(34);
THGM_DO_TEST_void(210, (pod600, "Hello %s%d%s", "BA", 1, "L!"));
THGM_DO_TEST(211, (5, "Hello %s%d%s", "BA", 1, "L!"));
THGM_DO_TEST(212, (5, "Hello %s%d%s", "BA", 1, "L!"));
THGM_DO_TEST(213, (5, "Hello %s%d%s", "BA", 1, "L!"));
// Silence Object's ctors/dtors: we only want a forced byref param
g_Silent_CtorDtor = true;
Object<133> *myobj133 = new Object<133>;
THGM_DO_TEST_void(214, (*myobj133, "Hello %s%d%s", "BA", 1, "L!"));
delete myobj133;
g_Silent_CtorDtor = false;
// Test for high vtable indices
Hello *pHello = new Hello;
CAutoPtrDestruction<Hello> apdHello(pHello);
SourceHook::CProtoInfoBuilder helloPi(SourceHook::ProtoInfo::CallConv_ThisCall);
SourceHook::HookManagerPubFunc helloHM_4 = g_HMAGPtr->MakeHookMan(helloPi, 0, 4);
SourceHook::HookManagerPubFunc helloHM_79 = g_HMAGPtr->MakeHookMan(helloPi, 0, 79);
pHello->Func4();
pHello->Func79();
SH_CALL(pHello, &Hello::Func4)();
SH_CALL(pHello, &Hello::Func79)();
CHECK_STATES((&g_States,
new State_Hello_Func4_Called,
new State_Hello_Func79_Called,
new State_Hello_Func4_Called,
new State_Hello_Func79_Called,
NULL), "Test" "Hello" " Part1");
int helloHook4 = g_SHPtr->AddHook(g_PLID, SourceHook::ISourceHook::Hook_Normal, reinterpret_cast<void*>(pHello),
0, helloHM_4, new Hello_Func4_Deleg, false);
int helloHook79 = g_SHPtr->AddHook(g_PLID, SourceHook::ISourceHook::Hook_Normal, reinterpret_cast<void*>(pHello),
0, helloHM_79, new Hello_Func79_Deleg, false);
pHello->Func4();
pHello->Func79();
SH_CALL(pHello, &Hello::Func4)();
SH_CALL(pHello, &Hello::Func79)();
CHECK_STATES((&g_States,
new State_Hello_Func4_PreHook,
new State_Hello_Func4_Called,
new State_Hello_Func79_PreHook,
new State_Hello_Func79_Called,
new State_Hello_Func4_Called,
new State_Hello_Func79_Called,
NULL), "Test" "Hello" " Part2");
g_SHPtr->RemoveHookByID(helloHook4);
g_SHPtr->RemoveHookByID(helloHook79);
g_HMAGPtr->ReleaseHookMan(helloHM_4);
g_HMAGPtr->ReleaseHookMan(helloHM_79);
return true;
}
}
bool TestHookManGen(std::string &error)
{
GET_SHPTR(g_SHPtr);
GET_HMAG(g_HMAGPtr, g_SHPtr);
g_PLID = 1337;
// 5 Global constructors (g_O111_*)
CHECK_STATES((&g_States,
new State_ObjOCtor_Called(111),
new State_ObjOCtor_Called(111),
new State_ObjOCtor_Called(111),
new State_ObjOCtor_Called(111),
new State_ObjOCtor_Called(111),
NULL), "GlobCtors");
if (!Tests1(error))
return false;
if (!Tests2(error))
return false;
if (!Tests3(error))
return false;
if (!Tests4(error))
return false;
if (!Tests5(error))
return false;
// Shutdown now!
// If we don't SH will auto-shutdown _after_ genc's destructor is called
// -> crash
Test_CompleteShutdown(g_SHPtr);
CHECK_COND(sizeof(PodRet1) == 1, "WTF!");
CHECK_COND(sizeof(PodRet4) == 4, "WTF!");
CHECK_COND(sizeof(PodRet8) == 8, "WTF!");
CHECK_COND(sizeof(PodRet13) == 13, "WTF!");
return true;
}
bool TestCPageAlloc(std::string &error)
{
using namespace SourceHook;
CPageAlloc alloc;
int i;
size_t ps = alloc.GetPageSize();
char *test1[8];
for (i = 0; i < 8; ++i)
test1[i] = (char*) alloc.Alloc(ps / 4);
CHECK_COND(test1[1] == test1[0] + ps/4, "Part 1.1");
CHECK_COND(test1[2] == test1[1] + ps/4, "Part 1.2");
CHECK_COND(test1[3] == test1[2] + ps/4, "Part 1.3");
CHECK_COND(test1[5] == test1[4] + ps/4, "Part 1.4");
CHECK_COND(test1[6] == test1[5] + ps/4, "Part 1.5");
CHECK_COND(test1[7] == test1[6] + ps/4, "Part 1.6");
void *test2 = alloc.Alloc(ps * 3);
alloc.SetRW(test2);
memset(test2, 0, ps * 3); // should not crash :)
alloc.SetRE(test2);
alloc.Free(test2);
// Dealloc a ps/4 block and place two ps/8 blocks into it
alloc.Free(test1[2]);
char *test3[2];
test3[0] = (char*) alloc.Alloc(ps / 8);
test3[1] = (char*) alloc.Alloc(ps / 8);
CHECK_COND(test3[0] == test1[2], "Part 2.1");
CHECK_COND(test3[1] == test1[2] + ps/8, "Part 2.2");
// Isolated
char *test4[8];
for (i = 0; i < 8; ++i)
test4[i] = (char*) alloc.AllocIsolated(ps / 4);
// -> The difference is at least one page
CHECK_COND(static_cast<size_t>(abs(test4[1] - test4[0])) >= ps, "Part 3.1");
CHECK_COND(static_cast<size_t>(abs(test4[2] - test4[1])) >= ps, "Part 3.2");
CHECK_COND(static_cast<size_t>(abs(test4[3] - test4[2])) >= ps, "Part 3.3");
CHECK_COND(static_cast<size_t>(abs(test4[5] - test4[4])) >= ps, "Part 3.4");
CHECK_COND(static_cast<size_t>(abs(test4[6] - test4[5])) >= ps, "Part 3.5");
CHECK_COND(static_cast<size_t>(abs(test4[7] - test4[6])) >= ps, "Part 3.6");
// Thus i can set everything except for test4[2] to RE and still write to test4[2]
alloc.SetRW(test4[2]);
alloc.SetRE(test4[0]);
alloc.SetRE(test4[1]);
alloc.SetRE(test4[3]);
alloc.SetRE(test4[4]);
alloc.SetRE(test4[5]);
alloc.SetRE(test4[6]);
alloc.SetRE(test4[7]);
memset((void*)test4[2], 0, ps / 4);
// alignement tests
CPageAlloc alloc1(1);
CPageAlloc alloc4(4);
CPageAlloc alloc16(16);
void *last1 = alloc1.Alloc(1);
void *last4 = alloc4.Alloc(4);
void *last16 = alloc16.Alloc(16);
void *cur;
for (int i = 0; i < 20; ++i)
{
cur = alloc1.Alloc(1);
CHECK_COND(reinterpret_cast<intptr_t>(cur) == reinterpret_cast<intptr_t>(last1) + 1, "Part 4.1");
last1 = cur;
cur = alloc4.Alloc(1);
CHECK_COND(reinterpret_cast<intptr_t>(cur) == reinterpret_cast<intptr_t>(last4) + 4, "Part 4.2");
last4 = cur;
cur = alloc16.Alloc(1);
CHECK_COND(reinterpret_cast<intptr_t>(cur) == reinterpret_cast<intptr_t>(last16) + 16, "Part 4.3");
last16 = cur;
}
alloc16.Free(alloc16.Alloc(1));
return true;
}