Fixed RemoveHook + minor changes

--HG--
extra : convert_revision : svn%3Ac2935e3e-5518-0410-8daf-afa5dab7d4e3/trunk%4048
This commit is contained in:
Pavol Marko 2005-05-01 09:55:51 +00:00
parent 373a6f228f
commit 211535d433
4 changed files with 189 additions and 76 deletions

View File

@ -124,6 +124,10 @@ namespace SourceHook
{
}
CSHDelegate(const CSHDelegate &other) : m_Deleg(other.m_Deleg)
{
}
void DeleteThis()
{
delete this;
@ -165,17 +169,18 @@ namespace SourceHook
};
void *vfnptr; //!< Pointer to the function
void *orig_entry; //!< The original vtable entry
void *orig_entry; //!< The original vtable entry
typedef std::list<Iface> IfaceList;
typedef IfaceList::iterator IfaceListIter;
IfaceList ifaces;
IfaceList ifaces; //!< List of interface pointers
bool operator ==(void *other)
{
return vfnptr == other;
}
};
Plugin plug; //!< The owner plugin
const char *proto; //!< The prototype of the function the hook manager is responsible for
int vtbl_idx; //!< The vtable index
@ -272,16 +277,17 @@ namespace SourceHook
};
}
//////////////////////////////////////////////////////////////////////////
// Macro interface
#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)
/************************************************************************/
/* High level interface */
/************************************************************************/
#define SET_META_RESULT(result) SH_GLOB_SHPTR->SetRes(result)
#define RETURN_META(result) do { SET_META_RESULT(result); return; } while(0)
#define RETURN_META_VALUE(result, value) do { SET_META_RESULT(result); return (value); } while(0)
#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_RESULT_ORIG_RET(type) *reinterpret_cast<const type*>(SH_GLOB_SHPTR->GetOrigRet())
#define META_RESULT_OVERRIDE_RET(type) *reinterpret_cast<const type*>(SH_GLOB_SHPTR->GetOverrideRet())
#define META_IFACEPTR SH_GLOB_SHPTR->GetIfacePtr()
@ -291,13 +297,20 @@ namespace SourceHook
* @param ifaceptr The interface pointer
*/
template<class ifacetype>
inline SourceHook::CallClass<ifacetype> *SH_GET_CALLCLASS(ifacetype *ptr)
inline SourceHook::CallClass<ifacetype> *SH_GET_CALLCLASS_R(SourceHook::ISourceHook *shptr, ifacetype *ptr)
{
return reinterpret_cast<SourceHook::CallClass<ifacetype>*>(
SH_GLOB_SHPTR->GetCallClass(reinterpret_cast<void*>(ptr)));
shptr->GetCallClass(reinterpret_cast<void*>(ptr)));
}
#define SH_RELEASE_CALLCLASS(ptr) SH_GLOB_SHPTR->ReleaseCallClass(reinterpret_cast<SourceHook::GenericCallClass*>(ptr))
template<class ifacetype>
inline void SH_RELEASE_CALLCLASS_R(SourceHook::ISourceHook *shptr, SourceHook::CallClass<ifacetype> *ptr)
{
shptr->ReleaseCallClass(reinterpret_cast<SourceHook::GenericCallClass*>(ptr));
}
#define SH_GET_CALLCLASS(ptr) SH_GET_CALLCLASS_R(SH_GLOB_SHPTR, ptr)
#define SH_RELEASE_CALLCLASS(ptr) SH_RELEASE_CALLCLASS_R(SH_GLOB_SHPTR, ptr)
#define SH_ADD_HOOK(ifacetype, ifacefunc, ifaceptr, handler, post) \
__SourceHook_FHAdd##ifacetype##ifacefunc((void*)ifaceptr, post, handler)
@ -317,6 +330,7 @@ inline SourceHook::CallClass<ifacetype> *SH_GET_CALLCLASS(ifacetype *ptr)
#if SH_COMP == SH_COMP_MSVC
# define SH_SETUP_MFP(mfp) \
reinterpret_cast<void**>(&mfp)[0] = vfnptr.orig_entry;

View File

@ -280,53 +280,54 @@ namespace SourceHook
reinterpret_cast<char*>(adjustediface) + tmp.vtbl_offs);
void *cur_vfnptr = reinterpret_cast<void*>(cur_vtptr + tmp.vtbl_idx);
for (HookManagerInfo::VfnPtrListIter vfnptr_iter = hookman->vfnptrs.begin();
vfnptr_iter != hookman->vfnptrs.end(); ++vfnptr_iter)
HookManagerInfo::VfnPtrListIter vfnptr_iter = std::find(hookman->vfnptrs.begin(), hookman->vfnptrs.end(), cur_vfnptr);
if (vfnptr_iter == hookman->vfnptrs.end())
return false;
for (HookManagerInfo::VfnPtr::IfaceListIter iface_iter = vfnptr_iter->ifaces.begin();
iface_iter != vfnptr_iter->ifaces.end();)
{
if (vfnptr_iter->vfnptr == cur_vfnptr)
std::list<HookManagerInfo::VfnPtr::Iface::Hook> &hooks =
post ? iface_iter->hooks_post : iface_iter->hooks_pre;
bool erase;
for (std::list<HookManagerInfo::VfnPtr::Iface::Hook>::iterator hookiter = hooks.begin();
hookiter != hooks.end(); erase ? hookiter = hooks.erase(hookiter) : ++hookiter)
{
for (HookManagerInfo::VfnPtr::IfaceListIter iface_iter = vfnptr_iter->ifaces.begin();
iface_iter != vfnptr_iter->ifaces.end(); ++iface_iter)
{
std::list<HookManagerInfo::VfnPtr::Iface::Hook> &hooks =
post ? iface_iter->hooks_post : iface_iter->hooks_pre;
bool erase;
for (std::list<HookManagerInfo::VfnPtr::Iface::Hook>::iterator hookiter = hooks.begin();
hookiter != hooks.end(); erase ? hookiter = hooks.erase(hookiter) : ++hookiter)
{
erase = hookiter->plug == plug && hookiter->handler->IsEqual(handler);
if (erase)
hookiter->handler->DeleteThis(); // Make the _plugin_ delete the handler object
}
if (iface_iter->hooks_post.empty() && iface_iter->hooks_pre.empty())
{
vfnptr_iter->ifaces.erase(iface_iter);
if (vfnptr_iter->ifaces.empty())
{
// Deactivate the hook
*reinterpret_cast<void**>(vfnptr_iter->vfnptr) = vfnptr_iter->orig_entry;
hookman->vfnptrs.erase(vfnptr_iter);
// Remove callclass patch
for (Impl_CallClassList::iterator cciter = m_CallClasses.begin(); cciter != m_CallClasses.end(); ++cciter)
if (cciter->cc.ptr == adjustediface)
RemoveCallClassPatch(*cciter, tmp.vtbl_offs, tmp.vtbl_idx);
if (hookman->vfnptrs.empty())
{
// Unregister the hook manager
hookman->func(HA_Unregister, NULL);
}
}
}
}
return true;
erase = hookiter->plug == plug && hookiter->handler->IsEqual(handler);
if (erase)
hookiter->handler->DeleteThis(); // Make the _plugin_ delete the handler object
}
if (iface_iter->hooks_post.empty() && iface_iter->hooks_pre.empty())
{
iface_iter = vfnptr_iter->ifaces.erase(iface_iter);
if (vfnptr_iter->ifaces.empty())
{
// Deactivate the hook
*reinterpret_cast<void**>(vfnptr_iter->vfnptr) = vfnptr_iter->orig_entry;
hookman->vfnptrs.erase(vfnptr_iter);
// Remove callclass patch
for (Impl_CallClassList::iterator cciter = m_CallClasses.begin(); cciter != m_CallClasses.end(); ++cciter)
if (cciter->cc.ptr == adjustediface)
RemoveCallClassPatch(*cciter, tmp.vtbl_offs, tmp.vtbl_idx);
if (hookman->vfnptrs.empty())
{
// Unregister the hook manager
hookman->func(HA_Unregister, NULL);
}
// Don't try to continue looping through ifaces
// - the list is already invalid
return true;
}
}
else
++iface_iter;
}
return false;
return true;
}
GenericCallClass *CSourceHookImpl::GetCallClass(void *iface)

View File

@ -124,6 +124,10 @@ namespace SourceHook
{
}
CSHDelegate(const CSHDelegate &other) : m_Deleg(other.m_Deleg)
{
}
void DeleteThis()
{
delete this;
@ -165,17 +169,18 @@ namespace SourceHook
};
void *vfnptr; //!< Pointer to the function
void *orig_entry; //!< The original vtable entry
void *orig_entry; //!< The original vtable entry
typedef std::list<Iface> IfaceList;
typedef IfaceList::iterator IfaceListIter;
IfaceList ifaces;
IfaceList ifaces; //!< List of interface pointers
bool operator ==(void *other)
{
return vfnptr == other;
}
};
Plugin plug; //!< The owner plugin
const char *proto; //!< The prototype of the function the hook manager is responsible for
int vtbl_idx; //!< The vtable index
@ -272,16 +277,17 @@ namespace SourceHook
};
}
//////////////////////////////////////////////////////////////////////////
// Macro interface
#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)
/************************************************************************/
/* High level interface */
/************************************************************************/
#define SET_META_RESULT(result) SH_GLOB_SHPTR->SetRes(result)
#define RETURN_META(result) do { SET_META_RESULT(result); return; } while(0)
#define RETURN_META_VALUE(result, value) do { SET_META_RESULT(result); return (value); } while(0)
#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_RESULT_ORIG_RET(type) *reinterpret_cast<const type*>(SH_GLOB_SHPTR->GetOrigRet())
#define META_RESULT_OVERRIDE_RET(type) *reinterpret_cast<const type*>(SH_GLOB_SHPTR->GetOverrideRet())
#define META_IFACEPTR SH_GLOB_SHPTR->GetIfacePtr()
@ -291,13 +297,20 @@ namespace SourceHook
* @param ifaceptr The interface pointer
*/
template<class ifacetype>
inline SourceHook::CallClass<ifacetype> *SH_GET_CALLCLASS(ifacetype *ptr)
inline SourceHook::CallClass<ifacetype> *SH_GET_CALLCLASS_R(SourceHook::ISourceHook *shptr, ifacetype *ptr)
{
return reinterpret_cast<SourceHook::CallClass<ifacetype>*>(
SH_GLOB_SHPTR->GetCallClass(reinterpret_cast<void*>(ptr)));
shptr->GetCallClass(reinterpret_cast<void*>(ptr)));
}
#define SH_RELEASE_CALLCLASS(ptr) SH_GLOB_SHPTR->ReleaseCallClass(reinterpret_cast<SourceHook::GenericCallClass*>(ptr))
template<class ifacetype>
inline void SH_RELEASE_CALLCLASS_R(SourceHook::ISourceHook *shptr, SourceHook::CallClass<ifacetype> *ptr)
{
shptr->ReleaseCallClass(reinterpret_cast<SourceHook::GenericCallClass*>(ptr));
}
#define SH_GET_CALLCLASS(ptr) SH_GET_CALLCLASS_R(SH_GLOB_SHPTR, ptr)
#define SH_RELEASE_CALLCLASS(ptr) SH_RELEASE_CALLCLASS_R(SH_GLOB_SHPTR, ptr)
#define SH_ADD_HOOK(ifacetype, ifacefunc, ifaceptr, handler, post) \
__SourceHook_FHAdd##ifacetype##ifacefunc((void*)ifaceptr, post, handler)
@ -317,6 +330,7 @@ inline SourceHook::CallClass<ifacetype> *SH_GET_CALLCLASS(ifacetype *ptr)
#if SH_COMP == SH_COMP_MSVC
# define SH_SETUP_MFP(mfp) \
reinterpret_cast<void**>(&mfp)[0] = vfnptr.orig_entry;

View File

@ -19,13 +19,15 @@
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="."
FavorSizeOrSpeed="0"
AdditionalIncludeDirectories=".."
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
StringPooling="TRUE"
MinimalRebuild="TRUE"
BasicRuntimeChecks="3"
RuntimeLibrary="5"
EnableFunctionLevelLinking="TRUE"
RuntimeTypeInfo="TRUE"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="TRUE"
@ -67,14 +69,16 @@
InlineFunctionExpansion="1"
FavorSizeOrSpeed="2"
OmitFramePointers="TRUE"
AdditionalIncludeDirectories=".."
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
StringPooling="TRUE"
RuntimeLibrary="4"
EnableFunctionLevelLinking="TRUE"
RuntimeTypeInfo="TRUE"
UsePrecompiledHeader="0"
BrowseInformation="0"
WarningLevel="3"
SuppressStartupBanner="FALSE"
SuppressStartupBanner="TRUE"
Detect64BitPortabilityProblems="TRUE"
DebugInformationFormat="3"/>
<Tool
@ -114,18 +118,21 @@
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
Optimization="2"
GlobalOptimizations="TRUE"
Optimization="3"
GlobalOptimizations="FALSE"
InlineFunctionExpansion="1"
EnableIntrinsicFunctions="FALSE"
FavorSizeOrSpeed="2"
OptimizeForWindowsApplication="TRUE"
AdditionalIncludeDirectories="."
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
OmitFramePointers="TRUE"
OptimizeForWindowsApplication="FALSE"
AdditionalIncludeDirectories=".."
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
StringPooling="TRUE"
MinimalRebuild="FALSE"
BasicRuntimeChecks="0"
RuntimeLibrary="5"
RuntimeLibrary="4"
EnableFunctionLevelLinking="TRUE"
RuntimeTypeInfo="TRUE"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="TRUE"
@ -155,6 +162,53 @@
<Tool
Name="VCWebDeploymentTool"/>
</Configuration>
<Configuration
Name="Debug_NoDebugRuntimeLib|Win32"
OutputDirectory="Debug_NoDebugRuntimeLib"
IntermediateDirectory="Debug_NoDebugRuntimeLib"
ConfigurationType="1"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
FavorSizeOrSpeed="0"
AdditionalIncludeDirectories=".."
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
StringPooling="TRUE"
MinimalRebuild="TRUE"
BasicRuntimeChecks="3"
RuntimeLibrary="4"
EnableFunctionLevelLinking="TRUE"
RuntimeTypeInfo="TRUE"
UsePrecompiledHeader="0"
WarningLevel="3"
Detect64BitPortabilityProblems="TRUE"
DebugInformationFormat="4"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
OutputFile="$(OutDir)/test.exe"
LinkIncremental="2"
GenerateDebugInformation="TRUE"
ProgramDatabaseFile="$(OutDir)/test.pdb"
SubSystem="1"
TargetMachine="1"/>
<Tool
Name="VCMIDLTool"/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
</Configuration>
</Configurations>
<Files>
<Filter
@ -164,7 +218,13 @@
RelativePath="main.cpp">
</File>
<File
RelativePath="sourcehook.cpp">
RelativePath="..\sourcehook.cpp">
</File>
<File
RelativePath="test1.cpp">
</File>
<File
RelativePath="test2.cpp">
</File>
</Filter>
<Filter
@ -176,6 +236,30 @@
<File
RelativePath="sourcehook_impl.h">
</File>
<File
RelativePath="testevents.h">
</File>
<Filter
Name="generate"
Filter="">
<File
RelativePath="..\generate\FastDelegate.hxx">
</File>
<File
RelativePath="..\generate\sourcehook.hxx">
<FileConfiguration
Name="Debug_NoDebugRuntimeLib|Win32">
<Tool
Name="VCCustomBuildTool"
CommandLine="echo on
pushd ..\generate
shworker.exe iter 16 sourcehook.hxx sourcehook.h
copy sourcehook.h ..\sourcehook.h
popd"
Outputs="../sourcehook.h"/>
</FileConfiguration>
</File>
</Filter>
</Filter>
<Filter
Name="Resource Files"