d2d2578314
--HG-- extra : convert_revision : svn%3A39bc706e-5318-0410-9160-8a85361fbb7c/trunk%402358
197 lines
5.8 KiB
C++
197 lines
5.8 KiB
C++
/**
|
|
* vim: set ts=4 :
|
|
* =============================================================================
|
|
* SourceMod
|
|
* Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved.
|
|
* =============================================================================
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify it under
|
|
* the terms of the GNU General Public License, version 3.0, as published by the
|
|
* Free Software Foundation.
|
|
*
|
|
* This program is distributed in the hope that it will be useful, but WITHOUT
|
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
|
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
|
* details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License along with
|
|
* this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*
|
|
* As a special exception, AlliedModders LLC gives you permission to link the
|
|
* code of this program (as well as its derivative works) to "Half-Life 2," the
|
|
* "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
|
|
* by the Valve Corporation. You must obey the GNU General Public License in
|
|
* all respects for all other code used. Additionally, AlliedModders LLC grants
|
|
* this exception to all derivative works. AlliedModders LLC defines further
|
|
* exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
|
|
* or <http://www.sourcemod.net/license.php>.
|
|
*
|
|
* Version: $Id$
|
|
*/
|
|
|
|
#ifndef _INCLUDE_SOURCEMOD_DETOURS_H_
|
|
#define _INCLUDE_SOURCEMOD_DETOURS_H_
|
|
|
|
#include "extension.h"
|
|
#include <jit/jit_helpers.h>
|
|
#include <jit/x86/x86_macros.h>
|
|
#include "detourhelpers.h"
|
|
|
|
/**
|
|
* CDetours class for SourceMod Extensions by pRED*
|
|
* detourhelpers.h entirely stolen from CSS:DM and were written by BAILOPAN (I assume).
|
|
* asm.h/c from devmaster.net (thanks cybermind)
|
|
*/
|
|
|
|
class CDetourManager;
|
|
|
|
class CDetour
|
|
{
|
|
public:
|
|
|
|
bool IsEnabled();
|
|
|
|
/**
|
|
* These would be somewhat self-explanatory I hope
|
|
*/
|
|
void EnableDetour();
|
|
void DisableDetour();
|
|
|
|
friend class CDetourManager;
|
|
|
|
protected:
|
|
CDetour(void *callbackfunction, size_t paramsize, const char *signame);
|
|
~CDetour();
|
|
|
|
bool Init(ISourcePawnEngine *spengine, IGameConfig *gameconf);
|
|
private:
|
|
|
|
/* These create/delete the allocated memory */
|
|
bool CreateDetour();
|
|
void DeleteDetour();
|
|
|
|
bool enabled;
|
|
bool detoured;
|
|
|
|
patch_t detour_restore;
|
|
void *detour_address;
|
|
void *detour_callback;
|
|
|
|
const char *signame;
|
|
|
|
void *callbackfunction;
|
|
|
|
size_t paramsize;
|
|
|
|
ISourcePawnEngine *spengine;
|
|
IGameConfig *gameconf;
|
|
};
|
|
|
|
class CBlocker
|
|
{
|
|
public:
|
|
void EnableBlock(int returnValue = 0);
|
|
void DisableBlock();
|
|
|
|
friend class CDetourManager;
|
|
|
|
protected:
|
|
CBlocker(const char *signame, bool isVoid);
|
|
~CBlocker();
|
|
|
|
bool Init(ISourcePawnEngine *spengine, IGameConfig *gameconf);
|
|
|
|
private:
|
|
bool isValid;
|
|
bool isEnabled;
|
|
bool isVoid;
|
|
patch_t block_restore;
|
|
void *block_address;
|
|
|
|
const char *block_sig;
|
|
|
|
ISourcePawnEngine *spengine;
|
|
IGameConfig *gameconf;
|
|
};
|
|
|
|
class CDetourManager
|
|
{
|
|
public:
|
|
|
|
/**
|
|
* Return Types for Detours
|
|
*/
|
|
enum DetourReturn
|
|
{
|
|
DetourReturn_Ignored = 0, /** Ignore our result and let the original function run */
|
|
DetourReturn_Override = 1, /** Block the original function from running and use our return value */
|
|
};
|
|
|
|
static void Init(ISourcePawnEngine *spengine, IGameConfig *gameconf);
|
|
|
|
/**
|
|
* Creates a new detour
|
|
* @param callbackfunction Void pointer to your detour callback function. This should be a static function.
|
|
* It should have pointer to the thisptr as the first param and then the same params
|
|
* as the original function. Use void * for unknown types.
|
|
* @param paramsize This is usually the number of params the function has (not including thisptr). If the function
|
|
* passes complex types by value you need to add the sizeof() the type (aligned to 4 bytes).
|
|
* Ie: passing something of size 8 would count as 2 in the param count.
|
|
* @param signame Section name containing a signature to fetch from the gamedata file.
|
|
* @return A new CDetour pointer to control your detour.
|
|
*
|
|
* Example:
|
|
*
|
|
* CBaseServer::ConnectClient(netadr_s &, int, int, int, char const*, char const*, char const*, int)
|
|
*
|
|
* Callback:
|
|
* DetourReturn ConnectClientDetour(void *CBaseServer, void *netaddr_s, int something, int something2, int something3, char const* name, char const* pass, const char* steamcert, int len);
|
|
*
|
|
* Creation:
|
|
* CDetourManager::CreateDetour((void *)&ConnectClientDetour, 8, "ConnectClient");
|
|
*/
|
|
static CDetour *CreateDetour(void *callbackfunction, size_t paramsize, const char *signame);
|
|
|
|
/**
|
|
* Deletes a detour
|
|
*/
|
|
static void DeleteDetour(CDetour *detour);
|
|
|
|
/**
|
|
* Creates a function blocker. This is slightly faster than a detour because it avoids a call.
|
|
*
|
|
* @param signame Section name containing a signature to fetch from the gamedata file.
|
|
* @param isVoid Specifies if the function can return void.
|
|
*/
|
|
static CBlocker *CreateFunctionBlock(const char *signame, bool isVoid);
|
|
|
|
/**
|
|
* Delete a function blocker.
|
|
*/
|
|
static void DeleteFunctionBlock(CBlocker *block);
|
|
|
|
|
|
/**
|
|
* Global DetourReturn value to use for the current hook
|
|
*/
|
|
static int returnValue;
|
|
|
|
friend class CBlocker;
|
|
friend class CDetour;
|
|
|
|
private:
|
|
static ISourcePawnEngine *spengine;
|
|
static IGameConfig *gameconf;
|
|
};
|
|
|
|
typedef bool DetourReturn;
|
|
|
|
#define DETOUR_RESULT_IGNORED false
|
|
#define DETOUR_RESULT_OVERRIDE true
|
|
|
|
#define SET_DETOUR_RETURN_VALUE(value) CDetourManager::returnValue=(int)value
|
|
#define RETURN_DETOUR(result) return result
|
|
#define RETURN_DETOUR_VALUE(result,value) do { SET_DETOUR_RETURN_VALUE(value); return (result); } while(0)
|
|
|
|
#endif // _INCLUDE_SOURCEMOD_DETOURS_H_
|