amxmodx/dlls/hamsandwich/tableentries/VTableManager.cpp

105 lines
1.8 KiB
C++
Raw Normal View History

#include "sdk/amxxmodule.h"
#include "VTableManager.h"
#include "VTableEntries.h"
#include "NEW_Util.h"
void *VTableManager::InsertIntoVTable(void **vtable, int index, void *trampoline)
{
void *func;
#if defined _WIN32
DWORD OldFlags;
VirtualProtect(&vtable[index],sizeof(int*),PAGE_READWRITE,&OldFlags);
#elif defined __linux__
mprotect(&vtable[index],sizeof(int*),PROT_READ|PROT_WRITE);
#endif
func=vtable[index];
vtable[index]=trampoline;
return func;
};
#define CLEAR_ENTRIES(Container) \
i=Container.size(); \
while (i--) \
{ \
Container[i]->Destroy(); \
delete Container[i]; \
} \
Container.clear()
void VTableManager::Cleanup(void)
{
int i;
CLEAR_ENTRIES(UseEntries);
CLEAR_ENTRIES(TakeDamageEntries);
};
void VTableEntryBase::CreateGenericTrampoline(VTableManager *manager, void **vtable, int vtid, int id, void **outtrampoline, void **origfunc, void *callee, int paramcount, int voidcall, int thiscall)
{
Trampolines::TrampolineMaker tramp;
if (voidcall)
{
if (thiscall)
{
tramp.ThisVoidPrologue();
}
else
{
tramp.VoidPrologue();
}
}
else
{
if (thiscall)
{
tramp.ThisReturnPrologue();
}
else
{
tramp.ReturnPrologue();
}
}
while (paramcount)
{
tramp.PushParam(paramcount--);
}
if (thiscall)
{
tramp.PushThis();
}
tramp.PushNum(id);
tramp.Call(callee);
tramp.FreeTargetStack();
if (voidcall)
{
#if defined _WIN32
tramp.VoidEpilogueAndFree();
#elif defined __linux__
tramp.VoidEpilogue();
#endif
}
else
{
#if defined _WIN32
tramp.ReturnEpilogueAndFree();
#elif defined __linux__
tramp.ReturnEpilogue();
#endif
}
void *trampoline=tramp.Finish(NULL);
*outtrampoline=trampoline;
*origfunc=manager->InsertIntoVTable(vtable,vtid,trampoline);
};