Skip to content

Commit 1c92d10

Browse files
committed
Add new proto info
1 parent 28cb3df commit 1c92d10

5 files changed

+216
-36
lines changed

core/sourcehook/sourcehook.h

+157-35
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,20 @@ namespace SourceHook
184184
*/
185185
struct PassInfo
186186
{
187+
PassInfo()
188+
: size(0)
189+
, type(0)
190+
, flags(0)
191+
{
192+
}
193+
194+
PassInfo(size_t typeSize, int typeId, unsigned int typeFlags)
195+
: size(typeSize)
196+
, type(typeId)
197+
, flags(typeFlags)
198+
{
199+
}
200+
187201
enum PassType
188202
{
189203
PassType_Unknown=0, /**< Unknown -- no extra info available */
@@ -217,6 +231,22 @@ namespace SourceHook
217231

218232
struct V2Info
219233
{
234+
V2Info()
235+
: pNormalCtor(nullptr)
236+
, pCopyCtor(nullptr)
237+
, pDtor(nullptr)
238+
, pAssignOperator(nullptr)
239+
{
240+
}
241+
242+
V2Info(void *normalCtor, void *copyCtor, void *dtor, void *assignOperator)
243+
: pNormalCtor(normalCtor)
244+
, pCopyCtor(copyCtor)
245+
, pDtor(dtor)
246+
, pAssignOperator(assignOperator)
247+
{
248+
}
249+
220250
void *pNormalCtor;
221251
void *pCopyCtor;
222252
void *pDtor;
@@ -252,6 +282,26 @@ namespace SourceHook
252282
const PassInfo::V2Info *paramsPassInfo2;
253283
};
254284

285+
class IProtoInfo
286+
{
287+
public:
288+
enum class ProtoInfoVersion : int
289+
{
290+
ProtoInfoVersionInvalid = -1,
291+
ProtoInfoVersion1 = 0,
292+
ProtoInfoVersion2 = 1
293+
};
294+
295+
virtual ~IProtoInfo() = default;
296+
virtual size_t GetNumOfParams() const = 0;
297+
virtual const PassInfo &GetRetPassInfo() const = 0;
298+
virtual const PassInfo *GetParamsPassInfo() const = 0;
299+
virtual int GetConvention() const = 0;
300+
virtual IProtoInfo::ProtoInfoVersion GetVersion() const = 0;
301+
virtual const PassInfo::V2Info &GetRetPassInfo2() const = 0;
302+
virtual const PassInfo::V2Info *GetParamsPassInfo2() const = 0;
303+
};
304+
255305
struct IHookManagerInfo;
256306

257307
/**
@@ -409,6 +459,9 @@ namespace SourceHook
409459
{
410460
virtual void SetInfo(int hookman_version, int vtbloffs, int vtblidx,
411461
ProtoInfo *proto, void *hookfunc_vfnptr) = 0;
462+
463+
virtual void SetInfo(int hookman_version, int vtbloffs, int vtblidx,
464+
IProtoInfo *proto, void *hookfunc_vfnptr) = 0;
412465
};
413466

414467
// I'm adding support for functions which return references.
@@ -5130,12 +5183,17 @@ class PassInfoInitializer
51305183
InitializePassInfo<sizeof...(ArgsType), 0, ArgsType...>();
51315184
}
51325185

5133-
const PassInfo *ParamsPassInfo() const
5186+
const PassInfo *GetParamsPassInfo() const
51345187
{
51355188
return params_;
51365189
}
51375190

5138-
const size_t ParamsPassInfoSize() const
5191+
const PassInfo::V2Info *GetParamsPassInfoV2() const
5192+
{
5193+
return paramsV2_;
5194+
}
5195+
5196+
const size_t GetParamsPassInfoSize() const
51395197
{
51405198
return sizeof...(ArgsType);
51415199
}
@@ -5155,6 +5213,32 @@ class PassInfoInitializer
51555213
}
51565214

51575215
PassInfo params_[sizeof...(ArgsType)];
5216+
PassInfo::V2Info paramsV2_[sizeof...(ArgsType)];
5217+
};
5218+
5219+
// For zero arguments
5220+
template<>
5221+
class PassInfoInitializer<>
5222+
{
5223+
public:
5224+
constexpr PassInfoInitializer()
5225+
{
5226+
}
5227+
5228+
const PassInfo *GetParamsPassInfo() const
5229+
{
5230+
return nullptr;
5231+
}
5232+
5233+
const PassInfo::V2Info *GetParamsPassInfoV2() const
5234+
{
5235+
return nullptr;
5236+
}
5237+
5238+
const size_t GetParamsPassInfoSize() const
5239+
{
5240+
return 0;
5241+
}
51585242
};
51595243

51605244
template <typename T>
@@ -5181,7 +5265,7 @@ struct ReturnTypeInfo<void>
51815265
{
51825266
static const size_t size()
51835267
{
5184-
return 0; // why isn't it sizeof(void) like in TypeInfo<T>?
5268+
return 0;
51855269
}
51865270

51875271
static const int type()
@@ -5222,6 +5306,64 @@ class CHookManagerMemberFuncHandler : public IHookManagerMemberFunc
52225306
HookManagerMemberFunc func_;
52235307
};
52245308

5309+
template<typename ReturnType, class ... Params>
5310+
class CProtoInfo : public IProtoInfo
5311+
{
5312+
public:
5313+
constexpr CProtoInfo()
5314+
: retPassInfo(ReturnTypeInfo<ReturnType>::size(),
5315+
ReturnTypeInfo<ReturnType>::type(),
5316+
ReturnTypeInfo<ReturnType>::flags())
5317+
{
5318+
}
5319+
5320+
virtual ~CProtoInfo() override
5321+
{
5322+
}
5323+
5324+
virtual size_t GetNumOfParams() const override
5325+
{
5326+
return paramsPassInfo.GetParamsPassInfoSize();
5327+
}
5328+
5329+
virtual const PassInfo &GetRetPassInfo() const override
5330+
{
5331+
return retPassInfo;
5332+
}
5333+
5334+
virtual const PassInfo *GetParamsPassInfo() const override
5335+
{
5336+
return paramsPassInfo.GetParamsPassInfo();
5337+
}
5338+
5339+
virtual int GetConvention() const override
5340+
{
5341+
return 0;
5342+
}
5343+
5344+
// version of the ProtoInfo structure.
5345+
virtual IProtoInfo::ProtoInfoVersion GetVersion() const override
5346+
{
5347+
return ProtoInfoVersion::ProtoInfoVersion2;
5348+
}
5349+
5350+
virtual const PassInfo::V2Info &GetRetPassInfo2() const override
5351+
{
5352+
return retPassInfo2;
5353+
}
5354+
5355+
virtual const PassInfo::V2Info *GetParamsPassInfo2() const override
5356+
{
5357+
return paramsPassInfo.GetParamsPassInfoV2();
5358+
}
5359+
5360+
private:
5361+
int numOfParams; //!< number of parameters
5362+
PassInfo retPassInfo; //!< PassInfo for the return value. size=0 -> no retval
5363+
PassInfo::V2Info retPassInfo2; //!< Version2 only
5364+
PassInfoInitializer<Params...> paramsPassInfo; //!< PassInfos for the parameters
5365+
};
5366+
52255367
template<typename ReturnType, class ... Params>
52265368
class ManualHookHandler : public CHookManagerMemberFuncHandler<ManualHookHandler<ReturnType, Params...>>
52275369
{
@@ -5237,40 +5379,26 @@ class ManualHookHandler : public CHookManagerMemberFuncHandler<ManualHookHandler
52375379
typedef ReturnType (T::*HookFunc)(Params...);
52385380
};
52395381

5240-
ManualHookHandler()
5382+
constexpr ManualHookHandler()
52415383
: CHookManagerMemberFuncHandler<ThisType>(this, &ThisType::HookManPubFunc)
5242-
, thisPointerOffset_(0)
5243-
, vTableIndex_(0)
5244-
, vtableOffset_(0)
52455384
, msMFI_{false, 0, 0, 0}
52465385
, msHI_(nullptr)
5247-
, msProto_{sizeof...(Params),
5248-
{ReturnTypeInfo<ReturnType>::size(), ReturnTypeInfo<ReturnType>::type(), ReturnTypeInfo<ReturnType>::flags()},
5249-
paramInfosM_.ParamsPassInfo(),
5250-
0,
5251-
__SH_EPI,
5252-
paramInfos2M_}
52535386
{
5254-
for(PassInfo::V2Info& paramInfo : paramInfos2M_)
5255-
{
5256-
paramInfo = __SH_EPI;
5257-
}
52585387
}
52595388

5389+
ManualHookHandler(const ManualHookHandler&) = delete;
5390+
5391+
ManualHookHandler(ManualHookHandler&&) = delete;
5392+
5393+
ManualHookHandler& operator=(const ManualHookHandler&) = delete;
5394+
5395+
ManualHookHandler& operator=(ManualHookHandler&&) = delete;
5396+
52605397
virtual ~ManualHookHandler()
52615398
{
52625399
//TODO apply RAII, cleanup all related hooks here
52635400
}
52645401

5265-
// TODO probably not needed for manual hooks
5266-
void Reconfigure()
5267-
{
5268-
msMFI_.isVirtual = true;
5269-
msMFI_.thisptroffs = thisPointerOffset_;
5270-
msMFI_.vtblindex = vTableIndex_;
5271-
msMFI_.vtbloffs = vtableOffset_;
5272-
}
5273-
52745402
void Reconfigure(int vtblindex, int vtbloffs = 0, int thisptroffs = 0)
52755403
{
52765404
g_SHPtr->RemoveHookManager(g_PLID, this);
@@ -5285,7 +5413,7 @@ class ManualHookHandler : public CHookManagerMemberFuncHandler<ManualHookHandler
52855413
typename ManualHookHandler::FD handler(callbackInstPtr, callbackFuncPtr);
52865414
typename ThisType::CMyDelegateImpl* tmp = new typename ThisType::CMyDelegateImpl(handler); // TODO use unique_ptr here
52875415

5288-
return g_SHPtr->AddHook(g_PLID, mode, iface, thisPointerOffset_, this, tmp, post);
5416+
return g_SHPtr->AddHook(g_PLID, mode, iface, 0, this, tmp, post);
52895417
}
52905418

52915419
template<typename T>
@@ -5294,7 +5422,7 @@ class ManualHookHandler : public CHookManagerMemberFuncHandler<ManualHookHandler
52945422
typename ManualHookHandler::FD handler(callbackInstPtr, callbackFuncPtr);
52955423
typename ThisType::CMyDelegateImpl tmp(handler);
52965424

5297-
return g_SHPtr->RemoveHook(g_PLID, iface, thisPointerOffset_, this, &tmp, post);
5425+
return g_SHPtr->RemoveHook(g_PLID, iface, 0, this, &tmp, post);
52985426
}
52995427

53005428
// For void return type only
@@ -5557,16 +5685,10 @@ class ManualHookHandler : public CHookManagerMemberFuncHandler<ManualHookHandler
55575685
}
55585686

55595687
private:
5560-
int thisPointerOffset_; // thisptroffs
5561-
int vTableIndex_; // vtblindex
5562-
int vtableOffset_; // vtbloffs
5563-
55645688
MemFuncInfo msMFI_; // ms_MFI
55655689
IHookManagerInfo *msHI_; // ms_HI
55665690

5567-
PassInfoInitializer<void, Params...> paramInfosM_; // ParamInfosM
5568-
PassInfo::V2Info paramInfos2M_[sizeof...(Params) + 1]; // ParamInfos2M
5569-
ProtoInfo msProto_; // ms_Proto
5691+
CProtoInfo<ReturnType, Params...> msProto_; // ms_Proto
55705692
};
55715693

55725694
} // SourceHook

core/sourcehook/sourcehook_impl_chookmaninfo.cpp

+10
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,16 @@ namespace SourceHook
3737
m_HookfuncVfnptr = hookfunc_vfnptr;
3838
}
3939

40+
void CHookManager::SetInfo(int hookman_version, int vtbloffs, int vtblidx,
41+
IProtoInfo *proto, void *hookfunc_vfnptr)
42+
{
43+
m_Version = hookman_version;
44+
m_VtblOffs = vtbloffs;
45+
m_VtblIdx = vtblidx;
46+
m_Proto = proto;
47+
m_HookfuncVfnptr = hookfunc_vfnptr;
48+
}
49+
4050
void CHookManager::Register()
4151
{
4252
m_PubFunc(true, this);

core/sourcehook/sourcehook_impl_chookmaninfo.h

+3
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,9 @@ namespace SourceHook
7474
// *** IHookManagerInfo interface ***
7575
void SetInfo(int hookman_version, int vtbloffs, int vtblidx,
7676
ProtoInfo *proto, void *hookfunc_vfnptr);
77+
78+
void SetInfo(int hookman_version, int vtbloffs, int vtblidx,
79+
IProtoInfo *proto, void *hookfunc_vfnptr);
7780
};
7881

7982
class CHookManList : public List<CHookManager>

core/sourcehook/sourcehook_impl_cproto.cpp

+39-1
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,6 @@ namespace SourceHook
3737
m_RetPassInfo.pDtor = NULL;
3838
m_RetPassInfo.pAssignOperator = NULL;
3939

40-
4140
m_ParamsPassInfo.resize(pProto->numOfParams);
4241

4342
for (int i = 1; i <= pProto->numOfParams; ++i)
@@ -89,6 +88,45 @@ namespace SourceHook
8988
}
9089
}
9190

91+
void CProto::Fill(const IProtoInfo *pProto)
92+
{
93+
if (pProto == nullptr)
94+
m_Version = -1;
95+
96+
m_ParamsPassInfo.clear();
97+
98+
m_Version = static_cast<int>(pProto->GetVersion());
99+
m_Convention = pProto->GetConvention();
100+
m_NumOfParams = pProto->GetNumOfParams();
101+
102+
const PassInfo& retPassInfo = pProto->GetRetPassInfo();
103+
m_RetPassInfo.size = retPassInfo.size;
104+
m_RetPassInfo.type = retPassInfo.type;
105+
m_RetPassInfo.flags = retPassInfo.flags;
106+
107+
const PassInfo::V2Info& retPassInfo2 = pProto->GetRetPassInfo2();
108+
m_RetPassInfo.pNormalCtor = retPassInfo2.pNormalCtor; // should be nullptr for Version 1
109+
m_RetPassInfo.pCopyCtor = retPassInfo2.pCopyCtor; // should be nullptr for Version 1
110+
m_RetPassInfo.pDtor = retPassInfo2.pDtor; // should be nullptr for Version 1
111+
m_RetPassInfo.pAssignOperator = retPassInfo2.pAssignOperator; // should be nullptr for Version 1
112+
113+
m_ParamsPassInfo.resize(pProto->GetNumOfParams());
114+
115+
const PassInfo* paramsPassInfo = pProto->GetParamsPassInfo();
116+
const PassInfo::V2Info* paramsPassInfo2 = pProto->GetParamsPassInfo2();
117+
for (int i = 0; i != m_NumOfParams; ++i)
118+
{
119+
m_ParamsPassInfo[i].size = paramsPassInfo[i].size;
120+
m_ParamsPassInfo[i].type = paramsPassInfo[i].type;
121+
m_ParamsPassInfo[i].flags = paramsPassInfo[i].flags;
122+
123+
m_ParamsPassInfo[i].pNormalCtor = paramsPassInfo2[i].pNormalCtor; // should be nullptr for Version 1
124+
m_ParamsPassInfo[i].pCopyCtor = paramsPassInfo2[i].pCopyCtor; // should be nullptr for Version 1
125+
m_ParamsPassInfo[i].pDtor = paramsPassInfo2[i].pDtor; // should be nullptr for Version 1
126+
m_ParamsPassInfo[i].pAssignOperator = paramsPassInfo2[i].pAssignOperator; // should be nullptr for Version 1
127+
}
128+
}
129+
92130
// Basic compat test
93131
// Other than this, we assume that the plugins know what they're doing
94132
bool CProto::operator == (const CProto &other) const

core/sourcehook/sourcehook_impl_cproto.h

+7
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,8 @@ namespace SourceHook
5353

5454
void Fill(const ProtoInfo *pProto);
5555

56+
void Fill(const IProtoInfo *pProto);
57+
5658
// For old sourcehook.h: flags 0 -> assume ByVal
5759
static unsigned int GetRealFlags(const PassInfo &info)
5860
{
@@ -69,6 +71,11 @@ namespace SourceHook
6971
Fill(pProto);
7072
}
7173

74+
CProto(const IProtoInfo *pProto)
75+
{
76+
Fill(pProto);
77+
}
78+
7279
CProto(const CProto &other) : m_Version(other.m_Version), m_NumOfParams(other.m_NumOfParams),
7380
m_RetPassInfo(other.m_RetPassInfo), m_ParamsPassInfo(other.m_ParamsPassInfo),
7481
m_Convention(other.m_Convention)

0 commit comments

Comments
 (0)