1
0
mirror of https://github.com/alliedmodders/metamod-source.git synced 2024-12-01 13:24:25 +01:00

Added SH_GET_ORIG_VFNPTR_ENTRY macro

--HG--
extra : convert_revision : svn%3Ac2935e3e-5518-0410-8daf-afa5dab7d4e3/trunk%40394
This commit is contained in:
Pavol Marko 2007-05-12 19:48:31 +00:00
parent ac92e7ff05
commit f6c428a56d
6 changed files with 116 additions and 3 deletions

View File

@ -534,6 +534,14 @@ namespace SourceHook
* @param vfnptr The virtual function pointer of the function in question
*/
virtual void ResetIgnoreHooks(Plugin plug, void *vfnptr) = 0;
/**
* @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) = 0;
};
// For META_RESULT_ORIG_RET and META_RESULT_OVERRIDE_RET:
@ -595,6 +603,19 @@ namespace SourceHook
delete p;
}
template <class X, class MFP>
void *GetOrigVfnPtrEntry(X *pInstance, MFP mfp, ISourceHook *pSH)
{
SourceHook::MemFuncInfo info = {true, -1, 0, 0};
SourceHook::GetFuncInfo(pInstance, mfp, info);
void *vfnptr = reinterpret_cast<void*>(
*reinterpret_cast<void***>(reinterpret_cast<char*>(pInstance) + info.thisptroffs + info.vtbloffs) + info.vtblindex);
void *origentry = pSH->GetOrigVfnPtrEntry(vfnptr);
return origentry ? origentry : *reinterpret_cast<void**>(vfnptr);
}
}
/************************************************************************/
@ -707,6 +728,9 @@ namespace SourceHook
SH_MFHCls(hookname)::ms_MFI.vtbloffs = pvtbloffs; \
} while (0)
#define SH_GET_ORIG_VFNPTR_ENTRY(inst, mfp) (SourceHook::GetOrigVfnPtrEntry(inst, mfp, SH_GLOB_SHPTR))
// For source-level compatibility
#define SH_GET_CALLCLASS(ptr) SourceHook::GetCallClass(ptr)

View File

@ -534,6 +534,14 @@ namespace SourceHook
* @param vfnptr The virtual function pointer of the function in question
*/
virtual void ResetIgnoreHooks(Plugin plug, void *vfnptr) = 0;
/**
* @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) = 0;
};
// For META_RESULT_ORIG_RET and META_RESULT_OVERRIDE_RET:
@ -595,6 +603,19 @@ namespace SourceHook
delete p;
}
template <class X, class MFP>
void *GetOrigVfnPtrEntry(X *pInstance, MFP mfp, ISourceHook *pSH)
{
SourceHook::MemFuncInfo info = {true, -1, 0, 0};
SourceHook::GetFuncInfo(pInstance, mfp, info);
void *vfnptr = reinterpret_cast<void*>(
*reinterpret_cast<void***>(reinterpret_cast<char*>(pInstance) + info.thisptroffs + info.vtbloffs) + info.vtblindex);
void *origentry = pSH->GetOrigVfnPtrEntry(vfnptr);
return origentry ? origentry : *reinterpret_cast<void**>(vfnptr);
}
}
/************************************************************************/
@ -707,6 +728,9 @@ namespace SourceHook
SH_MFHCls(hookname)::ms_MFI.vtbloffs = pvtbloffs; \
} while (0)
#define SH_GET_ORIG_VFNPTR_ENTRY(inst, mfp) (SourceHook::GetOrigVfnPtrEntry(inst, mfp, SH_GLOB_SHPTR))
// For source-level compatibility
#define SH_GET_CALLCLASS(ptr) SourceHook::GetCallClass(ptr)

View File

@ -917,6 +917,25 @@ namespace SourceHook
m_OneIgnore = NULL;
}
void *CSourceHookImpl::GetOrigVfnPtrEntry(void *vfnptr)
{
for (HookManContList::iterator hmcl_iter = m_HookMans.begin();
hmcl_iter != m_HookMans.end(); ++hmcl_iter)
{
for (CHookManagerContainer::iterator hookmaniter = hmcl_iter->begin();
hookmaniter != hmcl_iter->end(); ++hookmaniter)
{
for (CHookManagerInfo::VfnPtrListIter vfnptr_iter = hookmaniter->m_VfnPtrs.begin();
vfnptr_iter != hookmaniter->m_VfnPtrs.end(); ++vfnptr_iter)
{
if (vfnptr_iter->m_Ptr == vfnptr)
return vfnptr_iter->m_OrigEntry;
}
}
}
return NULL;
}
////////////////////////////
// CCallClassImpl
////////////////////////////

View File

@ -534,6 +534,14 @@ namespace SourceHook
* @param vfnptr The virtual function pointer of the function in question
*/
virtual void ResetIgnoreHooks(Plugin plug, void *vfnptr) = 0;
/**
* @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) = 0;
};
// For META_RESULT_ORIG_RET and META_RESULT_OVERRIDE_RET:
@ -595,6 +603,19 @@ namespace SourceHook
delete p;
}
template <class X, class MFP>
void *GetOrigVfnPtrEntry(X *pInstance, MFP mfp, ISourceHook *pSH)
{
SourceHook::MemFuncInfo info = {true, -1, 0, 0};
SourceHook::GetFuncInfo(pInstance, mfp, info);
void *vfnptr = reinterpret_cast<void*>(
*reinterpret_cast<void***>(reinterpret_cast<char*>(pInstance) + info.thisptroffs + info.vtbloffs) + info.vtblindex);
void *origentry = pSH->GetOrigVfnPtrEntry(vfnptr);
return origentry ? origentry : *reinterpret_cast<void**>(vfnptr);
}
}
/************************************************************************/
@ -707,6 +728,9 @@ namespace SourceHook
SH_MFHCls(hookname)::ms_MFI.vtbloffs = pvtbloffs; \
} while (0)
#define SH_GET_ORIG_VFNPTR_ENTRY(inst, mfp) (SourceHook::GetOrigVfnPtrEntry(inst, mfp, SH_GLOB_SHPTR))
// For source-level compatibility
#define SH_GET_CALLCLASS(ptr) SourceHook::GetCallClass(ptr)

View File

@ -803,6 +803,14 @@ namespace SourceHook
* @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);
};
}

View File

@ -322,12 +322,26 @@ bool TestVPHooks(std::string &error)
// Test removing normal hooks even though the instance is deleted
p_d1i1 = new CDerived1;
SH_ADD_HOOK(IBase, Func1, p_d1i1, SH_STATIC(Handler_Func1_Pre), false);
delete p_d1i1;
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;
}