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