diff --git a/sourcehook/generate/sourcehook.hxx b/sourcehook/generate/sourcehook.hxx index b293807..6fe6bd0 100755 --- a/sourcehook/generate/sourcehook.hxx +++ b/sourcehook/generate/sourcehook.hxx @@ -12,6 +12,14 @@ #ifndef __SOURCEHOOK_H__ #define __SOURCEHOOK_H__ +#ifndef SH_GLOB_SHPTR +#define SH_GLOB_SHPTR g_SHPtr +#endif + +#ifndef SH_GLOB_PLUGPTR +#define SH_GLOB_PLUGPTR g_Plug +#endif + #define SH_ASSERT(x) if (!(x)) __asm { int 3 } // System @@ -73,26 +81,24 @@ namespace SourceHook */ typedef void* Plugin; - enum HookerAction + enum HookManagerAction { HA_GetInfo = 0, // -> Only store info HA_Register, // -> Save the pointer for future reference - HA_Unregister, // -> Clear the saved pointer - HA_IfaceAdded, // -> Request call class - HA_IfaceRemoved // -> Release call class + HA_Unregister // -> Clear the saved pointer }; - struct HookerInfo; + struct HookManagerInfo; /** - * @brief Pointer to hooker type + * @brief Pointer to hook manager type * - * A "hooker" is a the only thing that knows the actual protoype of the function at compile time. + * A "hook manager" is a the only thing that knows the actual protoype of the function at compile time. * - * @param hi A pointer to a HookerInfo structure. The hooker should fill it and store it for + * @param hi A pointer to a HookManagerInfo structure. The hook manager should fill it and store it for * future reference (mainly if something should get hooked to its hookfunc) */ - typedef int (*Hooker)(HookerAction ha, HookerInfo *hi); + typedef int (*HookManagerPubFunc)(HookManagerAction ha, HookManagerInfo *hi); class ISHDelegate { @@ -126,9 +132,9 @@ namespace SourceHook }; /** - * @brief This structure contains information about a hooker (hook manager) + * @brief This structure contains information about a hook manager (hook manager) */ - struct HookerInfo + struct HookManagerInfo { struct Iface { @@ -148,11 +154,11 @@ namespace SourceHook } }; Plugin plug; //!< The owner plugin - const char *proto; //!< The prototype of the function the hooker is responsible for + const char *proto; //!< The prototype of the function the hook manager is responsible for int vtbl_idx; //!< The vtable index int vtbl_offs; //!< The vtable offset int thisptr_offs; //!< The this-pointer-adjuster - Hooker func; //!< The interface to the hooker + HookManagerPubFunc func; //!< The interface to the hook manager int hookfunc_vtbl_idx; //!< the vtable index of the hookfunc int hookfunc_vtbl_offs; //!< the vtable offset of the hookfunc @@ -203,11 +209,11 @@ namespace SourceHook * @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 myHooker A hooker function that should be capable of handling the function + * @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 bool AddHook(Plugin plug, void *iface, int ifacesize, Hooker myHooker, ISHDelegate *handler, bool post) = 0; + virtual bool AddHook(Plugin plug, void *iface, int ifacesize, HookManagerPubFunc myHookMan, ISHDelegate *handler, bool post) = 0; /** * @brief Removes a hook. @@ -216,14 +222,14 @@ namespace SourceHook * * @param plug The unique identifier of the plugin that calls this function * @param iface The interface pointer - * @param myHooker A hooker function that should be capable of handling the function + * @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 bool RemoveHook(Plugin plug, void *iface, Hooker myHooker, ISHDelegate *handler, bool post) = 0; + virtual bool RemoveHook(Plugin plug, void *iface, HookManagerPubFunc myHookMan, ISHDelegate *handler, bool post) = 0; /** - * @brief Checks whether a plugin has (a) hooker(s) that is/are currently used by other plugins + * @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 */ @@ -251,7 +257,7 @@ namespace SourceHook virtual const void *GetOverrideRet() = 0; //!< Gets the override result. If none is specified, NULL virtual void *GetIfacePtr() = 0; //!< Gets the interface pointer ////////////////////////////////////////////////////////////////////////// - // For hookers + // For hook managers virtual META_RES &GetCurResRef() = 0; //!< Gets the pointer to the current meta result virtual META_RES &GetPrevResRef() = 0; //!< Gets the pointer to the previous meta result virtual META_RES &GetStatusRef() = 0; //!< Gets the pointer to the status variable @@ -263,15 +269,15 @@ namespace SourceHook ////////////////////////////////////////////////////////////////////////// // Macro interface -#define SET_META_RESULT(result) g_SHPtr->SetRes(result) -#define RETURN_META(result) do { g_SHPtr->SetRes(result); return; } while(0) -#define RETURN_META_VALUE(result, value) do { g_SHPtr->SetRes(result); return (value); } while(0) +#define SET_META_RESULT(result) SH_GLOB_SHPTR->SetRes(result) +#define RETURN_META(result) do { SH_GLOB_SHPTR->SetRes(result); return; } while(0) +#define RETURN_META_VALUE(result, value) do { SH_GLOB_SHPTR->SetRes(result); return (value); } while(0) -#define META_RESULT_STATUS g_SHPtr->GetStatus() -#define META_RESULT_PREVIOUS g_SHPtr->GetPrevRes() -#define META_RESULT_ORIG_RET(type) *(const type *)g_SHPtr->GetOrigRet() -#define META_RESULT_OVERRIDE_RET(type) *(const type *)g_SHPtr->GetOverrideRet() -#define META_IFACEPTR g_SHPtr->GetIfacePtr() +#define META_RESULT_STATUS SH_GLOB_SHPTR->GetStatus() +#define META_RESULT_PREVIOUS SH_GLOB_SHPTR->GetPrevRes() +#define META_RESULT_ORIG_RET(type) *(const type *)SH_GLOB_SHPTR->GetOrigRet() +#define META_RESULT_OVERRIDE_RET(type) *(const type *)SH_GLOB_SHPTR->GetOverrideRet() +#define META_IFACEPTR SH_GLOB_SHPTR->GetIfacePtr() /** @@ -280,8 +286,8 @@ namespace SourceHook * @param ifacetype The type of the interface * @param ifaceptr The interface pointer */ -#define SH_GET_CALLCLASS(ifacetype, ifaceptr) reinterpret_cast(g_SHPtr->GetCallClass(ifaceptr, sizeof(ifacetype))) -#define SH_RELEASE_CALLCLASS(ptr) g_SHPtr->ReleaseCallClass(reinterpret_cast(ptr)) +#define SH_GET_CALLCLASS(ifacetype, ifaceptr) reinterpret_cast(SH_GLOB_SHPTR->GetCallClass(ifaceptr, sizeof(ifacetype))) +#define SH_RELEASE_CALLCLASS(ptr) SH_GLOB_SHPTR->ReleaseCallClass(reinterpret_cast(ptr)) #define SH_ADD_HOOK(ifacetype, ifacefunc, ifaceptr, handler, post) \ SourceHook::SH_FHAdd##ifacetype##ifacefunc((void*)ifaceptr, post, handler) @@ -303,8 +309,8 @@ namespace SourceHook ////////////////////////////////////////////////////////////////////////// #define SH_FHCls(ift, iff, ov) FHCls_##ift##iff##ov -#define SHINT_MAKE_HOOKERPUBFUNC(ifacetype, ifacefunc, overload, funcptr) \ - static int Hooker(HookerAction action, HookerInfo *param) \ +#define SHINT_MAKE_HOOKMANPUBFUNC(ifacetype, ifacefunc, overload, funcptr) \ + static int HookManPubFunc(HookManagerAction action, HookManagerInfo *param) \ { \ if (action == HA_GetInfo) \ { \ @@ -314,7 +320,7 @@ namespace SourceHook param->vtbl_idx = mfi.vtblindex; \ param->vtbl_offs = mfi.vtbloffs; \ param->thisptr_offs = mfi.thisptroffs; \ - if (param->thisptr_offs) \ + if (param->thisptr_offs < 0) \ return 2; /*No virtual inheritance supported*/ \ GetFuncInfo(&SH_FHCls(ifacetype,ifacefunc,overload)::Func, mfi); \ param->hookfunc_vtbl_idx = mfi.vtblindex; \ @@ -342,28 +348,28 @@ namespace SourceHook struct SH_FHCls(ifacetype,ifacefunc,overload) \ { \ static SH_FHCls(ifacetype,ifacefunc,overload) ms_Inst; \ - static HookerInfo *ms_HI; \ + static HookManagerInfo *ms_HI; \ static const char *ms_Proto; \ - SHINT_MAKE_HOOKERPUBFUNC(ifacetype, ifacefunc, overload, funcptr) + SHINT_MAKE_HOOKMANPUBFUNC(ifacetype, ifacefunc, overload, funcptr) #define SHINT_MAKE_GENERICSTUFF_END(ifacetype, ifacefunc, overload, proto) \ }; \ const char *SH_FHCls(ifacetype,ifacefunc,overload)::ms_Proto = proto; \ SH_FHCls(ifacetype,ifacefunc,overload) SH_FHCls(ifacetype,ifacefunc,overload)::ms_Inst; \ - HookerInfo *SH_FHCls(ifacetype,ifacefunc,overload)::ms_HI; \ + HookManagerInfo *SH_FHCls(ifacetype,ifacefunc,overload)::ms_HI; \ bool SH_FHAdd##ifacetype##ifacefunc(void *iface, bool post, \ SH_FHCls(ifacetype,ifacefunc,overload)::FD handler) \ { \ - return g_SHPtr->AddHook(g_Plug, iface, sizeof(ifacetype), \ - SH_FHCls(ifacetype,ifacefunc,overload)::Hooker, \ + return SH_GLOB_SHPTR->AddHook(SH_GLOB_PLUGPTR, iface, sizeof(ifacetype), \ + SH_FHCls(ifacetype,ifacefunc,overload)::HookManPubFunc, \ new CSHDelegate(handler), post); \ } \ bool SH_FHRemove##ifacetype##ifacefunc(void *iface, bool post, \ SH_FHCls(ifacetype,ifacefunc,overload)::FD handler) \ { \ CSHDelegate tmp(handler); \ - return g_SHPtr->RemoveHook(g_Plug, iface, \ - SH_FHCls(ifacetype,ifacefunc,overload)::Hooker, &tmp, post); \ + return SH_GLOB_SHPTR->RemoveHook(SH_GLOB_PLUGPTR, iface, \ + SH_FHCls(ifacetype,ifacefunc,overload)::HookManPubFunc, &tmp, post); \ } \ } @@ -371,25 +377,25 @@ namespace SourceHook /* 1) Find the iface ptr */ \ /* 1.1) Adjust to original this pointer */ \ void *origthis = this - ms_HI->thisptr_offs; \ - std::list::iterator ifaceiter = std::find(ms_HI->ifaces.begin(), \ + std::list::iterator ifaceiter = std::find(ms_HI->ifaces.begin(), \ ms_HI->ifaces.end(), origthis); \ SH_ASSERT(ifaceiter != ms_HI->ifaces.end()); \ - HookerInfo::Iface &ci = *ifaceiter; \ + HookManagerInfo::Iface &ci = *ifaceiter; \ /* 2) Declare some vars and set it up */ \ - std::list &prelist = ci.hooks_pre; \ - std::list &postlist = ci.hooks_post; \ + std::list &prelist = ci.hooks_pre; \ + std::list &postlist = ci.hooks_post; \ rettype orig_ret, override_ret, plugin_ret; \ - META_RES &cur_res = g_SHPtr->GetCurResRef(); \ - META_RES &prev_res = g_SHPtr->GetPrevResRef(); \ - META_RES &status = g_SHPtr->GetStatusRef(); \ + META_RES &cur_res = SH_GLOB_SHPTR->GetCurResRef(); \ + META_RES &prev_res = SH_GLOB_SHPTR->GetPrevResRef(); \ + META_RES &status = SH_GLOB_SHPTR->GetStatusRef(); \ status = MRES_IGNORED; \ - g_SHPtr->SetIfacePtr(ci.ptr); \ - g_SHPtr->SetOrigRet(reinterpret_cast(&orig_ret)); \ - g_SHPtr->SetOverrideRet(NULL); + SH_GLOB_SHPTR->SetIfacePtr(ci.ptr); \ + SH_GLOB_SHPTR->SetOrigRet(reinterpret_cast(&orig_ret)); \ + SH_GLOB_SHPTR->SetOverrideRet(NULL); #define SH_CALL_HOOKS(post, params) \ prev_res = MRES_IGNORED; \ - for (std::list::iterator hiter = post##list.begin(); hiter != post##list.end(); ++hiter) \ + for (std::list::iterator hiter = post##list.begin(); hiter != post##list.end(); ++hiter) \ { \ cur_res = MRES_IGNORED; \ plugin_ret = reinterpret_cast*>(hiter->handler)->GetDeleg() params; \ @@ -399,7 +405,7 @@ namespace SourceHook if (cur_res >= MRES_OVERRIDE) \ { \ override_ret = plugin_ret; \ - g_SHPtr->SetOverrideRet(&override_ret); \ + SH_GLOB_SHPTR->SetOverrideRet(&override_ret); \ } \ } @@ -424,23 +430,23 @@ namespace SourceHook /* 1) Find the iface ptr */ \ /* 1.1) Adjust to original this pointer */ \ void *origthis = this - ms_HI->thisptr_offs; \ - std::list::iterator ifaceiter = std::find(ms_HI->ifaces.begin(), \ + std::list::iterator ifaceiter = std::find(ms_HI->ifaces.begin(), \ ms_HI->ifaces.end(), origthis); \ SH_ASSERT(ifaceiter != ms_HI->ifaces.end()); \ - HookerInfo::Iface &ci = *ifaceiter; \ + HookManagerInfo::Iface &ci = *ifaceiter; \ /* 2) Declare some vars and set it up */ \ - std::list &prelist = ci.hooks_pre; \ - std::list &postlist = ci.hooks_post; \ - META_RES &cur_res = g_SHPtr->GetCurResRef(); \ - META_RES &prev_res = g_SHPtr->GetPrevResRef(); \ - META_RES &status = g_SHPtr->GetStatusRef(); \ + std::list &prelist = ci.hooks_pre; \ + std::list &postlist = ci.hooks_post; \ + META_RES &cur_res = SH_GLOB_SHPTR->GetCurResRef(); \ + META_RES &prev_res = SH_GLOB_SHPTR->GetPrevResRef(); \ + META_RES &status = SH_GLOB_SHPTR->GetStatusRef(); \ status = MRES_IGNORED; \ - g_SHPtr->SetIfacePtr(ci.ptr); \ - g_SHPtr->SetOverrideRet(NULL); + SH_GLOB_SHPTR->SetIfacePtr(ci.ptr); \ + SH_GLOB_SHPTR->SetOverrideRet(NULL); #define SH_CALL_HOOKS_void(post, params) \ prev_res = MRES_IGNORED; \ - for (std::list::iterator hiter = post##list.begin(); hiter != post##list.end(); ++hiter) \ + for (std::list::iterator hiter = post##list.begin(); hiter != post##list.end(); ++hiter) \ { \ cur_res = MRES_IGNORED; \ reinterpret_cast*>(hiter->handler)->GetDeleg() params; \ diff --git a/sourcehook/sourcehook.cpp b/sourcehook/sourcehook.cpp index e655444..8964b6e 100644 --- a/sourcehook/sourcehook.cpp +++ b/sourcehook/sourcehook.cpp @@ -83,18 +83,18 @@ namespace SourceHook bool CSourceHookImpl::IsPluginInUse(Plugin plug) { - // Iterate through all hookers which are in this plugin + // Iterate through all hook managers which are in this plugin // Iterate through their hooks // If a hook from an other plugin is found, return true // Return false otherwise - for (HookerInfoList::iterator iter = m_Hookers.begin(); iter != m_Hookers.end(); ++iter) + for (HookManInfoList::iterator iter = m_HookMans.begin(); iter != m_HookMans.end(); ++iter) { if (iter->plug == plug && !iter->ifaces.empty()) { - for (std::list::iterator iter2 = iter->ifaces.begin(); iter2 != iter->ifaces.end(); ++iter2) + for (std::list::iterator iter2 = iter->ifaces.begin(); iter2 != iter->ifaces.end(); ++iter2) { - std::list::iterator iter3; + std::list::iterator iter3; for (iter3 = iter2->hooks_pre.begin(); iter3 != iter2->hooks_pre.end(); ++iter3) if (iter3->plug == plug) return true; @@ -109,41 +109,43 @@ namespace SourceHook void CSourceHookImpl::UnloadPlugin(Plugin plug) { - // Get a list of hookers that are in this plugin and are used by other plugins + // 1) Manually remove all hooks by this plugin + std::list hookstoremove; - HookerInfoList tmphookers; - bool erase = false; - for (HookerInfoList::iterator iter = m_Hookers.begin(); iter != m_Hookers.end(); - erase ? iter=m_Hookers.erase(iter) : ++iter) + for (HookManInfoList::iterator iter = m_HookMans.begin(); iter != m_HookMans.end(); ++iter) { - if (iter->plug == plug && !iter->ifaces.empty()) + for (std::list::iterator iter2 = iter->ifaces.begin(); iter2 != iter->ifaces.end(); + ++iter2) { - bool found = false; - for (std::list::iterator iter2 = iter->ifaces.begin(); - iter2 != iter->ifaces.end(); ++iter2) + for (std::list::iterator iter3 = iter2->hooks_pre.begin(); iter3 != iter2->hooks_pre.end(); ++iter3) + if (iter3->plug == plug) + hookstoremove.push_back(RemoveHookInfo(iter3->plug, iter2->ptr, iter->func, iter3->handler, false)); + + for (std::list::iterator iter3 = iter2->hooks_post.begin(); iter3 != iter2->hooks_post.end(); ++iter3) + if (iter3->plug == plug) + hookstoremove.push_back(RemoveHookInfo(iter3->plug, iter2->ptr, iter->func, iter3->handler, true)); + } + } + + for (std::list::iterator rmiter = hookstoremove.begin(); rmiter != hookstoremove.end(); ++rmiter) + RemoveHook(rmiter->plug, rmiter->iface, rmiter->hpf, rmiter->handler, rmiter->post); + + // 2) Other plugins may use hook managers in this plugin. + // Get a list of hook managers that are in this plugin and are used by other plugins + // Delete all hook managers that are in this plugin + + HookManInfoList tmphookmans; + bool erase = false; + for (HookManInfoList::iterator iter = m_HookMans.begin(); iter != m_HookMans.end(); + erase ? iter=m_HookMans.erase(iter) : ++iter) + { + if (iter->plug == plug) + { + if (!iter->ifaces.empty()) { - for (std::list::iterator iter3 = iter2->hooks_pre.begin(); - iter3 != iter2->hooks_pre.end(); ++iter3) - { - if (iter3->plug != plug) - { - found = true; - break; - } - } - for (iter3 = iter2->hooks_post.begin(); iter3 != iter2->hooks_post.end(); ++iter3) - { - if (iter3->plug != plug) - { - found = true; - break; - } - } - if (found) - { - tmphookers.push_back(*iter); - break; - } + // All hooks by this plugin are already removed + // So if there is an iface, it has to be used by an other plugin + tmphookmans.push_back(*iter); } erase = true; } @@ -151,120 +153,106 @@ namespace SourceHook erase = false; } - // For each hooker: - for (HookerInfoList::iterator iter = tmphookers.begin(); iter != tmphookers.end(); ++iter) + // For each hook manager: + for (HookManInfoList::iterator iter = tmphookmans.begin(); iter != tmphookmans.end(); ++iter) { - // Shutdown all ifaces and remove the hooks from this plugin from their lists - for (std::list::iterator iter2 = iter->ifaces.begin(); iter2 != iter->ifaces.end(); - erase ? iter2 = iter->ifaces.erase(iter2) : ++iter2) - { - *(reinterpret_cast(reinterpret_cast(iter2->ptr) + iter->vtbl_offs) - + iter->vtbl_idx) = iter2->orig_entry; - - for (std::list::iterator iter3 = iter2->hooks_pre.begin(); iter3 != iter2->hooks_pre.end(); - iter3->plug == plug ? iter3=iter2->hooks_pre.erase(iter3) : ++iter3) {} - for (std::list::iterator iter3 = iter2->hooks_post.begin(); iter3 != iter2->hooks_post.end(); - iter3->plug == plug ? iter3=iter2->hooks_post.erase(iter3) : ++iter3) {} - - erase = iter2->hooks_pre.empty() && iter2->hooks_post.empty(); - } - - if (iter->ifaces.empty()) - { - // Nothing more to do; no more ifaces to re-register - continue; - } - - // 2) Find a suitable hooker in an other plugin - HookerInfoList::iterator newHooker = FindHooker(m_Hookers.begin(), m_Hookers.end(), + // Find a suitable hook manager in an other plugin + HookManInfoList::iterator newHookMan = FindHookMan(m_HookMans.begin(), m_HookMans.end(), iter->proto, iter->vtbl_offs, iter->vtbl_idx, iter->thisptr_offs); - if (newHooker == m_Hookers.end()) + if (newHookMan == m_HookMans.end()) { // This should _never_ happen. - // If there is a hook from an other plugin, the plugin must have provided a hooker as well. + // If there is a hook from an other plugin, the plugin must have provided a hook manager as well. SH_ASSERT(0); } - // AddHook should make sure that every plugin only has _one_ hooker for _one_ proto/vi/vo - SH_ASSERT(newHooker->plug != plug); + // AddHook should make sure that every plugin only has _one_ hook manager for _one_ proto/vi/vo/thisptroffs + SH_ASSERT(newHookMan->plug != plug); - // 3) Register it! - newHooker->func(HA_Register, &(*iter)); - for (std::list::iterator iter2 = iter->ifaces.begin(); iter2 != iter->ifaces.end(); - ++iter2) - { - reinterpret_cast(reinterpret_cast(iter2->ptr) + iter->vtbl_offs)[iter->vtbl_idx] = - reinterpret_cast(reinterpret_cast(iter->hookfunc_inst) + iter->hookfunc_vtbl_offs)[iter->hookfunc_vtbl_idx]; - } + // The first hooker should be always used - so the new hook manager has to be empty + SH_ASSERT(newHookMan->ifaces.empty()); + + // Move the ifaces from the old hook manager to the new one + newHookMan->ifaces = iter->ifaces; + + // Unregister the old one, register the new one + iter->func(HA_Unregister, NULL); + newHookMan->func(HA_Register, &(*newHookMan)); } } void CSourceHookImpl::CompleteShutdown() { - // Go through all hookers and shut down all interfaces - for (HookerInfoList::iterator iter = m_Hookers.begin(); iter != m_Hookers.end(); ++iter) + std::list hookstoremove; + + for (HookManInfoList::iterator iter = m_HookMans.begin(); iter != m_HookMans.end(); ++iter) { - for (std::list::iterator iter2 = iter->ifaces.begin(); iter2 != iter->ifaces.end(); ++iter2) + for (std::list::iterator iter2 = iter->ifaces.begin(); iter2 != iter->ifaces.end(); + ++iter2) { - // Note that we can pass iter->func as "myHooker" because it is only used - // to retreive data - for (std::list::iterator iter3 = iter2->hooks_pre.begin(); iter3 != iter2->hooks_pre.end(); ++iter3) - RemoveHook(iter3->plug, iter2->ptr, iter->func, iter3->handler, false); - for (std::list::iterator iter3 = iter2->hooks_post.begin(); iter3 != iter2->hooks_post.end(); ++iter3) - RemoveHook(iter3->plug, iter2->ptr, iter->func, iter3->handler, true); + for (std::list::iterator iter3 = iter2->hooks_pre.begin(); iter3 != iter2->hooks_pre.end(); ++iter3) + hookstoremove.push_back(RemoveHookInfo(iter3->plug, iter2->ptr, iter->func, iter3->handler, false)); + + for (std::list::iterator iter3 = iter2->hooks_post.begin(); iter3 != iter2->hooks_post.end(); ++iter3) + hookstoremove.push_back(RemoveHookInfo(iter3->plug, iter2->ptr, iter->func, iter3->handler, true)); } } + + for (std::list::iterator rmiter = hookstoremove.begin(); rmiter != hookstoremove.end(); ++rmiter) + RemoveHook(rmiter->plug, rmiter->iface, rmiter->hpf, rmiter->handler, rmiter->post); + + m_HookMans.clear(); } - bool CSourceHookImpl::AddHook(Plugin plug, void *iface, int ifacesize, Hooker myHooker, ISHDelegate *handler, bool post) + bool CSourceHookImpl::AddHook(Plugin plug, void *iface, int ifacesize, HookManagerPubFunc myHookMan, ISHDelegate *handler, bool post) { - // 1) Get info about the hooker - HookerInfo tmp; - if (myHooker(HA_GetInfo, &tmp) != 0) + // 1) Get info about the hook manager + HookManagerInfo tmp; + if (myHookMan(HA_GetInfo, &tmp) != 0) return false; - // Add the proposed hooker to the _end_ of the list if the plugin doesn't have a hooker with this proto/vo/vi registered - HookerInfoList::iterator hookeriter; - for (hookeriter = m_Hookers.begin(); hookeriter != m_Hookers.end(); ++hookeriter) + // Add the proposed hook manager to the _end_ of the list if the plugin doesn't have a hook manager with this proto/vo/vi registered + HookManInfoList::iterator hookmaniter; + for (hookmaniter = m_HookMans.begin(); hookmaniter != m_HookMans.end(); ++hookmaniter) { - if (hookeriter->plug == plug && strcmp(hookeriter->proto, tmp.proto) == 0 && - hookeriter->vtbl_offs == tmp.vtbl_offs && hookeriter->vtbl_idx == tmp.vtbl_idx && - hookeriter->thisptr_offs == tmp.thisptr_offs) + if (hookmaniter->plug == plug && strcmp(hookmaniter->proto, tmp.proto) == 0 && + hookmaniter->vtbl_offs == tmp.vtbl_offs && hookmaniter->vtbl_idx == tmp.vtbl_idx && + hookmaniter->thisptr_offs == tmp.thisptr_offs) break; } - if (hookeriter == m_Hookers.end()) + if (hookmaniter == m_HookMans.end()) { - // No such hooker from this plugin yet, add it! - tmp.func = myHooker; + // No such hook manager from this plugin yet, add it! + tmp.func = myHookMan; tmp.plug = plug; - m_Hookers.push_back(tmp); + m_HookMans.push_back(tmp); } - // Then, search for a suitable hooker (from the beginning) - HookerInfoList::iterator hooker = FindHooker(m_Hookers.begin(), m_Hookers.end(), tmp.proto, tmp.vtbl_offs, tmp.vtbl_idx, tmp.thisptr_offs); - SH_ASSERT(hooker != m_Hookers.end()); + // Then, search for a suitable hook manager (from the beginning) + HookManInfoList::iterator hookman = FindHookMan(m_HookMans.begin(), m_HookMans.end(), tmp.proto, tmp.vtbl_offs, tmp.vtbl_idx, tmp.thisptr_offs); + SH_ASSERT(hookman != m_HookMans.end()); // Tell it to store the pointer if it's not already active - if (hooker->ifaces.empty()) - hooker->func(HA_Register, &(*hooker)); + if (hookman->ifaces.empty()) + hookman->func(HA_Register, &(*hookman)); - std::list::iterator ifsiter = std::find(hooker->ifaces.begin(), hooker->ifaces.end(), iface); + std::list::iterator ifsiter = std::find(hookman->ifaces.begin(), hookman->ifaces.end(), iface); - if (ifsiter == hooker->ifaces.end()) + if (ifsiter == hookman->ifaces.end()) { - HookerInfo::Iface ifs; + HookManagerInfo::Iface ifs; ifs.ptr = iface; ifs.callclass = GetCallClass(iface, ifacesize); - void *vtableptr = *reinterpret_cast(reinterpret_cast(iface) + hooker->vtbl_offs); - SetMemAccess(vtableptr, sizeof(void*) * hooker->vtbl_idx, SH_MEM_READ | SH_MEM_WRITE); - ifs.orig_entry = (*reinterpret_cast(reinterpret_cast(iface) + hooker->vtbl_offs))[hooker->vtbl_idx]; - (*reinterpret_cast(reinterpret_cast(iface) + hooker->vtbl_offs))[hooker->vtbl_idx] = - (*reinterpret_cast(reinterpret_cast(hooker->hookfunc_inst) + hooker->hookfunc_vtbl_offs))[hooker->hookfunc_vtbl_idx]; - hooker->ifaces.push_back(ifs); - ifsiter = hooker->ifaces.end(); + void *vtableptr = *reinterpret_cast(reinterpret_cast(iface) + hookman->vtbl_offs); + SetMemAccess(vtableptr, sizeof(void*) * hookman->vtbl_idx, SH_MEM_READ | SH_MEM_WRITE); + ifs.orig_entry = (*reinterpret_cast(reinterpret_cast(iface) + hookman->vtbl_offs))[hookman->vtbl_idx]; + (*reinterpret_cast(reinterpret_cast(iface) + hookman->vtbl_offs))[hookman->vtbl_idx] = + (*reinterpret_cast(reinterpret_cast(hookman->hookfunc_inst) + hookman->hookfunc_vtbl_offs))[hookman->hookfunc_vtbl_idx]; + hookman->ifaces.push_back(ifs); + ifsiter = hookman->ifaces.end(); --ifsiter; } - HookerInfo::Iface::Hook hookinfo; + HookManagerInfo::Iface::Hook hookinfo; hookinfo.handler = handler; hookinfo.plug = plug; if (post) @@ -288,25 +276,25 @@ namespace SourceHook return true; } - bool CSourceHookImpl::RemoveHook(Plugin plug, void *iface, Hooker myHooker, ISHDelegate *handler, bool post) + bool CSourceHookImpl::RemoveHook(Plugin plug, void *iface, HookManagerPubFunc myHookMan, ISHDelegate *handler, bool post) { - HookerInfo tmp; - if (myHooker(HA_GetInfo, &tmp) != 0) + HookManagerInfo tmp; + if (myHookMan(HA_GetInfo, &tmp) != 0) return false; - // Find the hooker and the hook - HookerInfoList::iterator hooker = FindHooker(m_Hookers.begin(), m_Hookers.end(), + // Find the hook manager and the hook + HookManInfoList::iterator hookman = FindHookMan(m_HookMans.begin(), m_HookMans.end(), tmp.proto, tmp.vtbl_offs, tmp.vtbl_idx, tmp.thisptr_offs); - if (hooker == m_Hookers.end()) + if (hookman == m_HookMans.end()) return false; - for (std::list::iterator ifaceiter = hooker->ifaces.begin(); ifaceiter != hooker->ifaces.end(); ++ifaceiter) + for (std::list::iterator ifaceiter = hookman->ifaces.begin(); ifaceiter != hookman->ifaces.end(); ++ifaceiter) { if (ifaceiter->ptr == iface) { - std::list &hooks = post ? ifaceiter->hooks_post : ifaceiter->hooks_pre; + std::list &hooks = post ? ifaceiter->hooks_post : ifaceiter->hooks_pre; bool erase; - for (std::list::iterator hookiter = hooks.begin(); + for (std::list::iterator hookiter = hooks.begin(); hookiter != hooks.end(); erase ? hookiter = hooks.erase(hookiter) : ++hookiter) { erase = hookiter->plug == plug && hookiter->handler->IsEqual(handler); @@ -317,16 +305,16 @@ namespace SourceHook { // Deactivate the hook (*reinterpret_cast(reinterpret_cast(ifaceiter->ptr) + - hooker->vtbl_offs))[hooker->vtbl_idx]= ifaceiter->orig_entry; + hookman->vtbl_offs))[hookman->vtbl_idx]= ifaceiter->orig_entry; // Release the callclass ReleaseCallClass(ifaceiter->callclass); // Remove the iface info - hooker->ifaces.erase(ifaceiter); + hookman->ifaces.erase(ifaceiter); - if (hooker->ifaces.empty()) - hooker->func(HA_Unregister, NULL); + if (hookman->ifaces.empty()) + hookman->func(HA_Unregister, NULL); } // :TODO: Better return value? Or none? return true; @@ -361,13 +349,13 @@ namespace SourceHook tmp.refcounter = 1; // Go through _all_ hooks and apply any needed patches - for (HookerInfoList::iterator hooker = m_Hookers.begin(); hooker != m_Hookers.end(); ++hooker) + for (HookManInfoList::iterator hookman = m_HookMans.begin(); hookman != m_HookMans.end(); ++hookman) { - for (std::list::iterator ifaceiter = hooker->ifaces.begin(); ifaceiter != hooker->ifaces.end(); ++ifaceiter) + for (std::list::iterator ifaceiter = hookman->ifaces.begin(); ifaceiter != hookman->ifaces.end(); ++ifaceiter) { if (ifaceiter->ptr == iface) { - if (!ApplyCallClassPatch(tmp, hooker->vtbl_offs, hooker->vtbl_idx, ifaceiter->orig_entry)) + if (!ApplyCallClassPatch(tmp, hookman->vtbl_offs, hookman->vtbl_idx, ifaceiter->orig_entry)) { FreeCallClass(tmp); return NULL; @@ -479,16 +467,16 @@ namespace SourceHook } - CSourceHookImpl::HookerInfoList::iterator CSourceHookImpl::FindHooker(HookerInfoList::iterator begin, - HookerInfoList::iterator end, const char *proto, int vtblofs, int vtblidx, int thisptrofs) + CSourceHookImpl::HookManInfoList::iterator CSourceHookImpl::FindHookMan(HookManInfoList::iterator begin, + HookManInfoList::iterator end, const char *proto, int vtblofs, int vtblidx, int thisptrofs) { - for (HookerInfoList::iterator hookeriter = m_Hookers.begin(); hookeriter != m_Hookers.end(); ++hookeriter) + for (HookManInfoList::iterator hookmaniter = m_HookMans.begin(); hookmaniter != m_HookMans.end(); ++hookmaniter) { - if (strcmp(hookeriter->proto, proto) == 0 && hookeriter->vtbl_offs == vtblofs && hookeriter->vtbl_idx == vtblidx && - hookeriter->thisptr_offs == thisptrofs) + if (strcmp(hookmaniter->proto, proto) == 0 && hookmaniter->vtbl_offs == vtblofs && hookmaniter->vtbl_idx == vtblidx && + hookmaniter->thisptr_offs == thisptrofs) break; } - return hookeriter; + return hookmaniter; } diff --git a/sourcehook/sourcehook.h b/sourcehook/sourcehook.h index b617bf7..78f8dac 100644 --- a/sourcehook/sourcehook.h +++ b/sourcehook/sourcehook.h @@ -12,6 +12,14 @@ #ifndef __SOURCEHOOK_H__ #define __SOURCEHOOK_H__ +#ifndef SH_GLOB_SHPTR +#define SH_GLOB_SHPTR g_SHPtr +#endif + +#ifndef SH_GLOB_PLUGPTR +#define SH_GLOB_PLUGPTR g_Plug +#endif + #define SH_ASSERT(x) if (!(x)) __asm { int 3 } // System @@ -73,26 +81,24 @@ namespace SourceHook */ typedef void* Plugin; - enum HookerAction + enum HookManagerAction { HA_GetInfo = 0, // -> Only store info HA_Register, // -> Save the pointer for future reference - HA_Unregister, // -> Clear the saved pointer - HA_IfaceAdded, // -> Request call class - HA_IfaceRemoved // -> Release call class + HA_Unregister // -> Clear the saved pointer }; - struct HookerInfo; + struct HookManagerInfo; /** - * @brief Pointer to hooker type + * @brief Pointer to hook manager type * - * A "hooker" is a the only thing that knows the actual protoype of the function at compile time. + * A "hook manager" is a the only thing that knows the actual protoype of the function at compile time. * - * @param hi A pointer to a HookerInfo structure. The hooker should fill it and store it for + * @param hi A pointer to a HookManagerInfo structure. The hook manager should fill it and store it for * future reference (mainly if something should get hooked to its hookfunc) */ - typedef int (*Hooker)(HookerAction ha, HookerInfo *hi); + typedef int (*HookManagerPubFunc)(HookManagerAction ha, HookManagerInfo *hi); class ISHDelegate { @@ -126,9 +132,9 @@ namespace SourceHook }; /** - * @brief This structure contains information about a hooker (hook manager) + * @brief This structure contains information about a hook manager (hook manager) */ - struct HookerInfo + struct HookManagerInfo { struct Iface { @@ -148,11 +154,11 @@ namespace SourceHook } }; Plugin plug; //!< The owner plugin - const char *proto; //!< The prototype of the function the hooker is responsible for + const char *proto; //!< The prototype of the function the hook manager is responsible for int vtbl_idx; //!< The vtable index int vtbl_offs; //!< The vtable offset int thisptr_offs; //!< The this-pointer-adjuster - Hooker func; //!< The interface to the hooker + HookManagerPubFunc func; //!< The interface to the hook manager int hookfunc_vtbl_idx; //!< the vtable index of the hookfunc int hookfunc_vtbl_offs; //!< the vtable offset of the hookfunc @@ -203,11 +209,11 @@ namespace SourceHook * @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 myHooker A hooker function that should be capable of handling the function + * @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 bool AddHook(Plugin plug, void *iface, int ifacesize, Hooker myHooker, ISHDelegate *handler, bool post) = 0; + virtual bool AddHook(Plugin plug, void *iface, int ifacesize, HookManagerPubFunc myHookMan, ISHDelegate *handler, bool post) = 0; /** * @brief Removes a hook. @@ -216,14 +222,14 @@ namespace SourceHook * * @param plug The unique identifier of the plugin that calls this function * @param iface The interface pointer - * @param myHooker A hooker function that should be capable of handling the function + * @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 bool RemoveHook(Plugin plug, void *iface, Hooker myHooker, ISHDelegate *handler, bool post) = 0; + virtual bool RemoveHook(Plugin plug, void *iface, HookManagerPubFunc myHookMan, ISHDelegate *handler, bool post) = 0; /** - * @brief Checks whether a plugin has (a) hooker(s) that is/are currently used by other plugins + * @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 */ @@ -251,7 +257,7 @@ namespace SourceHook virtual const void *GetOverrideRet() = 0; //!< Gets the override result. If none is specified, NULL virtual void *GetIfacePtr() = 0; //!< Gets the interface pointer ////////////////////////////////////////////////////////////////////////// - // For hookers + // For hook managers virtual META_RES &GetCurResRef() = 0; //!< Gets the pointer to the current meta result virtual META_RES &GetPrevResRef() = 0; //!< Gets the pointer to the previous meta result virtual META_RES &GetStatusRef() = 0; //!< Gets the pointer to the status variable @@ -263,15 +269,15 @@ namespace SourceHook ////////////////////////////////////////////////////////////////////////// // Macro interface -#define SET_META_RESULT(result) g_SHPtr->SetRes(result) -#define RETURN_META(result) do { g_SHPtr->SetRes(result); return; } while(0) -#define RETURN_META_VALUE(result, value) do { g_SHPtr->SetRes(result); return (value); } while(0) +#define SET_META_RESULT(result) SH_GLOB_SHPTR->SetRes(result) +#define RETURN_META(result) do { SH_GLOB_SHPTR->SetRes(result); return; } while(0) +#define RETURN_META_VALUE(result, value) do { SH_GLOB_SHPTR->SetRes(result); return (value); } while(0) -#define META_RESULT_STATUS g_SHPtr->GetStatus() -#define META_RESULT_PREVIOUS g_SHPtr->GetPrevRes() -#define META_RESULT_ORIG_RET(type) *(const type *)g_SHPtr->GetOrigRet() -#define META_RESULT_OVERRIDE_RET(type) *(const type *)g_SHPtr->GetOverrideRet() -#define META_IFACEPTR g_SHPtr->GetIfacePtr() +#define META_RESULT_STATUS SH_GLOB_SHPTR->GetStatus() +#define META_RESULT_PREVIOUS SH_GLOB_SHPTR->GetPrevRes() +#define META_RESULT_ORIG_RET(type) *(const type *)SH_GLOB_SHPTR->GetOrigRet() +#define META_RESULT_OVERRIDE_RET(type) *(const type *)SH_GLOB_SHPTR->GetOverrideRet() +#define META_IFACEPTR SH_GLOB_SHPTR->GetIfacePtr() /** @@ -280,8 +286,8 @@ namespace SourceHook * @param ifacetype The type of the interface * @param ifaceptr The interface pointer */ -#define SH_GET_CALLCLASS(ifacetype, ifaceptr) reinterpret_cast(g_SHPtr->GetCallClass(ifaceptr, sizeof(ifacetype))) -#define SH_RELEASE_CALLCLASS(ptr) g_SHPtr->ReleaseCallClass(reinterpret_cast(ptr)) +#define SH_GET_CALLCLASS(ifacetype, ifaceptr) reinterpret_cast(SH_GLOB_SHPTR->GetCallClass(ifaceptr, sizeof(ifacetype))) +#define SH_RELEASE_CALLCLASS(ptr) SH_GLOB_SHPTR->ReleaseCallClass(reinterpret_cast(ptr)) #define SH_ADD_HOOK(ifacetype, ifacefunc, ifaceptr, handler, post) \ SourceHook::SH_FHAdd##ifacetype##ifacefunc((void*)ifaceptr, post, handler) @@ -303,8 +309,8 @@ namespace SourceHook ////////////////////////////////////////////////////////////////////////// #define SH_FHCls(ift, iff, ov) FHCls_##ift##iff##ov -#define SHINT_MAKE_HOOKERPUBFUNC(ifacetype, ifacefunc, overload, funcptr) \ - static int Hooker(HookerAction action, HookerInfo *param) \ +#define SHINT_MAKE_HOOKMANPUBFUNC(ifacetype, ifacefunc, overload, funcptr) \ + static int HookManPubFunc(HookManagerAction action, HookManagerInfo *param) \ { \ if (action == HA_GetInfo) \ { \ @@ -342,28 +348,28 @@ namespace SourceHook struct SH_FHCls(ifacetype,ifacefunc,overload) \ { \ static SH_FHCls(ifacetype,ifacefunc,overload) ms_Inst; \ - static HookerInfo *ms_HI; \ + static HookManagerInfo *ms_HI; \ static const char *ms_Proto; \ - SHINT_MAKE_HOOKERPUBFUNC(ifacetype, ifacefunc, overload, funcptr) + SHINT_MAKE_HOOKMANPUBFUNC(ifacetype, ifacefunc, overload, funcptr) #define SHINT_MAKE_GENERICSTUFF_END(ifacetype, ifacefunc, overload, proto) \ }; \ const char *SH_FHCls(ifacetype,ifacefunc,overload)::ms_Proto = proto; \ SH_FHCls(ifacetype,ifacefunc,overload) SH_FHCls(ifacetype,ifacefunc,overload)::ms_Inst; \ - HookerInfo *SH_FHCls(ifacetype,ifacefunc,overload)::ms_HI; \ + HookManagerInfo *SH_FHCls(ifacetype,ifacefunc,overload)::ms_HI; \ bool SH_FHAdd##ifacetype##ifacefunc(void *iface, bool post, \ SH_FHCls(ifacetype,ifacefunc,overload)::FD handler) \ { \ - return g_SHPtr->AddHook(g_Plug, iface, sizeof(ifacetype), \ - SH_FHCls(ifacetype,ifacefunc,overload)::Hooker, \ + return SH_GLOB_SHPTR->AddHook(SH_GLOB_PLUGPTR, iface, sizeof(ifacetype), \ + SH_FHCls(ifacetype,ifacefunc,overload)::HookManPubFunc, \ new CSHDelegate(handler), post); \ } \ bool SH_FHRemove##ifacetype##ifacefunc(void *iface, bool post, \ SH_FHCls(ifacetype,ifacefunc,overload)::FD handler) \ { \ CSHDelegate tmp(handler); \ - return g_SHPtr->RemoveHook(g_Plug, iface, \ - SH_FHCls(ifacetype,ifacefunc,overload)::Hooker, &tmp, post); \ + return SH_GLOB_SHPTR->RemoveHook(SH_GLOB_PLUGPTR, iface, \ + SH_FHCls(ifacetype,ifacefunc,overload)::HookManPubFunc, &tmp, post); \ } \ } @@ -371,25 +377,25 @@ namespace SourceHook /* 1) Find the iface ptr */ \ /* 1.1) Adjust to original this pointer */ \ void *origthis = this - ms_HI->thisptr_offs; \ - std::list::iterator ifaceiter = std::find(ms_HI->ifaces.begin(), \ + std::list::iterator ifaceiter = std::find(ms_HI->ifaces.begin(), \ ms_HI->ifaces.end(), origthis); \ SH_ASSERT(ifaceiter != ms_HI->ifaces.end()); \ - HookerInfo::Iface &ci = *ifaceiter; \ + HookManagerInfo::Iface &ci = *ifaceiter; \ /* 2) Declare some vars and set it up */ \ - std::list &prelist = ci.hooks_pre; \ - std::list &postlist = ci.hooks_post; \ + std::list &prelist = ci.hooks_pre; \ + std::list &postlist = ci.hooks_post; \ rettype orig_ret, override_ret, plugin_ret; \ - META_RES &cur_res = g_SHPtr->GetCurResRef(); \ - META_RES &prev_res = g_SHPtr->GetPrevResRef(); \ - META_RES &status = g_SHPtr->GetStatusRef(); \ + META_RES &cur_res = SH_GLOB_SHPTR->GetCurResRef(); \ + META_RES &prev_res = SH_GLOB_SHPTR->GetPrevResRef(); \ + META_RES &status = SH_GLOB_SHPTR->GetStatusRef(); \ status = MRES_IGNORED; \ - g_SHPtr->SetIfacePtr(ci.ptr); \ - g_SHPtr->SetOrigRet(reinterpret_cast(&orig_ret)); \ - g_SHPtr->SetOverrideRet(NULL); + SH_GLOB_SHPTR->SetIfacePtr(ci.ptr); \ + SH_GLOB_SHPTR->SetOrigRet(reinterpret_cast(&orig_ret)); \ + SH_GLOB_SHPTR->SetOverrideRet(NULL); #define SH_CALL_HOOKS(post, params) \ prev_res = MRES_IGNORED; \ - for (std::list::iterator hiter = post##list.begin(); hiter != post##list.end(); ++hiter) \ + for (std::list::iterator hiter = post##list.begin(); hiter != post##list.end(); ++hiter) \ { \ cur_res = MRES_IGNORED; \ plugin_ret = reinterpret_cast*>(hiter->handler)->GetDeleg() params; \ @@ -399,7 +405,7 @@ namespace SourceHook if (cur_res >= MRES_OVERRIDE) \ { \ override_ret = plugin_ret; \ - g_SHPtr->SetOverrideRet(&override_ret); \ + SH_GLOB_SHPTR->SetOverrideRet(&override_ret); \ } \ } @@ -424,23 +430,23 @@ namespace SourceHook /* 1) Find the iface ptr */ \ /* 1.1) Adjust to original this pointer */ \ void *origthis = this - ms_HI->thisptr_offs; \ - std::list::iterator ifaceiter = std::find(ms_HI->ifaces.begin(), \ + std::list::iterator ifaceiter = std::find(ms_HI->ifaces.begin(), \ ms_HI->ifaces.end(), origthis); \ SH_ASSERT(ifaceiter != ms_HI->ifaces.end()); \ - HookerInfo::Iface &ci = *ifaceiter; \ + HookManagerInfo::Iface &ci = *ifaceiter; \ /* 2) Declare some vars and set it up */ \ - std::list &prelist = ci.hooks_pre; \ - std::list &postlist = ci.hooks_post; \ - META_RES &cur_res = g_SHPtr->GetCurResRef(); \ - META_RES &prev_res = g_SHPtr->GetPrevResRef(); \ - META_RES &status = g_SHPtr->GetStatusRef(); \ + std::list &prelist = ci.hooks_pre; \ + std::list &postlist = ci.hooks_post; \ + META_RES &cur_res = SH_GLOB_SHPTR->GetCurResRef(); \ + META_RES &prev_res = SH_GLOB_SHPTR->GetPrevResRef(); \ + META_RES &status = SH_GLOB_SHPTR->GetStatusRef(); \ status = MRES_IGNORED; \ - g_SHPtr->SetIfacePtr(ci.ptr); \ - g_SHPtr->SetOverrideRet(NULL); + SH_GLOB_SHPTR->SetIfacePtr(ci.ptr); \ + SH_GLOB_SHPTR->SetOverrideRet(NULL); #define SH_CALL_HOOKS_void(post, params) \ prev_res = MRES_IGNORED; \ - for (std::list::iterator hiter = post##list.begin(); hiter != post##list.end(); ++hiter) \ + for (std::list::iterator hiter = post##list.begin(); hiter != post##list.end(); ++hiter) \ { \ cur_res = MRES_IGNORED; \ reinterpret_cast*>(hiter->handler)->GetDeleg() params; \ diff --git a/sourcehook/sourcehook_impl.h b/sourcehook/sourcehook_impl.h index b1c08e6..b124de6 100644 --- a/sourcehook/sourcehook_impl.h +++ b/sourcehook/sourcehook_impl.h @@ -22,9 +22,26 @@ namespace SourceHook class CSourceHookImpl : public ISourceHook { /** - * @brief A list of HookerInfo structures + * @brief A hook can be removed if you have this information */ - typedef std::list HookerInfoList; + struct RemoveHookInfo + { + RemoveHookInfo(Plugin p, void *i, HookManagerPubFunc h, ISHDelegate *hd, bool ps) + : plug(p), iface(i), hpf(h), handler(hd), post(ps) + { + } + + Plugin plug; + void *iface; + HookManagerPubFunc hpf; + ISHDelegate *handler; + bool post; + }; + + /** + * @brief A list of HookManagerInfo structures + */ + typedef std::list HookManInfoList; /** @@ -33,14 +50,14 @@ namespace SourceHook typedef std::list Impl_CallClassList; Impl_CallClassList m_CallClasses; //!< A list of already generated callclasses - HookerInfoList m_Hookers; //!< A list of hookers + HookManInfoList m_HookMans; //!< A list of hook managers int m_PageSize; //!< Stores the system's page size /** - * @brief Finds a hooker for a function based on a text-prototype, a vtable offset and a vtable index + * @brief Finds a hook manager for a function based on a text-prototype, a vtable offset and a vtable index */ - HookerInfoList::iterator FindHooker(HookerInfoList::iterator begin, HookerInfoList::iterator end, + HookManInfoList::iterator FindHookMan(HookManInfoList::iterator begin, HookManInfoList::iterator end, const char *proto, int vtblofs, int vtblidx, int thisptrofs); void FreeCallClass(CallClass &cc); @@ -57,12 +74,12 @@ namespace SourceHook ~CSourceHookImpl(); /** - * @brief Make sure that a plugin is not used by any other plugins anymore, and unregister all its hookers + * @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 Shut down the whole system, unregister all hookers + * @brief Shut down the whole system, unregister all hook managers */ void CompleteShutdown(); @@ -73,11 +90,12 @@ namespace SourceHook * * @param plug The unique identifier of the plugin that calls this function * @param iface The interface pointer - * @param myHooker A hooker (hook manager) function that should be capable of handling the corresponding function + * @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 ifacesize, Hooker myHooker, ISHDelegate *handler, bool post); + bool AddHook(Plugin plug, void *iface, int ifacesize, HookManagerPubFunc myHookMan, ISHDelegate *handler, bool post); /** * @brief Removes a hook. @@ -86,16 +104,14 @@ namespace SourceHook * * @param plug The unique identifier of the plugin that calls this function * @param iface The interface pointer - * @param vtableoffset Offset to the vtable, in bytes - * @param vtableidx Pointer to the vtable index of the function - * @param proto A text version of the function prototype; generated by the macros + * @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, Hooker myHooker, ISHDelegate *handler, bool post); + bool RemoveHook(Plugin plug, void *iface, HookManagerPubFunc myHookMan, ISHDelegate *handler, bool post); /** - * @brief Checks whether a plugin has (a) hooker(s) that is/are currently used by other plugins + * @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 */ @@ -123,7 +139,7 @@ namespace SourceHook virtual void *GetIfacePtr(); //!< Gets the interface pointer ////////////////////////////////////////////////////////////////////////// - // For hookers + // For hook managers virtual META_RES &GetCurResRef(); //!< Gets the pointer to the current meta result virtual META_RES &GetPrevResRef(); //!< Gets the pointer to the previous meta result virtual META_RES &GetStatusRef(); //!< Gets the pointer to the status variable