More linux fixes.
This commit is contained in:
parent
b2288d7333
commit
c3fcdbb7db
10
natives.cpp
10
natives.cpp
@ -42,6 +42,7 @@ bool GetHandleIfValidOrError(HandleType_t type, void **object, IPluginContext *p
|
||||
return true;
|
||||
}
|
||||
|
||||
#ifndef __linux__
|
||||
intptr_t GetObjectAddr(HookParamType type, void **params, int index)
|
||||
{
|
||||
if(type == HookParamType_Object)
|
||||
@ -51,6 +52,12 @@ intptr_t GetObjectAddr(HookParamType type, void **params, int index)
|
||||
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
intptr_t GetObjectAddr(HookParamType type, void **params, int index)
|
||||
{
|
||||
return (intptr_t)params[index];
|
||||
}
|
||||
#endif
|
||||
|
||||
//native Handle:DHookCreate(offset, HookType:hooktype, ReturnType:returntype, ThisPointerType:thistype, DHookCallback:callback);
|
||||
cell_t Native_CreateHook(IPluginContext *pContext, const cell_t *params)
|
||||
@ -495,8 +502,6 @@ cell_t Native_SetParamVector(IPluginContext *pContext, const cell_t *params)
|
||||
}
|
||||
return pContext->ThrowNativeError("Invalid param type to set. Param is not a vector.");
|
||||
}
|
||||
/*cell_t Native_GetReturnVector(IPluginContext *pContext, const cell_t *params);
|
||||
cell_t Native_SetReturnVector(IPluginContext *pContext, const cell_t *params);*/
|
||||
|
||||
// native DHookGetParamString(Handle:hParams, num, String:buffer[], size)
|
||||
cell_t Native_GetParamString(IPluginContext *pContext, const cell_t *params)
|
||||
@ -526,6 +531,7 @@ cell_t Native_GetParamString(IPluginContext *pContext, const cell_t *params)
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
// native DHookGetReturnString(Handle:hReturn, String:buffer[], size)
|
||||
cell_t Native_GetReturnString(IPluginContext *pContext, const cell_t *params)
|
||||
{
|
||||
|
90
vfunc_call.h
90
vfunc_call.h
@ -110,6 +110,7 @@ T CallVFunction(DHooksCallback *dg, HookParamsStruct *paramStruct, void *iface)
|
||||
}
|
||||
|
||||
T ret = 0;
|
||||
|
||||
if(dg->returnType == ReturnType_Void)
|
||||
{
|
||||
pCall = g_pBinTools->CreateVCall(dg->offset, 0, 0, NULL, paramInfo, dg->params.Count());
|
||||
@ -132,4 +133,93 @@ T CallVFunction(DHooksCallback *dg, HookParamsStruct *paramStruct, void *iface)
|
||||
return ret;
|
||||
}
|
||||
|
||||
#ifdef __linux__
|
||||
template <>
|
||||
string_t CallVFunction<string_t>(DHooksCallback *dg, HookParamsStruct *paramStruct, void *iface)
|
||||
{
|
||||
SourceMod::PassInfo *paramInfo = NULL;
|
||||
SourceMod::PassInfo returnInfo;
|
||||
|
||||
if(dg->returnType != ReturnType_Void)
|
||||
{
|
||||
returnInfo.flags = dg->returnFlag;
|
||||
returnInfo.size = sizeof(string_t);
|
||||
returnInfo.type = PassType_Object;
|
||||
}
|
||||
|
||||
ICallWrapper *pCall;
|
||||
|
||||
size_t size = GetStackArgsSize(dg);
|
||||
|
||||
unsigned char *vstk = (unsigned char *)malloc(sizeof(void *) + size);
|
||||
unsigned char *vptr = vstk;
|
||||
|
||||
*(void **)vptr = iface;
|
||||
|
||||
if(paramStruct)
|
||||
{
|
||||
vptr += sizeof(void *);
|
||||
paramInfo = (SourceMod::PassInfo *)malloc(sizeof(SourceMod::PassInfo) * dg->params.Count());
|
||||
for(int i = 0; i < dg->params.Count(); i++)
|
||||
{
|
||||
switch(dg->params.Element(i).type)
|
||||
{
|
||||
case HookParamType_Int:
|
||||
PARAMINFO_SWITCH(PassType_Basic);
|
||||
VSTK_PARAM_SWITCH(int);
|
||||
case HookParamType_Bool:
|
||||
PARAMINFO_SWITCH(PassType_Basic);
|
||||
VSTK_PARAM_SWITCH(cell_t);
|
||||
case HookParamType_Float:
|
||||
PARAMINFO_SWITCH(PassType_Float);
|
||||
VSTK_PARAM_SWITCH_FLOAT();
|
||||
case HookParamType_String:
|
||||
PARAMINFO_SWITCH(PassType_Object);
|
||||
VSTK_PARAM_SWITCH(int);
|
||||
case HookParamType_StringPtr:
|
||||
PARAMINFO_SWITCH(PassType_Basic);
|
||||
VSTK_PARAM_SWITCH(string_t *);
|
||||
case HookParamType_CharPtr:
|
||||
PARAMINFO_SWITCH(PassType_Basic);
|
||||
VSTK_PARAM_SWITCH(char *);
|
||||
case HookParamType_VectorPtr:
|
||||
PARAMINFO_SWITCH(PassType_Basic);
|
||||
VSTK_PARAM_SWITCH(Vector *);
|
||||
case HookParamType_CBaseEntity:
|
||||
PARAMINFO_SWITCH(PassType_Basic);
|
||||
VSTK_PARAM_SWITCH(CBaseEntity *);
|
||||
case HookParamType_Edict:
|
||||
PARAMINFO_SWITCH(PassType_Basic);
|
||||
VSTK_PARAM_SWITCH(edict_t *);
|
||||
default:
|
||||
PARAMINFO_SWITCH(PassType_Basic);
|
||||
VSTK_PARAM_SWITCH(void *);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
string_t ret = NULL_STRING;
|
||||
|
||||
if(dg->returnType == ReturnType_Void)
|
||||
{
|
||||
pCall = g_pBinTools->CreateVCall(dg->offset, 0, 0, NULL, paramInfo, dg->params.Count());
|
||||
pCall->Execute(vstk, NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
pCall = g_pBinTools->CreateVCall(dg->offset, 0, 0, &returnInfo, paramInfo, dg->params.Count());
|
||||
pCall->Execute(vstk, &ret);
|
||||
}
|
||||
|
||||
pCall->Destroy();
|
||||
free(vstk);
|
||||
|
||||
if(paramInfo != NULL)
|
||||
{
|
||||
free(paramInfo);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
166
vhook.cpp
166
vhook.cpp
@ -7,6 +7,11 @@ CUtlVector<DHooksManager *> g_pHooks;
|
||||
|
||||
using namespace SourceHook;
|
||||
|
||||
#ifndef __linux__
|
||||
#define OBJECT_OFFSET sizeof(void *)
|
||||
#else
|
||||
#define OBJECT_OFFSET (sizeof(void *)*2)
|
||||
#endif
|
||||
DHooksManager::DHooksManager(HookSetup *setup, void *iface, IPluginFunction *remove_callback, bool post)
|
||||
{
|
||||
this->callback = MakeHandler(setup->returnType);
|
||||
@ -110,9 +115,13 @@ size_t GetStackArgsSize(DHooksCallback *dg)
|
||||
res += dg->params.Element(i).size;
|
||||
}
|
||||
|
||||
#ifndef __linux__
|
||||
if(dg->returnType == ReturnType_Vector)//Account for result vector ptr.
|
||||
#else
|
||||
if(dg->returnType == ReturnType_Vector || dg->returnType == ReturnType_String)
|
||||
#endif
|
||||
{
|
||||
res += sizeof(void *);
|
||||
res += OBJECT_OFFSET;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
@ -120,15 +129,19 @@ HookParamsStruct *GetParamStruct(DHooksCallback *dg, void **argStack, size_t arg
|
||||
{
|
||||
HookParamsStruct *params = new HookParamsStruct();
|
||||
params->dg = dg;
|
||||
#ifndef __linux__
|
||||
if(dg->returnType != ReturnType_Vector)
|
||||
#else
|
||||
if(dg->returnType != ReturnType_Vector && dg->returnType != ReturnType_String)
|
||||
#endif
|
||||
{
|
||||
params->orgParams = (void **)malloc(argStackSize);
|
||||
memcpy(params->orgParams, argStack, argStackSize);
|
||||
}
|
||||
else //Offset result ptr
|
||||
{
|
||||
params->orgParams = (void **)malloc(argStackSize-sizeof(void *));
|
||||
memcpy(params->orgParams, argStack+sizeof(void *), argStackSize);
|
||||
params->orgParams = (void **)malloc(argStackSize-OBJECT_OFFSET);
|
||||
memcpy(params->orgParams, argStack+OBJECT_OFFSET, argStackSize-OBJECT_OFFSET);
|
||||
}
|
||||
params->newParams = (void **)malloc(dg->params.Count() * sizeof(void *));
|
||||
params->isChanged = (bool *)malloc(dg->params.Count() * sizeof(bool));
|
||||
@ -681,3 +694,150 @@ Vector *Callback_vector(DHooksCallback *dg, void **argStack)
|
||||
}
|
||||
return vec_result;
|
||||
}
|
||||
|
||||
#ifdef __linux__
|
||||
string_t *Callback_stringt(DHooksCallback *dg, void **argStack)
|
||||
{
|
||||
string_t *string_result = (string_t *)argStack[0]; // Save the result
|
||||
|
||||
HookReturnStruct *returnStruct = NULL;
|
||||
HookParamsStruct *paramStruct = NULL;
|
||||
Handle_t rHndl;
|
||||
Handle_t pHndl;
|
||||
|
||||
size_t argsize = GetStackArgsSize(dg);
|
||||
|
||||
if(dg->thisType == ThisPointer_CBaseEntity || dg->thisType == ThisPointer_Address)
|
||||
{
|
||||
dg->plugin_callback->PushCell(GetThisPtr(g_SHPtr->GetIfacePtr(), dg->thisType));
|
||||
}
|
||||
|
||||
returnStruct = GetReturnStruct(dg);
|
||||
rHndl = handlesys->CreateHandle(g_HookReturnHandle, returnStruct, dg->plugin_callback->GetParentRuntime()->GetDefaultContext()->GetIdentity(), myself->GetIdentity(), NULL);
|
||||
|
||||
if(!rHndl)
|
||||
{
|
||||
dg->plugin_callback->Cancel();
|
||||
if(returnStruct)
|
||||
{
|
||||
delete returnStruct;
|
||||
}
|
||||
g_SHPtr->SetRes(MRES_IGNORED);
|
||||
return NULL;
|
||||
}
|
||||
dg->plugin_callback->PushCell(rHndl);
|
||||
|
||||
if(argsize > 0)
|
||||
{
|
||||
paramStruct = GetParamStruct(dg, argStack, argsize);
|
||||
pHndl = handlesys->CreateHandle(g_HookParamsHandle, paramStruct, dg->plugin_callback->GetParentRuntime()->GetDefaultContext()->GetIdentity(), myself->GetIdentity(), NULL);
|
||||
if(!pHndl)
|
||||
{
|
||||
dg->plugin_callback->Cancel();
|
||||
if(returnStruct)
|
||||
{
|
||||
delete returnStruct;
|
||||
}
|
||||
if(paramStruct)
|
||||
{
|
||||
delete paramStruct;
|
||||
}
|
||||
g_SHPtr->SetRes(MRES_IGNORED);
|
||||
return NULL;
|
||||
}
|
||||
dg->plugin_callback->PushCell(pHndl);
|
||||
}
|
||||
cell_t result = (cell_t)MRES_Ignored;
|
||||
META_RES mres = MRES_IGNORED;
|
||||
dg->plugin_callback->Execute(&result);
|
||||
|
||||
void *ret = g_SHPtr->GetOverrideRetPtr();
|
||||
ret = string_result;
|
||||
switch((MRESReturn)result)
|
||||
{
|
||||
case MRES_Handled:
|
||||
case MRES_ChangedHandled:
|
||||
g_SHPtr->DoRecall();
|
||||
g_SHPtr->SetRes(MRES_SUPERCEDE);
|
||||
mres = MRES_SUPERCEDE;
|
||||
*string_result = CallVFunction<string_t>(dg, paramStruct, g_SHPtr->GetIfacePtr());
|
||||
break;
|
||||
case MRES_ChangedOverride:
|
||||
if(dg->returnType != ReturnType_Void)
|
||||
{
|
||||
if(returnStruct->isChanged)
|
||||
{
|
||||
*string_result = *(string_t *)returnStruct->newResult;
|
||||
}
|
||||
else //Throw an error if no override was set
|
||||
{
|
||||
g_SHPtr->SetRes(MRES_IGNORED);
|
||||
mres = MRES_IGNORED;
|
||||
dg->plugin_callback->GetParentRuntime()->GetDefaultContext()->ThrowNativeError("Tried to override return value without return value being set");
|
||||
break;
|
||||
}
|
||||
}
|
||||
g_SHPtr->DoRecall();
|
||||
g_SHPtr->SetRes(MRES_SUPERCEDE);
|
||||
mres = MRES_SUPERCEDE;
|
||||
CallVFunction<Vector>(dg, paramStruct, g_SHPtr->GetIfacePtr());
|
||||
break;
|
||||
case MRES_Override:
|
||||
if(dg->returnType != ReturnType_Void)
|
||||
{
|
||||
if(returnStruct->isChanged)
|
||||
{
|
||||
g_SHPtr->SetRes(MRES_OVERRIDE);
|
||||
mres = MRES_OVERRIDE;
|
||||
*string_result = *(string_t *)returnStruct->newResult;
|
||||
}
|
||||
else //Throw an error if no override was set
|
||||
{
|
||||
g_SHPtr->SetRes(MRES_IGNORED);
|
||||
mres = MRES_IGNORED;
|
||||
dg->plugin_callback->GetParentRuntime()->GetDefaultContext()->ThrowNativeError("Tried to override return value without return value being set");
|
||||
}
|
||||
}
|
||||
break;
|
||||
case MRES_Supercede:
|
||||
if(dg->returnType != ReturnType_Void)
|
||||
{
|
||||
if(returnStruct->isChanged)
|
||||
{
|
||||
g_SHPtr->SetRes(MRES_SUPERCEDE);
|
||||
mres = MRES_SUPERCEDE;
|
||||
*string_result = *(string_t *)returnStruct->newResult;
|
||||
}
|
||||
else //Throw an error if no override was set
|
||||
{
|
||||
g_SHPtr->SetRes(MRES_IGNORED);
|
||||
mres = MRES_IGNORED;
|
||||
dg->plugin_callback->GetParentRuntime()->GetDefaultContext()->ThrowNativeError("Tried to override return value without return value being set");
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
g_SHPtr->SetRes(MRES_IGNORED);
|
||||
mres = MRES_IGNORED;
|
||||
break;
|
||||
}
|
||||
|
||||
HandleSecurity sec(dg->plugin_callback->GetParentRuntime()->GetDefaultContext()->GetIdentity(), myself->GetIdentity());
|
||||
|
||||
if(returnStruct)
|
||||
{
|
||||
handlesys->FreeHandle(rHndl, &sec);
|
||||
}
|
||||
if(paramStruct)
|
||||
{
|
||||
handlesys->FreeHandle(pHndl, &sec);
|
||||
}
|
||||
|
||||
if(dg->returnType == ReturnType_Void || mres <= MRES_HANDLED)
|
||||
{
|
||||
*string_result = NULL_STRING;
|
||||
return string_result;
|
||||
}
|
||||
return string_result;
|
||||
}
|
||||
#endif
|
||||
|
19
vhook.h
19
vhook.h
@ -166,6 +166,7 @@ Vector *Callback_vector(DHooksCallback *dg, void **stack, size_t *argsizep);
|
||||
void *Callback(DHooksCallback *dg, void **stack);
|
||||
float Callback_float(DHooksCallback *dg, void **stack);
|
||||
Vector *Callback_vector(DHooksCallback *dg, void **stack);
|
||||
string_t *Callback_stringt(DHooksCallback *dg, void **stack);
|
||||
#endif
|
||||
bool SetupHookManager(ISmmAPI *ismm);
|
||||
void CleanupHooks(IPluginContext *pContext);
|
||||
@ -182,10 +183,20 @@ static void *GenerateThunk(ReturnType type)
|
||||
masm.push(ebp);
|
||||
masm.movl(ebp, esp);
|
||||
masm.subl(esp, kReserve);
|
||||
if(type != ReturnType_String && type != ReturnType_Vector)
|
||||
{
|
||||
masm.lea(eax, Operand(ebp, 12)); // grab the incoming caller argument vector
|
||||
masm.movl(Operand(esp, 1 * 4), eax); // set that as the 2nd argument
|
||||
masm.lea(eax, Operand(ebp, 8)); // grab the |this|
|
||||
masm.movl(Operand(esp, 0 * 4), eax); // set |this| as the 1st argument
|
||||
masm.movl(eax, Operand(ebp, 8)); // grab the |this|
|
||||
masm.movl(Operand(esp, 0 * 4), eax); // set |this| as the 1st argument*/
|
||||
}
|
||||
else
|
||||
{
|
||||
masm.lea(eax, Operand(ebp, 8)); // grab the incoming caller argument vector
|
||||
masm.movl(Operand(esp, 1 * 4), eax); // set that as the 2nd argument
|
||||
masm.movl(eax, Operand(ebp, 12)); // grab the |this|
|
||||
masm.movl(Operand(esp, 0 * 4), eax); // set |this| as the 1st argument*/
|
||||
}
|
||||
if(type == ReturnType_Float)
|
||||
{
|
||||
masm.call(ExternalAddress((void *)Callback_float));
|
||||
@ -194,6 +205,10 @@ static void *GenerateThunk(ReturnType type)
|
||||
{
|
||||
masm.call(ExternalAddress((void *)Callback_vector));
|
||||
}
|
||||
else if(type == ReturnType_String)
|
||||
{
|
||||
masm.call(ExternalAddress((void *)Callback_stringt));
|
||||
}
|
||||
else
|
||||
{
|
||||
masm.call(ExternalAddress((void *)Callback));
|
||||
|
Loading…
Reference in New Issue
Block a user