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:
parent
ac92e7ff05
commit
f6c428a56d
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
////////////////////////////
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user