Added Dynamic Hooking to BinTools (bug 2616 r=dvander,DS)
authorMatt Woodrow <pred@alliedmods.net>
Thu Jan 08 18:17:17 2009 +1300 (2009-01-08)
changeset 250474fea7db93e4
parent 2503 602bd1bc1739
child 2505 10b51c8c7896
Added Dynamic Hooking to BinTools (bug 2616 r=dvander,DS)
extensions/bintools/CallMaker.cpp
extensions/bintools/CallMaker.h
extensions/bintools/CallWrapper.cpp
extensions/bintools/CallWrapper.h
extensions/bintools/HookWrapper.cpp
extensions/bintools/HookWrapper.h
extensions/bintools/Makefile
extensions/bintools/extension.cpp
extensions/bintools/jit_call.cpp
extensions/bintools/jit_call.h
extensions/bintools/jit_compile.h
extensions/bintools/jit_hook.cpp
extensions/bintools/msvc9/bintools.sln
extensions/bintools/msvc9/bintools.vcproj
extensions/bintools/sdk/smsdk_config.h
extensions/bintools/sdk/smsdk_ext.cpp
extensions/bintools/sdk/smsdk_ext.h
public/extensions/IBinTools.h
tools/builder/PkgCore.cs
     1.1 --- a/extensions/bintools/CallMaker.cpp	Wed Jan 07 22:55:40 2009 -0500
     1.2 +++ b/extensions/bintools/CallMaker.cpp	Thu Jan 08 18:17:17 2009 +1300
     1.3 @@ -29,9 +29,54 @@
     1.4   * Version: $Id$
     1.5   */
     1.6  
     1.7 +#include <stdio.h>
     1.8  #include "CallMaker.h"
     1.9 -#include "CallWrapper.h"
    1.10 -#include "jit_call.h"
    1.11 +#include "jit_compile.h"
    1.12 +#include "extension.h"
    1.13 +
    1.14 +/* SourceMod <==> SourceHook type conversion functions */
    1.15 +
    1.16 +SourceHook::ProtoInfo::CallConvention GetSHCallConvention(SourceMod::CallConvention cv)
    1.17 +{
    1.18 +	if (cv < SourceMod::CallConv_ThisCall || cv > SourceMod::CallConv_Cdecl)
    1.19 +	{
    1.20 +		return SourceHook::ProtoInfo::CallConv_Unknown;
    1.21 +	}
    1.22 +
    1.23 +	return (SourceHook::ProtoInfo::CallConvention)(cv + 1);
    1.24 +}
    1.25 +
    1.26 +SourceMod::CallConvention GetSMCallConvention(SourceHook::ProtoInfo::CallConvention cv)
    1.27 +{
    1.28 +	assert(cv >= SourceHook::ProtoInfo::CallConv_ThisCall || cv <= SourceHook::ProtoInfo::CallConv_Cdecl);
    1.29 +
    1.30 +	return (SourceMod::CallConvention)(cv - 1);
    1.31 +}
    1.32 +
    1.33 +SourceHook::PassInfo::PassType GetSHPassType(SourceMod::PassType type)
    1.34 +{
    1.35 +	if (type < SourceMod::PassType_Basic || type > SourceMod::PassType_Object)
    1.36 +	{
    1.37 +		return SourceHook::PassInfo::PassType_Unknown;
    1.38 +	}
    1.39 +
    1.40 +	return (SourceHook::PassInfo::PassType)(type + 1);
    1.41 +}
    1.42 +
    1.43 +SourceMod::PassType GetSMPassType(int type)
    1.44 +{
    1.45 +	/* SourceMod doesn't provide an Unknown type so we it must be an error */
    1.46 +	assert(type >= SourceHook::PassInfo::PassType_Basic && type <= SourceHook::PassInfo::PassType_Object);
    1.47 +
    1.48 +	return (SourceMod::PassType)(type - 1);
    1.49 +}
    1.50 +
    1.51 +void GetSMPassInfo(SourceMod::PassInfo *out, const SourceHook::PassInfo *in)
    1.52 +{
    1.53 +	out->size = in->size;
    1.54 +	out->flags = in->flags;
    1.55 +	out->type = GetSMPassType(in->type);
    1.56 +}
    1.57  
    1.58  ICallWrapper *CallMaker::CreateCall(void *address,
    1.59  						 CallConvention cv,
    1.60 @@ -39,12 +84,26 @@
    1.61  						 const PassInfo paramInfo[],
    1.62  						 unsigned int numParams)
    1.63  {
    1.64 -	CallWrapper *pWrapper = new CallWrapper(cv, paramInfo, retInfo, numParams);
    1.65 -	pWrapper->m_Addrs[ADDR_CALLEE] = address;
    1.66 +	SourceHook::CProtoInfoBuilder protoInfo(GetSHCallConvention(cv));
    1.67 +
    1.68 +	for (unsigned int i=0; i<numParams; i++)
    1.69 +	{
    1.70 +		protoInfo.AddParam(paramInfo[i].size, GetSHPassType(paramInfo[i].type), paramInfo[i].flags,
    1.71 +			NULL, NULL, NULL, NULL);
    1.72 +	}
    1.73  
    1.74 -	JIT_Compile(pWrapper, FuncAddr_Direct);
    1.75 +	if (retInfo)
    1.76 +	{
    1.77 +		protoInfo.SetReturnType(retInfo->size, GetSHPassType(retInfo->type), retInfo->flags,
    1.78 +			NULL, NULL, NULL, NULL);
    1.79 +	}
    1.80 +	else
    1.81 +	{
    1.82 +		protoInfo.SetReturnType(0, SourceHook::PassInfo::PassType_Unknown, 0,
    1.83 +			NULL, NULL, NULL, NULL);
    1.84 +	}
    1.85  
    1.86 -	return pWrapper;
    1.87 +	return g_CallMaker2.CreateCall(address, &(*protoInfo));
    1.88  }
    1.89  
    1.90  ICallWrapper *CallMaker::CreateVCall(unsigned int vtblIdx, 
    1.91 @@ -54,12 +113,73 @@
    1.92  									 const PassInfo paramInfo[], 
    1.93  									 unsigned int numParams)
    1.94  {
    1.95 -	CallWrapper *pWrapper = new CallWrapper(CallConv_ThisCall, paramInfo, retInfo, numParams);
    1.96 -	pWrapper->m_VtInfo.thisOffs = thisOffs;
    1.97 -	pWrapper->m_VtInfo.vtblIdx = vtblIdx;
    1.98 -	pWrapper->m_VtInfo.vtblOffs = vtblOffs;
    1.99 +	SourceHook::MemFuncInfo info;
   1.100 +	info.isVirtual = true;
   1.101 +	info.vtblindex = vtblIdx;
   1.102 +	info.vtbloffs = vtblOffs;
   1.103 +	info.thisptroffs = thisOffs;
   1.104 +
   1.105 +	SourceHook::CProtoInfoBuilder protoInfo(SourceHook::ProtoInfo::CallConv_ThisCall);
   1.106 +
   1.107 +	for (unsigned int i=0; i<numParams; i++)
   1.108 +	{
   1.109 +		protoInfo.AddParam(paramInfo[i].size, GetSHPassType(paramInfo[i].type), paramInfo[i].flags,
   1.110 +			NULL, NULL, NULL, NULL);
   1.111 +	}
   1.112  
   1.113 -	JIT_Compile(pWrapper, FuncAddr_VTable);
   1.114 +	if (retInfo)
   1.115 +	{
   1.116 +		protoInfo.SetReturnType(retInfo->size, GetSHPassType(retInfo->type), retInfo->flags,
   1.117 +			NULL, NULL, NULL, NULL);
   1.118 +	}
   1.119 +	else
   1.120 +	{
   1.121 +		protoInfo.SetReturnType(0, SourceHook::PassInfo::PassType_Unknown, 0,
   1.122 +			NULL, NULL, NULL, NULL);
   1.123 +	}
   1.124 +	
   1.125 +
   1.126 +	return g_CallMaker2.CreateVirtualCall(&(*protoInfo), &info);
   1.127 +}
   1.128 +
   1.129 +ICallWrapper *CallMaker2::CreateCall(void *address, const SourceHook::ProtoInfo *protoInfo)
   1.130 +{
   1.131 +	CallWrapper *pWrapper = new CallWrapper(protoInfo);
   1.132 +	pWrapper->SetCalleeAddr(address);
   1.133 +
   1.134 +	void *addr = JIT_CallCompile(pWrapper, FuncAddr_Direct);
   1.135 +	pWrapper->SetCodeBaseAddr(addr);
   1.136  
   1.137  	return pWrapper;
   1.138  }
   1.139 +
   1.140 +ICallWrapper *CallMaker2::CreateVirtualCall(const SourceHook::ProtoInfo *protoInfo, 
   1.141 +											const SourceHook::MemFuncInfo *info)
   1.142 +{
   1.143 +	CallWrapper *pWrapper = new CallWrapper(protoInfo);
   1.144 +	pWrapper->SetMemFuncInfo(info);
   1.145 +
   1.146 +	void *addr = JIT_CallCompile(pWrapper, FuncAddr_VTable);
   1.147 +	pWrapper->SetCodeBaseAddr(addr);
   1.148 +
   1.149 +	return pWrapper;
   1.150 +}
   1.151 +
   1.152 +#if defined HOOKING_ENABLED
   1.153 +IHookWrapper *CallMaker2::CreateVirtualHook(SourceHook::ISourceHook *pSH, 
   1.154 +											const SourceHook::ProtoInfo *protoInfo,
   1.155 +											const SourceHook::MemFuncInfo *info, 
   1.156 +											VIRTUAL_HOOK_PROTO f)
   1.157 +{
   1.158 +	HookWrapper *pWrapper = new HookWrapper(pSH, protoInfo, const_cast<SourceHook::MemFuncInfo *>(info), (void *)f);
   1.159 +
   1.160 +	void *addr = JIT_HookCompile(pWrapper);
   1.161 +	pWrapper->SetHookWrpAddr(addr);
   1.162 +
   1.163 +	ICallWrapper *callWrap = CreateVirtualCall(protoInfo, info);
   1.164 +	pWrapper->SetCallWrapperAddr(callWrap);
   1.165 +	
   1.166 +	return pWrapper;
   1.167 +}
   1.168 +#endif
   1.169 +
     2.1 --- a/extensions/bintools/CallMaker.h	Wed Jan 07 22:55:40 2009 -0500
     2.2 +++ b/extensions/bintools/CallMaker.h	Thu Jan 08 18:17:17 2009 +1300
     2.3 @@ -32,16 +32,12 @@
     2.4  #ifndef _INCLUDE_SOURCEMOD_CALLMAKER_H_
     2.5  #define _INCLUDE_SOURCEMOD_CALLMAKER_H_
     2.6  
     2.7 -#include <IBinTools.h>
     2.8 +
     2.9 +#include "CallWrapper.h"
    2.10 +#include "HookWrapper.h"
    2.11  
    2.12  using namespace SourceMod;
    2.13  
    2.14 -enum FuncAddrMethod
    2.15 -{
    2.16 -	FuncAddr_Direct,
    2.17 -	FuncAddr_VTable
    2.18 -};
    2.19 -
    2.20  class CallMaker : public IBinTools
    2.21  {
    2.22  public: //IBinTools
    2.23 @@ -58,4 +54,32 @@
    2.24  		unsigned int numParams);
    2.25  };
    2.26  
    2.27 +class CallMaker2 
    2.28 +#if defined HOOKING_ENABLED
    2.29 +	: public IBinTools2
    2.30 +#endif
    2.31 +{
    2.32 +public: //IBinTools2
    2.33 +	virtual ICallWrapper *CreateCall(void *address,
    2.34 +		const SourceHook::ProtoInfo *protoInfo);
    2.35 +	virtual ICallWrapper *CreateVirtualCall(const SourceHook::ProtoInfo *protoInfo,
    2.36 +		const SourceHook::MemFuncInfo *info);
    2.37 +#if defined HOOKING_ENABLED
    2.38 +	virtual IHookWrapper *CreateVirtualHook(SourceHook::ISourceHook *pSH, 
    2.39 +		const SourceHook::ProtoInfo *protoInfo, 
    2.40 +		const SourceHook::MemFuncInfo *info, 
    2.41 +		VIRTUAL_HOOK_PROTO f);
    2.42 +#endif
    2.43 +};
    2.44 +
    2.45 +extern CallMaker2 g_CallMaker2;
    2.46 +
    2.47 +SourceHook::ProtoInfo::CallConvention GetSHCallConvention(SourceMod::CallConvention cv);
    2.48 +SourceMod::CallConvention GetSMCallConvention(SourceHook::ProtoInfo::CallConvention cv);
    2.49 +SourceHook::PassInfo::PassType GetSHPassType(SourceMod::PassType type);
    2.50 +SourceMod::PassType GetSMPassType(int type);
    2.51 +void GetSMPassInfo(SourceMod::PassInfo *out, const SourceHook::PassInfo *in);
    2.52 +
    2.53 +
    2.54 +
    2.55  #endif //_INCLUDE_SOURCEMOD_CALLMAKER_H_
     3.1 --- a/extensions/bintools/CallWrapper.cpp	Wed Jan 07 22:55:40 2009 -0500
     3.2 +++ b/extensions/bintools/CallWrapper.cpp	Thu Jan 08 18:17:17 2009 +1300
     3.3 @@ -31,40 +31,46 @@
     3.4  
     3.5  #include "extension.h"
     3.6  #include "CallWrapper.h"
     3.7 +#include "CallMaker.h"
     3.8  
     3.9 -CallWrapper::CallWrapper(CallConvention cv, const PassInfo *paramInfo, const PassInfo *retInfo, unsigned int numParams)
    3.10 +CallWrapper::CallWrapper(const SourceHook::ProtoInfo *protoInfo)
    3.11  {
    3.12 -	m_Cv = cv;
    3.13 +	m_AddrCodeBase = NULL;
    3.14 +	m_AddrCallee = NULL;
    3.15 +
    3.16 +	unsigned int argnum = protoInfo->numOfParams;
    3.17  
    3.18 -	if (numParams)
    3.19 +	m_Info = *protoInfo;
    3.20 +	m_Info.paramsPassInfo = new SourceHook::PassInfo[argnum + 1];
    3.21 +	memcpy((void *)m_Info.paramsPassInfo, protoInfo->paramsPassInfo, sizeof(SourceHook::PassInfo) * (argnum+1));
    3.22 +
    3.23 +	if (argnum)
    3.24  	{
    3.25 -		m_Params = new PassEncode[numParams];
    3.26 -		for (size_t i=0; i<numParams; i++)
    3.27 +		m_Params = new PassEncode[argnum];
    3.28 +		for (size_t i=0; i<argnum; i++)
    3.29  		{
    3.30 -			m_Params[i].info = paramInfo[i];
    3.31 +			GetSMPassInfo(&(m_Params[i].info), &(m_Info.paramsPassInfo[i+1]));
    3.32  		}
    3.33  	} else {
    3.34  		m_Params = NULL;
    3.35  	}
    3.36  
    3.37 -	if (retInfo)
    3.38 +	if (m_Info.retPassInfo.size != 0)
    3.39  	{
    3.40  		m_RetParam = new PassInfo;
    3.41 -		*m_RetParam = *retInfo;
    3.42 +		GetSMPassInfo(m_RetParam, &(m_Info.retPassInfo));
    3.43  	} else {
    3.44  		m_RetParam = NULL;
    3.45  	}
    3.46  
    3.47 -	m_NumParams = numParams;
    3.48 -
    3.49  	/* Calculate virtual stack offsets for each parameter */
    3.50  	size_t offs = 0;
    3.51  
    3.52 -	if (cv == CallConv_ThisCall)
    3.53 +	if (m_Info.convention == SourceHook::ProtoInfo::CallConv_ThisCall)
    3.54  	{
    3.55  		offs += sizeof(void *);
    3.56  	}
    3.57 -	for (size_t i=0; i<numParams; i++)
    3.58 +	for (size_t i=0; i<argnum; i++)
    3.59  	{
    3.60  		m_Params[i].offset = offs;
    3.61  		offs += m_Params[i].info.size;
    3.62 @@ -75,22 +81,34 @@
    3.63  {
    3.64  	delete [] m_Params;
    3.65  	delete m_RetParam;
    3.66 -	g_SPEngine->FreePageMemory(m_Addrs[ADDR_CODEBASE]);
    3.67 +	delete [] m_Info.paramsPassInfo;
    3.68  }
    3.69  
    3.70  void CallWrapper::Destroy()
    3.71  {
    3.72 +	if (m_AddrCodeBase != NULL)
    3.73 +	{
    3.74 +		g_SPEngine->FreePageMemory(m_AddrCodeBase);
    3.75 +		m_AddrCodeBase = NULL;
    3.76 +	}
    3.77 +
    3.78  	delete this;
    3.79  }
    3.80  
    3.81  CallConvention CallWrapper::GetCallConvention()
    3.82  {
    3.83 -	return m_Cv;
    3.84 +	/* Need to convert to a SourceMod convention for bcompat */
    3.85 +	return GetSMCallConvention((SourceHook::ProtoInfo::CallConvention)m_Info.convention);
    3.86  }
    3.87  
    3.88  const PassEncode *CallWrapper::GetParamInfo(unsigned int num)
    3.89  {
    3.90 -	return (num+1 > m_NumParams) ? NULL : &m_Params[num];
    3.91 +	if (num + 1 > GetParamCount() || num < 0)
    3.92 +	{
    3.93 +		return NULL;
    3.94 +	}
    3.95 +
    3.96 +	return &m_Params[num];
    3.97  }
    3.98  
    3.99  const PassInfo *CallWrapper::GetReturnInfo()
   3.100 @@ -100,12 +118,69 @@
   3.101  
   3.102  unsigned int CallWrapper::GetParamCount()
   3.103  {
   3.104 -	return m_NumParams;
   3.105 +	return m_Info.numOfParams;
   3.106  }
   3.107  
   3.108  void CallWrapper::Execute(void *vParamStack, void *retBuffer)
   3.109  {
   3.110  	typedef void (*CALL_EXECUTE)(void *, void *);
   3.111 -	CALL_EXECUTE fn = (CALL_EXECUTE)m_Addrs[ADDR_CODEBASE];
   3.112 +	CALL_EXECUTE fn = (CALL_EXECUTE)GetCodeBaseAddr();
   3.113  	fn(vParamStack, retBuffer);
   3.114  }
   3.115 +
   3.116 +void CallWrapper::SetMemFuncInfo(const SourceHook::MemFuncInfo *funcInfo)
   3.117 +{
   3.118 +	m_FuncInfo = *funcInfo;
   3.119 +}
   3.120 +
   3.121 +SourceHook::MemFuncInfo *CallWrapper::GetMemFuncInfo()
   3.122 +{
   3.123 +	return &m_FuncInfo;
   3.124 +}
   3.125 +
   3.126 +void CallWrapper::SetCalleeAddr(void *addr)
   3.127 +{
   3.128 +	m_AddrCallee = addr;
   3.129 +}
   3.130 +
   3.131 +void CallWrapper::SetCodeBaseAddr(void *addr)
   3.132 +{
   3.133 +	m_AddrCodeBase = addr;
   3.134 +}
   3.135 +
   3.136 +void *CallWrapper::GetCalleeAddr()
   3.137 +{
   3.138 +	return m_AddrCallee;
   3.139 +}
   3.140 +
   3.141 +void *CallWrapper::GetCodeBaseAddr()
   3.142 +{
   3.143 +	return m_AddrCodeBase;
   3.144 +}
   3.145 +
   3.146 +const SourceHook::PassInfo *CallWrapper::GetSHReturnInfo()
   3.147 +{
   3.148 +	return &(m_Info.retPassInfo);
   3.149 +}
   3.150 +
   3.151 +SourceHook::ProtoInfo::CallConvention CallWrapper::GetSHCallConvention()
   3.152 +{
   3.153 +	return (SourceHook::ProtoInfo::CallConvention)m_Info.convention;
   3.154 +}
   3.155 +
   3.156 +const SourceHook::PassInfo * CallWrapper::GetSHParamInfo(unsigned int num)
   3.157 +{
   3.158 +	if (num + 1 > GetParamCount() || num < 0)
   3.159 +	{
   3.160 +		return NULL;
   3.161 +	}
   3.162 +
   3.163 +	return &(m_Info.paramsPassInfo[num+1]);
   3.164 +}
   3.165 +
   3.166 +unsigned int CallWrapper::GetParamOffset(unsigned int num)
   3.167 +{
   3.168 +	assert(num <= GetParamCount() && num > 0);
   3.169 +
   3.170 +	return m_Params[num].offset;
   3.171 +}
     4.1 --- a/extensions/bintools/CallWrapper.h	Wed Jan 07 22:55:40 2009 -0500
     4.2 +++ b/extensions/bintools/CallWrapper.h	Thu Jan 08 18:17:17 2009 +1300
     4.3 @@ -29,27 +29,24 @@
     4.4   * Version: $Id$
     4.5   */
     4.6  
     4.7 -#ifndef _INCLUDE_SOURCEMOD_CCALLWRAPPER_H_
     4.8 -#define _INCLUDE_SOURCEMOD_CCALLWRAPPER_H_
     4.9 +#ifndef _INCLUDE_SOURCEMOD_CALLWRAPPER_H_
    4.10 +#define _INCLUDE_SOURCEMOD_CALLWRAPPER_H_
    4.11  
    4.12  #include <IBinTools.h>
    4.13 +#include <sourcehook_pibuilder.h>
    4.14  
    4.15  using namespace SourceMod;
    4.16  
    4.17 -#define ADDR_CALLEE			0
    4.18 -#define ADDR_CODEBASE		1
    4.19 -
    4.20 -struct VtableInfo 
    4.21 +enum FuncAddrMethod
    4.22  {
    4.23 -	unsigned int vtblIdx;
    4.24 -	unsigned int vtblOffs;
    4.25 -	unsigned int thisOffs;
    4.26 +	FuncAddr_Direct,
    4.27 +	FuncAddr_VTable
    4.28  };
    4.29  
    4.30  class CallWrapper : public ICallWrapper
    4.31  {
    4.32  public:
    4.33 -	CallWrapper(CallConvention cv, const PassInfo *paramInfo, const PassInfo *retInfo, unsigned int numParams);
    4.34 +	CallWrapper(const SourceHook::ProtoInfo *protoInfo);
    4.35  	~CallWrapper();
    4.36  public: //ICallWrapper
    4.37  	CallConvention GetCallConvention();
    4.38 @@ -58,15 +55,25 @@
    4.39  	unsigned int GetParamCount();
    4.40  	void Execute(void *vParamStack, void *retBuffer);
    4.41  	void Destroy();
    4.42 +	const SourceHook::PassInfo *GetSHReturnInfo();
    4.43 +	SourceHook::ProtoInfo::CallConvention GetSHCallConvention();
    4.44 +	const SourceHook::PassInfo *GetSHParamInfo(unsigned int num);
    4.45 +	unsigned int GetParamOffset(unsigned int num);
    4.46  public:
    4.47 -	inline void deleteThis() { delete this; }
    4.48 -	void *m_Addrs[4];
    4.49 -	VtableInfo m_VtInfo;
    4.50 +	void SetCalleeAddr(void *addr);
    4.51 +	void SetCodeBaseAddr(void *addr);
    4.52 +	void *GetCalleeAddr();
    4.53 +	void *GetCodeBaseAddr();
    4.54 +
    4.55 +	void SetMemFuncInfo(const SourceHook::MemFuncInfo *funcInfo);
    4.56 +	SourceHook::MemFuncInfo *GetMemFuncInfo();
    4.57  private:
    4.58 -	CallConvention m_Cv;
    4.59  	PassEncode *m_Params;
    4.60 +	SourceHook::ProtoInfo m_Info;
    4.61  	PassInfo *m_RetParam;
    4.62 -	unsigned int m_NumParams;
    4.63 +	void *m_AddrCallee;
    4.64 +	void *m_AddrCodeBase;
    4.65 +	SourceHook::MemFuncInfo m_FuncInfo;
    4.66  };
    4.67  
    4.68 -#endif //_INCLUDE_SOURCEMOD_CCALLWRAPPER_H_
    4.69 +#endif //_INCLUDE_SOURCEMOD_CALLWRAPPER_H_
     5.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     5.2 +++ b/extensions/bintools/HookWrapper.cpp	Thu Jan 08 18:17:17 2009 +1300
     5.3 @@ -0,0 +1,243 @@
     5.4 +/**
     5.5 + * vim: set ts=4 :
     5.6 + * =============================================================================
     5.7 + * SourceMod BinTools Extension
     5.8 + * Copyright (C) 2004-2008 AlliedModders LLC.  All rights reserved.
     5.9 + * =============================================================================
    5.10 + *
    5.11 + * This program is free software; you can redistribute it and/or modify it under
    5.12 + * the terms of the GNU General Public License, version 3.0, as published by the
    5.13 + * Free Software Foundation.
    5.14 + * 
    5.15 + * This program is distributed in the hope that it will be useful, but WITHOUT
    5.16 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
    5.17 + * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
    5.18 + * details.
    5.19 + *
    5.20 + * You should have received a copy of the GNU General Public License along with
    5.21 + * this program.  If not, see <http://www.gnu.org/licenses/>.
    5.22 + *
    5.23 + * As a special exception, AlliedModders LLC gives you permission to link the
    5.24 + * code of this program (as well as its derivative works) to "Half-Life 2," the
    5.25 + * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
    5.26 + * by the Valve Corporation.  You must obey the GNU General Public License in
    5.27 + * all respects for all other code used.  Additionally, AlliedModders LLC grants
    5.28 + * this exception to all derivative works.  AlliedModders LLC defines further
    5.29 + * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
    5.30 + * or <http://www.sourcemod.net/license.php>.
    5.31 + *
    5.32 + * Version: $Id: CallMaker.h 1964 2008-03-27 04:54:56Z damagedsoul $
    5.33 + */
    5.34 +
    5.35 +#if defined HOOKING_ENABLED
    5.36 +
    5.37 +#include "HookWrapper.h"
    5.38 +#include "jit_compile.h"
    5.39 +
    5.40 +/******************************
    5.41 + * HookWrapper Implementation *
    5.42 + ******************************/
    5.43 +
    5.44 +HookWrapper::HookWrapper(SourceHook::ISourceHook *pSH, 
    5.45 +						 const SourceHook::ProtoInfo *proto, 
    5.46 +						 SourceHook::MemFuncInfo *memfunc, 
    5.47 +						 void *addr) : m_ParamOffs(NULL), m_ParamSize(0), m_RetSize(0)
    5.48 +{
    5.49 +	unsigned int argnum = proto->numOfParams;
    5.50 +
    5.51 +	m_pSH = pSH;
    5.52 +	m_ProtoInfo = *proto;
    5.53 +	m_ProtoInfo.paramsPassInfo = new SourceHook::PassInfo[argnum + 1];
    5.54 +	memcpy((void *)m_ProtoInfo.paramsPassInfo, proto->paramsPassInfo, sizeof(SourceHook::PassInfo) * (argnum+1));
    5.55 +	m_MemFuncInfo = *memfunc;
    5.56 +	m_FuncAddr = addr;
    5.57 +	m_HookWrapper = NULL;
    5.58 +
    5.59 +	/* If the function has parameters calculate the parameter buffer size and offsets */
    5.60 +	if (argnum > 0)
    5.61 +	{
    5.62 +		const SourceHook::PassInfo *info = m_ProtoInfo.paramsPassInfo;
    5.63 +		m_ParamOffs = new unsigned int[argnum];
    5.64 +		m_ParamOffs[0] = 0;
    5.65 +
    5.66 +		for (unsigned int i=1; i<=argnum; i++)
    5.67 +		{
    5.68 +			/* The stack should be at least aligned to a 4 byte boundary 
    5.69 +			* and byref params have the size of pointers 
    5.70 +			*/
    5.71 +			if (((info[i].type == SourceHook::PassInfo::PassType_Basic) &&
    5.72 +				(info[i].flags & SourceHook::PassInfo::PassFlag_ByVal) && 
    5.73 +				(info[i].size < sizeof(void *))) ||
    5.74 +				(info[i].flags & SourceHook::PassInfo::PassFlag_ByRef))
    5.75 +			{
    5.76 +				m_ParamSize += sizeof(void *);
    5.77 +			}
    5.78 +			else
    5.79 +			{
    5.80 +				m_ParamSize += info[i].size;
    5.81 +			}
    5.82 +
    5.83 +			//:TODO: fix this!
    5.84 +			if (i < argnum)
    5.85 +			{
    5.86 +				m_ParamOffs[i] = m_ParamSize;
    5.87 +			}
    5.88 +		}
    5.89 +	}
    5.90 +
    5.91 +	/* Finally calculate the retval size if any */
    5.92 +	size_t retsize = m_ProtoInfo.retPassInfo.size;
    5.93 +	if (retsize != 0)
    5.94 +	{
    5.95 +		if (m_ProtoInfo.retPassInfo.flags & SourceHook::PassInfo::PassFlag_ByRef)
    5.96 +		{
    5.97 +			m_RetSize = sizeof(void *);
    5.98 +		}
    5.99 +		else
   5.100 +		{
   5.101 +			m_RetSize = (retsize < sizeof(void *)) ? sizeof(void *) : retsize;
   5.102 +		}
   5.103 +	}
   5.104 +}
   5.105 +
   5.106 +ISMDelegate *HookWrapper::CreateDelegate(void *data)
   5.107 +{
   5.108 +	SMDelegate *pDeleg = new SMDelegate(data);
   5.109 +	pDeleg->PatchVtable(m_HookWrapper);
   5.110 +
   5.111 +	return pDeleg;
   5.112 +}
   5.113 +
   5.114 +unsigned int HookWrapper::GetParamCount()
   5.115 +{
   5.116 +	return m_ProtoInfo.numOfParams;
   5.117 +}
   5.118 +
   5.119 +unsigned int HookWrapper::GetParamOffset(unsigned int argnum, unsigned int *size)
   5.120 +{
   5.121 +	assert(m_ParamOffs && argnum < (unsigned int)m_ProtoInfo.numOfParams);
   5.122 +
   5.123 +	if (size)
   5.124 +	{
   5.125 +		*size = m_ProtoInfo.paramsPassInfo[argnum+1].size;
   5.126 +	}
   5.127 +
   5.128 +	return m_ParamOffs[argnum];
   5.129 +}
   5.130 +
   5.131 +void HookWrapper::PerformRecall(void *params, void *retval)
   5.132 +{
   5.133 +	/* Notify SourceHook of the upcoming recall */
   5.134 +	SH_GLOB_SHPTR->DoRecall();
   5.135 +
   5.136 +	/* Add thisptr into params buffer */
   5.137 +	unsigned char *newparams = new unsigned char[sizeof(void *) + m_ParamSize];
   5.138 +	*(void **)newparams = META_IFACEPTR(void);
   5.139 +	memcpy(newparams + sizeof(void *), params, m_ParamSize);
   5.140 +
   5.141 +	/* Execute the call */
   5.142 +	m_CallWrapper->Execute(newparams, retval);
   5.143 +
   5.144 +	SET_META_RESULT(MRES_SUPERCEDE);
   5.145 +
   5.146 +	return;
   5.147 +}
   5.148 +
   5.149 +void HookWrapper::Destroy()
   5.150 +{
   5.151 +	if (m_HookWrapper != NULL)
   5.152 +	{
   5.153 +		JIT_FreeHook(m_HookWrapper);
   5.154 +	}
   5.155 +
   5.156 +	if (m_CallWrapper != NULL)
   5.157 +	{
   5.158 +		m_CallWrapper->Destroy();
   5.159 +	}
   5.160 +
   5.161 +	delete this;
   5.162 +}
   5.163 +
   5.164 +unsigned int HookWrapper::GetParamSize()
   5.165 +{
   5.166 +	return m_ParamSize;
   5.167 +}
   5.168 +
   5.169 +SourceHook::ProtoInfo * HookWrapper::GetProtoInfo()
   5.170 +{
   5.171 +	return &m_ProtoInfo;
   5.172 +}
   5.173 +
   5.174 +unsigned int HookWrapper::GetRetSize()
   5.175 +{
   5.176 +	return m_RetSize;
   5.177 +}
   5.178 +
   5.179 +void * HookWrapper::GetHandlerAddr()
   5.180 +{
   5.181 +	return m_FuncAddr;
   5.182 +}
   5.183 +
   5.184 +void HookWrapper::SetCallWrapperAddr( ICallWrapper *wrap )
   5.185 +{
   5.186 +	m_CallWrapper = wrap;
   5.187 +}
   5.188 +
   5.189 +void HookWrapper::SetHookWrpAddr( void *addr )
   5.190 +{
   5.191 +	m_HookWrapper = addr;
   5.192 +}
   5.193 +
   5.194 +HookWrapper::~HookWrapper()
   5.195 +{
   5.196 +	delete [] m_ProtoInfo.paramsPassInfo;
   5.197 +	delete [] m_ParamOffs;
   5.198 +}
   5.199 +/*****************************
   5.200 + * SMDelegate Implementation *
   5.201 + *****************************/
   5.202 +
   5.203 +SMDelegate::SMDelegate(void *data)
   5.204 +{
   5.205 +	m_Data = data;
   5.206 +}
   5.207 +
   5.208 +bool SMDelegate::IsEqual(ISHDelegate *pOtherDeleg)
   5.209 +{
   5.210 +	return false;
   5.211 +}
   5.212 +
   5.213 +void SMDelegate::DeleteThis()
   5.214 +{
   5.215 +	/* Remove our allocated vtable */
   5.216 +	delete [] *reinterpret_cast<void ***>(this);
   5.217 +
   5.218 +	delete this;
   5.219 +}
   5.220 +
   5.221 +void SMDelegate::Call()
   5.222 +{
   5.223 +}
   5.224 +
   5.225 +void *SMDelegate::GetUserData()
   5.226 +{
   5.227 +	return m_Data;
   5.228 +}
   5.229 +
   5.230 +/** 
   5.231 + * This duplicates the vtable (so each instance has a unique table) and patches SMDelgate::Call to point to our allocated function 
   5.232 + */
   5.233 +void SMDelegate::PatchVtable(void *addr)
   5.234 +{
   5.235 +	void **new_vtptr = new void *[4];
   5.236 +	void **cur_vtptr = *reinterpret_cast<void ***>(this);
   5.237 +	memcpy(new_vtptr, cur_vtptr, sizeof(void *)*4);
   5.238 +
   5.239 +	*reinterpret_cast<void ***>(this) = new_vtptr;
   5.240 +
   5.241 +	void *cur_vfnptr = reinterpret_cast<void *>(new_vtptr + VTABLE_PATCH_OFFS);
   5.242 +
   5.243 +	*reinterpret_cast<void **>(cur_vfnptr) = addr;
   5.244 +}
   5.245 +
   5.246 +#endif
     6.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     6.2 +++ b/extensions/bintools/HookWrapper.h	Thu Jan 08 18:17:17 2009 +1300
     6.3 @@ -0,0 +1,97 @@
     6.4 +/**
     6.5 + * vim: set ts=4 :
     6.6 + * =============================================================================
     6.7 + * SourceMod BinTools Extension
     6.8 + * Copyright (C) 2004-2008 AlliedModders LLC.  All rights reserved.
     6.9 + * =============================================================================
    6.10 + *
    6.11 + * This program is free software; you can redistribute it and/or modify it under
    6.12 + * the terms of the GNU General Public License, version 3.0, as published by the
    6.13 + * Free Software Foundation.
    6.14 + * 
    6.15 + * This program is distributed in the hope that it will be useful, but WITHOUT
    6.16 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
    6.17 + * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
    6.18 + * details.
    6.19 + *
    6.20 + * You should have received a copy of the GNU General Public License along with
    6.21 + * this program.  If not, see <http://www.gnu.org/licenses/>.
    6.22 + *
    6.23 + * As a special exception, AlliedModders LLC gives you permission to link the
    6.24 + * code of this program (as well as its derivative works) to "Half-Life 2," the
    6.25 + * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
    6.26 + * by the Valve Corporation.  You must obey the GNU General Public License in
    6.27 + * all respects for all other code used.  Additionally, AlliedModders LLC grants
    6.28 + * this exception to all derivative works.  AlliedModders LLC defines further
    6.29 + * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
    6.30 + * or <http://www.sourcemod.net/license.php>.
    6.31 + *
    6.32 + * Version: $Id: CallMaker.h 1964 2008-03-27 04:54:56Z damagedsoul $
    6.33 + */
    6.34 +
    6.35 +#ifndef _INCLUDE_SOURCEMOD_HOOKWRAPPER_H_
    6.36 +#define _INCLUDE_SOURCEMOD_HOOKWRAPPER_H_
    6.37 +
    6.38 +#if defined HOOKING_ENABLED
    6.39 +
    6.40 +#include "smsdk_ext.h"
    6.41 +#include "sourcehook.h"
    6.42 +#include "IBinTools.h"
    6.43 +
    6.44 +#define VTABLE_PATCH_OFFS		2
    6.45 +
    6.46 +using namespace SourceMod;
    6.47 +
    6.48 +class HookWrapper : public IHookWrapper
    6.49 +{
    6.50 +public:
    6.51 +	HookWrapper(SourceHook::ISourceHook *pSH, 
    6.52 +				const SourceHook::ProtoInfo *proto, 
    6.53 +				SourceHook::MemFuncInfo *memfunc, 
    6.54 +				void *addr
    6.55 +				);
    6.56 +	~HookWrapper();
    6.57 +public: //IHookWrapper
    6.58 +	ISMDelegate *CreateDelegate(void *data);
    6.59 +	unsigned int GetParamCount();
    6.60 +	unsigned int GetParamOffset(unsigned int argnum, unsigned int *size);
    6.61 +	void PerformRecall(void *params, void *retval);
    6.62 +	void Destroy();
    6.63 +public:
    6.64 +	unsigned int GetParamSize();
    6.65 +	unsigned int GetRetSize();
    6.66 +	SourceHook::ProtoInfo *GetProtoInfo();
    6.67 +	void *GetHandlerAddr();
    6.68 +	void SetHookWrpAddr(void *addr);
    6.69 +	void SetCallWrapperAddr(ICallWrapper *wrap);
    6.70 +private:
    6.71 +	void *m_FuncAddr;
    6.72 +	void *m_HookWrapper;
    6.73 +	SourceHook::ISourceHook *m_pSH;
    6.74 +	unsigned int *m_ParamOffs;
    6.75 +	unsigned int m_ParamSize;
    6.76 +	unsigned int m_RetSize;
    6.77 +	SourceHook::MemFuncInfo m_MemFuncInfo;
    6.78 +	SourceHook::ProtoInfo m_ProtoInfo;
    6.79 +	ICallWrapper *m_CallWrapper;
    6.80 +};
    6.81 +
    6.82 +class SMDelegate : public ISMDelegate
    6.83 +{
    6.84 +public:
    6.85 +	SMDelegate(void *data);
    6.86 +public: //SourceHook::ISHDelegate
    6.87 +	bool IsEqual(ISHDelegate *pOtherDeleg);
    6.88 +	void DeleteThis();
    6.89 +	void Call();
    6.90 +public: //ISMDelegate
    6.91 +	void *GetUserData();
    6.92 +public:
    6.93 +	void PatchVtable(void *addr);
    6.94 +private:
    6.95 +	void *m_Data;
    6.96 +};
    6.97 +
    6.98 +#endif
    6.99 +
   6.100 +#endif //_INCLUDE_SOURCEMOD_HOOKWRAPPER_H_
     7.1 --- a/extensions/bintools/Makefile	Wed Jan 07 22:55:40 2009 -0500
     7.2 +++ b/extensions/bintools/Makefile	Thu Jan 08 18:17:17 2009 +1300
     7.3 @@ -14,10 +14,7 @@
     7.4  
     7.5  PROJECT = bintools
     7.6  
     7.7 -#Uncomment for Metamod: Source enabled extension
     7.8 -#USEMETA = true
     7.9 -
    7.10 -OBJECTS = sdk/smsdk_ext.cpp extension.cpp jit_call.cpp CallWrapper.cpp CallMaker.cpp
    7.11 +OBJECTS = sdk/smsdk_ext.cpp extension.cpp jit_call.cpp CallWrapper.cpp CallMaker.cpp HookWrapper.cpp jit_hook.cpp
    7.12  
    7.13  ##############################################
    7.14  ### CONFIGURE ANY OTHER FLAGS/OPTIONS HERE ###
    7.15 @@ -49,6 +46,8 @@
    7.16  	INCLUDE += -I$(HL2SDK)/public/game/server
    7.17  	SRCDS = $(SRCDS_BASE)/orangebox
    7.18  	override ENGSET = true
    7.19 +	USEMETA = true
    7.20 +	CFLAGS += -DHOOKING_ENABLED
    7.21  endif
    7.22  ifeq "$(ENGINE)" "left4dead"
    7.23  	HL2SDK = $(HL2SDK_L4D)
    7.24 @@ -59,6 +58,8 @@
    7.25  	INCLUDE += -I$(HL2SDK)/public/game/server
    7.26  	SRCDS = $(SRCDS_BASE)/l4d
    7.27  	override ENGSET = true
    7.28 +	USEMETA = true
    7.29 +	CFLAGS += -DHOOKING_ENABLED
    7.30  endif
    7.31  
    7.32  ifeq "$(USEMETA)" "true"
     8.1 --- a/extensions/bintools/extension.cpp	Wed Jan 07 22:55:40 2009 -0500
     8.2 +++ b/extensions/bintools/extension.cpp	Thu Jan 08 18:17:17 2009 +1300
     8.3 @@ -39,6 +39,7 @@
     8.4  
     8.5  BinTools g_BinTools;		/**< Global singleton for extension's main interface */
     8.6  CallMaker g_CallMaker;
     8.7 +CallMaker2 g_CallMaker2;
     8.8  ISourcePawnEngine *g_SPEngine;
     8.9  
    8.10  SMEXT_LINK(&g_BinTools);
    8.11 @@ -47,6 +48,9 @@
    8.12  {
    8.13  	g_SPEngine = g_pSM->GetScriptingEngine();
    8.14  	g_pShareSys->AddInterface(myself, &g_CallMaker);
    8.15 +#if defined METAMOD_PLAPI_VERSION
    8.16 +	g_pShareSys->AddInterface(myself, &g_CallMaker2);
    8.17 +#endif
    8.18  
    8.19  	return true;
    8.20  }
     9.1 --- a/extensions/bintools/jit_call.cpp	Wed Jan 07 22:55:40 2009 -0500
     9.2 +++ b/extensions/bintools/jit_call.cpp	Thu Jan 08 18:17:17 2009 +1300
     9.3 @@ -33,39 +33,13 @@
     9.4  #include "extension.h"
     9.5  #include <jit_helpers.h>
     9.6  #include <x86_macros.h>
     9.7 -#include "jit_call.h"
     9.8 +#include "jit_compile.h"
     9.9  
    9.10  jit_uint32_t g_StackUsage = 0;
    9.11  jit_uint32_t g_StackAlign = 0;
    9.12  jit_uint32_t g_RegDecoder = 0;
    9.13  
    9.14  /********************
    9.15 - * Assembly Helpers *
    9.16 - ********************/
    9.17 -
    9.18 -inline jit_uint8_t _DecodeRegister3(jit_uint32_t val)
    9.19 -{
    9.20 -	switch (val % 3)
    9.21 -	{
    9.22 -	case 0:
    9.23 -		{
    9.24 -			return REG_EAX;
    9.25 -		}
    9.26 -	case 1:
    9.27 -		{
    9.28 -			return REG_EDX;
    9.29 -		}
    9.30 -	case 2:
    9.31 -		{
    9.32 -			return REG_ECX;
    9.33 -		}
    9.34 -	}
    9.35 -
    9.36 -	/* Should never happen */
    9.37 -	return 0xFF;
    9.38 -}
    9.39 -
    9.40 -/********************
    9.41   * Assembly Opcodes *
    9.42   ********************/
    9.43  
    9.44 @@ -137,25 +111,25 @@
    9.45  	IA32_Return(jit);
    9.46  }
    9.47  
    9.48 -inline void Write_PushPOD(JitWriter *jit, const PassEncode *pEnc)
    9.49 +inline void Write_PushPOD(JitWriter *jit, const SourceHook::PassInfo *info, unsigned int offset)
    9.50  {
    9.51  	jit_uint8_t reg = _DecodeRegister3(g_RegDecoder++);
    9.52  
    9.53 -	if (pEnc->info.flags & PASSFLAG_BYVAL)
    9.54 +	if (info->flags & PASSFLAG_BYVAL)
    9.55  	{
    9.56 -		switch (pEnc->info.size)
    9.57 +		switch (info->size)
    9.58  		{
    9.59  		case 1:
    9.60  			{
    9.61  				//movzx reg, BYTE PTR [ebx+<offset>]
    9.62  				//push reg
    9.63 -				if (pEnc->offset < SCHAR_MAX)
    9.64 +				if (offset < SCHAR_MAX)
    9.65  				{
    9.66 -					IA32_Movzx_Reg32_Rm8_Disp8(jit, reg, REG_EBX, (jit_int8_t)pEnc->offset);
    9.67 -				} else if (!pEnc->offset) {
    9.68 +					IA32_Movzx_Reg32_Rm8_Disp8(jit, reg, REG_EBX, (jit_int8_t)offset);
    9.69 +				} else if (!offset) {
    9.70  					IA32_Movzx_Reg32_Rm8(jit, reg, REG_EBX, MOD_MEM_REG);
    9.71  				} else {
    9.72 -					IA32_Movzx_Reg32_Rm8_Disp32(jit, reg, REG_EBX, pEnc->offset);
    9.73 +					IA32_Movzx_Reg32_Rm8_Disp32(jit, reg, REG_EBX, offset);
    9.74  				}
    9.75  				IA32_Push_Reg(jit, reg);
    9.76  
    9.77 @@ -167,13 +141,13 @@
    9.78  				//movzx reg, WORD PTR [ebx+<offset>]
    9.79  				//push reg
    9.80  				jit->write_ubyte(IA32_16BIT_PREFIX);
    9.81 -				if (pEnc->offset < SCHAR_MAX)
    9.82 +				if (offset < SCHAR_MAX)
    9.83  				{
    9.84 -					IA32_Movzx_Reg32_Rm16_Disp8(jit, reg, REG_EBX, (jit_int8_t)pEnc->offset);
    9.85 -				} else if (!pEnc->offset) {
    9.86 +					IA32_Movzx_Reg32_Rm16_Disp8(jit, reg, REG_EBX, (jit_int8_t)offset);
    9.87 +				} else if (!offset) {
    9.88  					IA32_Movzx_Reg32_Rm16(jit, reg, REG_EBX, MOD_MEM_REG);
    9.89  				} else {
    9.90 -					IA32_Movzx_Reg32_Rm16_Disp32(jit, reg, REG_EBX, pEnc->offset);
    9.91 +					IA32_Movzx_Reg32_Rm16_Disp32(jit, reg, REG_EBX, offset);
    9.92  				}
    9.93  				IA32_Push_Reg(jit, reg);
    9.94  
    9.95 @@ -184,13 +158,13 @@
    9.96  			{
    9.97  				//mov reg, DWORD PTR [ebx+<offset>]
    9.98  				//push reg
    9.99 -				if (pEnc->offset < SCHAR_MAX)
   9.100 +				if (offset < SCHAR_MAX)
   9.101  				{
   9.102 -					IA32_Mov_Reg_Rm_Disp8(jit, reg, REG_EBX, (jit_int8_t)pEnc->offset);
   9.103 -				} else if (!pEnc->offset) {
   9.104 +					IA32_Mov_Reg_Rm_Disp8(jit, reg, REG_EBX, (jit_int8_t)offset);
   9.105 +				} else if (!offset) {
   9.106  					IA32_Mov_Reg_Rm(jit, reg, REG_EBX, MOD_MEM_REG);
   9.107  				} else {
   9.108 -					IA32_Mov_Reg_Rm_Disp32(jit, reg, REG_EBX, pEnc->offset);
   9.109 +					IA32_Mov_Reg_Rm_Disp32(jit, reg, REG_EBX, offset);
   9.110  				}
   9.111  				IA32_Push_Reg(jit, reg);
   9.112  
   9.113 @@ -205,19 +179,19 @@
   9.114  				//push reg2
   9.115  				jit_uint8_t reg2 = _DecodeRegister3(g_RegDecoder++);
   9.116  
   9.117 -				if (pEnc->offset+4 < SCHAR_MAX)
   9.118 +				if (offset+4 < SCHAR_MAX)
   9.119  				{
   9.120 -					IA32_Mov_Reg_Rm_Disp8(jit, reg, REG_EBX, (jit_int8_t)(pEnc->offset+4));
   9.121 +					IA32_Mov_Reg_Rm_Disp8(jit, reg, REG_EBX, (jit_int8_t)(offset+4));
   9.122  				} else {
   9.123 -					IA32_Mov_Reg_Rm_Disp32(jit, reg, REG_EBX, pEnc->offset+4);
   9.124 +					IA32_Mov_Reg_Rm_Disp32(jit, reg, REG_EBX, offset+4);
   9.125  				}
   9.126 -				if (pEnc->offset < SCHAR_MAX)
   9.127 +				if (offset < SCHAR_MAX)
   9.128  				{
   9.129 -					IA32_Mov_Reg_Rm_Disp8(jit, reg2, REG_EBX, (jit_int8_t)pEnc->offset);
   9.130 -				} else if (!pEnc->offset) {
   9.131 +					IA32_Mov_Reg_Rm_Disp8(jit, reg2, REG_EBX, (jit_int8_t)offset);
   9.132 +				} else if (!offset) {
   9.133  					IA32_Mov_Reg_Rm(jit, reg2, REG_EBX, MOD_MEM_REG);
   9.134  				} else {
   9.135 -					IA32_Mov_Reg_Rm_Disp32(jit, reg2, REG_EBX, pEnc->offset);
   9.136 +					IA32_Mov_Reg_Rm_Disp32(jit, reg2, REG_EBX, offset);
   9.137  				}
   9.138  				IA32_Push_Reg(jit, reg);
   9.139  				IA32_Push_Reg(jit, reg2);
   9.140 @@ -226,20 +200,20 @@
   9.141  				break;
   9.142  			}
   9.143  		}
   9.144 -	} else if (pEnc->info.flags & PASSFLAG_BYREF) {
   9.145 +	} else if (info->flags & PASSFLAG_BYREF) {
   9.146  		//lea reg, [ebx+<offset>]
   9.147  		//push reg
   9.148 -		if (!pEnc->offset)
   9.149 +		if (!offset)
   9.150  		{
   9.151  			IA32_Push_Reg(jit, REG_EBX);
   9.152  			g_StackUsage += 4;
   9.153  			return;
   9.154  		}
   9.155 -		if (pEnc->offset < SCHAR_MAX)
   9.156 +		if (offset < SCHAR_MAX)
   9.157  		{
   9.158 -			IA32_Lea_DispRegImm8(jit, reg, REG_EBX, (jit_int8_t)pEnc->offset);
   9.159 +			IA32_Lea_DispRegImm8(jit, reg, REG_EBX, (jit_int8_t)offset);
   9.160  		} else {
   9.161 -			IA32_Lea_DispRegImm32(jit, reg, REG_EBX, pEnc->offset);
   9.162 +			IA32_Lea_DispRegImm32(jit, reg, REG_EBX, offset);
   9.163  		}
   9.164  		IA32_Push_Reg(jit, reg);
   9.165  
   9.166 @@ -247,24 +221,24 @@
   9.167  	}
   9.168  }
   9.169  
   9.170 -inline void Write_PushFloat(JitWriter *jit, const PassEncode *pEnc)
   9.171 +inline void Write_PushFloat(JitWriter *jit, const SourceHook::PassInfo *info, unsigned int offset)
   9.172  {
   9.173 -	if (pEnc->info.flags & PASSFLAG_BYVAL)
   9.174 +	if (info->flags & PASSFLAG_BYVAL)
   9.175  	{
   9.176 -		switch (pEnc->info.size)
   9.177 +		switch (info->size)
   9.178  		{
   9.179  		case 4:
   9.180  			{
   9.181  				//fld DWORD PTR [ebx+<offset>]
   9.182  				//push reg
   9.183  				//fstp DWORD PTR [esp]
   9.184 -				if (pEnc->offset < SCHAR_MAX)
   9.185 +				if (offset < SCHAR_MAX)
   9.186  				{
   9.187 -					IA32_Fld_Mem32_Disp8(jit, REG_EBX, (jit_int8_t)pEnc->offset);
   9.188 -				} else if (!pEnc->offset) {
   9.189 +					IA32_Fld_Mem32_Disp8(jit, REG_EBX, (jit_int8_t)offset);
   9.190 +				} else if (!offset) {
   9.191  					IA32_Fld_Mem32(jit, REG_EBX);
   9.192  				} else {
   9.193 -					IA32_Fld_Mem32_Disp32(jit, REG_EBX, pEnc->offset);
   9.194 +					IA32_Fld_Mem32_Disp32(jit, REG_EBX, offset);
   9.195  				}
   9.196  				IA32_Push_Reg(jit, _DecodeRegister3(g_RegDecoder++));
   9.197  				IA32_Fstp_Mem32_ESP(jit);
   9.198 @@ -276,13 +250,13 @@
   9.199  				//fld QWORD PTR [ebx+<offset>]
   9.200  				//sub esp, 8
   9.201  				//fstp QWORD PTR [esp]
   9.202 -				if (pEnc->offset < SCHAR_MAX)
   9.203 +				if (offset < SCHAR_MAX)
   9.204  				{
   9.205 -					IA32_Fld_Mem64_Disp8(jit, REG_EBX, (jit_int8_t)pEnc->offset);
   9.206 -				} else if (!pEnc->offset) {
   9.207 +					IA32_Fld_Mem64_Disp8(jit, REG_EBX, (jit_int8_t)offset);
   9.208 +				} else if (!offset) {
   9.209  					IA32_Fld_Mem64(jit, REG_EBX);
   9.210  				} else {
   9.211 -					IA32_Fld_Mem64_Disp32(jit, REG_EBX, pEnc->offset);
   9.212 +					IA32_Fld_Mem64_Disp32(jit, REG_EBX, offset);
   9.213  				}
   9.214  				IA32_Sub_Rm_Imm8(jit, REG_ESP, 8, MOD_REG);
   9.215  				IA32_Fstp_Mem64_ESP(jit);
   9.216 @@ -290,10 +264,10 @@
   9.217  				break;
   9.218  			}
   9.219  		}
   9.220 -	} else if (pEnc->info.flags & PASSFLAG_BYREF) {
   9.221 +	} else if (info->flags & PASSFLAG_BYREF) {
   9.222  		//lea reg, [ebx+<offset>]
   9.223  		//push reg
   9.224 -		if (!pEnc->offset)
   9.225 +		if (!offset)
   9.226  		{
   9.227  			IA32_Push_Reg(jit, REG_EBX);
   9.228  			g_StackUsage += 4;
   9.229 @@ -301,11 +275,11 @@
   9.230  		}
   9.231  
   9.232  		jit_uint8_t reg = _DecodeRegister3(g_RegDecoder++);
   9.233 -		if (pEnc->offset < SCHAR_MAX)
   9.234 +		if (offset < SCHAR_MAX)
   9.235  		{
   9.236 -			IA32_Lea_DispRegImm8(jit, reg, REG_EBX, (jit_int8_t)pEnc->offset);
   9.237 +			IA32_Lea_DispRegImm8(jit, reg, REG_EBX, (jit_int8_t)offset);
   9.238  		} else {
   9.239 -			IA32_Lea_DispRegImm32(jit, reg, REG_EBX, pEnc->offset);
   9.240 +			IA32_Lea_DispRegImm32(jit, reg, REG_EBX, offset);
   9.241  		}
   9.242  		IA32_Push_Reg(jit, reg);
   9.243  
   9.244 @@ -313,18 +287,18 @@
   9.245  	}
   9.246  }
   9.247  
   9.248 -inline void Write_PushObject(JitWriter *jit, const PassEncode *pEnc)
   9.249 +inline void Write_PushObject(JitWriter *jit, const SourceHook::PassInfo *info, unsigned int offset)
   9.250  {
   9.251 -	if (pEnc->info.flags & PASSFLAG_BYVAL)
   9.252 +	if (info->flags & PASSFLAG_BYVAL)
   9.253  	{
   9.254  #ifdef PLATFORM_POSIX
   9.255 -		if (pEnc->info.flags & PASSFLAG_ODTOR)
   9.256 +		if (info->flags & PASSFLAG_ODTOR)
   9.257  		{
   9.258  			goto push_byref;
   9.259  		}
   9.260  #endif
   9.261 -		jit_uint32_t dwords = pEnc->info.size >> 2;
   9.262 -		jit_uint32_t bytes = pEnc->info.size & 0x3;
   9.263 +		jit_uint32_t dwords = info->size >> 2;
   9.264 +		jit_uint32_t bytes = info->size & 0x3;
   9.265  
   9.266  		//sub esp, <size>
   9.267  		//cld
   9.268 @@ -340,23 +314,23 @@
   9.269  		// rep movsb
   9.270  		//pop esi
   9.271  		//pop edi
   9.272 -		if (pEnc->info.size < SCHAR_MAX)
   9.273 +		if (info->size < SCHAR_MAX)
   9.274  		{
   9.275 -			IA32_Sub_Rm_Imm8(jit, REG_ESP, (jit_int8_t)pEnc->info.size, MOD_REG);
   9.276 +			IA32_Sub_Rm_Imm8(jit, REG_ESP, (jit_int8_t)info->size, MOD_REG);
   9.277  		} else {
   9.278 -			IA32_Sub_Rm_Imm32(jit, REG_ESP, pEnc->info.size, MOD_REG);
   9.279 +			IA32_Sub_Rm_Imm32(jit, REG_ESP, info->size, MOD_REG);
   9.280  		}
   9.281  		IA32_Cld(jit);
   9.282  		IA32_Push_Reg(jit, REG_EDI);
   9.283  		IA32_Push_Reg(jit, REG_ESI);
   9.284  		IA32_Lea_Reg_DispRegMultImm8(jit, REG_EDI, REG_NOIDX, REG_ESP, NOSCALE, 8);
   9.285 -		if (pEnc->offset < SCHAR_MAX)
   9.286 +		if (offset < SCHAR_MAX)
   9.287  		{
   9.288 -			IA32_Lea_DispRegImm8(jit, REG_ESI, REG_EBX, (jit_int8_t)pEnc->offset);
   9.289 -		} else if (!pEnc->offset) {
   9.290 +			IA32_Lea_DispRegImm8(jit, REG_ESI, REG_EBX, (jit_int8_t)offset);
   9.291 +		} else if (!offset) {
   9.292  			IA32_Mov_Reg_Rm(jit, REG_ESI, REG_EBX, MOD_REG);
   9.293  		} else {
   9.294 -			IA32_Lea_DispRegImm32(jit, REG_ESI, REG_EBX, pEnc->offset);
   9.295 +			IA32_Lea_DispRegImm32(jit, REG_ESI, REG_EBX, offset);
   9.296  		}
   9.297  		if (dwords)
   9.298  		{
   9.299 @@ -373,12 +347,12 @@
   9.300  		IA32_Pop_Reg(jit, REG_ESI);
   9.301  		IA32_Pop_Reg(jit, REG_EDI);
   9.302  
   9.303 -		g_StackUsage += pEnc->info.size;
   9.304 -	} else if (pEnc->info.flags & PASSFLAG_BYREF) {
   9.305 +		g_StackUsage += info->size;
   9.306 +	} else if (info->flags & PASSFLAG_BYREF) {
   9.307  #ifdef PLATFORM_POSIX
   9.308  push_byref:
   9.309  #endif
   9.310 -		if (!pEnc->offset)
   9.311 +		if (!offset)
   9.312  		{
   9.313  			IA32_Push_Reg(jit, REG_EBX);
   9.314  			g_StackUsage += 4;
   9.315 @@ -388,11 +362,11 @@
   9.316  		//lea reg, [ebx+<offset>]
   9.317  		//push reg
   9.318  		jit_uint8_t reg = _DecodeRegister3(g_RegDecoder++);
   9.319 -		if (pEnc->offset < SCHAR_MAX)
   9.320 +		if (offset < SCHAR_MAX)
   9.321  		{
   9.322 -			IA32_Lea_DispRegImm8(jit, reg, REG_EBX, (jit_int8_t)pEnc->offset);
   9.323 +			IA32_Lea_DispRegImm8(jit, reg, REG_EBX, (jit_int8_t)offset);
   9.324  		} else {
   9.325 -			IA32_Lea_DispRegImm32(jit, reg, REG_EBX, pEnc->offset);
   9.326 +			IA32_Lea_DispRegImm32(jit, reg, REG_EBX, offset);
   9.327  		}
   9.328  		IA32_Push_Reg(jit, reg);
   9.329  
   9.330 @@ -429,15 +403,16 @@
   9.331  	{
   9.332  		//call <addr>
   9.333  		jitoffs_t call = IA32_Call_Imm32(jit, 0);
   9.334 -		IA32_Write_Jump32_Abs(jit, call, pWrapper->m_Addrs[ADDR_CALLEE]);
   9.335 +		IA32_Write_Jump32_Abs(jit, call, pWrapper->GetCalleeAddr());
   9.336  	} else if (method == FuncAddr_VTable) {
   9.337  		//*(this + thisOffs + vtblOffs)[vtblIdx]
   9.338  		//mov edx, [ebx]
   9.339  		//mov eax, [edx+<thisOffs>+<vtblOffs>]
   9.340  		//mov edx, [eax+<vtblIdx>*4]
   9.341  		//call edx
   9.342 -		jit_uint32_t total_offs = pWrapper->m_VtInfo.thisOffs + pWrapper->m_VtInfo.vtblOffs;
   9.343 -		jit_uint32_t vfunc_pos = pWrapper->m_VtInfo.vtblIdx * 4;
   9.344 +		SourceHook::MemFuncInfo *funcInfo = pWrapper->GetMemFuncInfo();
   9.345 +		jit_uint32_t total_offs = funcInfo->thisptroffs + funcInfo->vtbloffs;
   9.346 +		jit_uint32_t vfunc_pos = funcInfo->vtblindex * 4;
   9.347  
   9.348  		IA32_Mov_Reg_Rm(jit, REG_EDX, REG_EBX, MOD_MEM_REG);
   9.349  		if (total_offs < SCHAR_MAX)
   9.350 @@ -529,7 +504,7 @@
   9.351   * Assembly Compiler Function *
   9.352   ******************************/
   9.353  
   9.354 -void JIT_Compile(CallWrapper *pWrapper, FuncAddrMethod method)
   9.355 +void *JIT_CallCompile(CallWrapper *pWrapper, FuncAddrMethod method)
   9.356  {
   9.357  	JitWriter writer;
   9.358  	JitWriter *jit = &writer;
   9.359 @@ -553,22 +528,25 @@
   9.360  	/* Write parameter push code */
   9.361  	for (jit_int32_t i=ParamCount-1; i>=0; i--)
   9.362  	{
   9.363 -		const PassEncode *pEnc = pWrapper->GetParamInfo(i);
   9.364 -		switch (pEnc->info.type)
   9.365 +		unsigned int offset = pWrapper->GetParamOffset(i);
   9.366 +		const SourceHook::PassInfo *info = pWrapper->GetSHParamInfo(i);
   9.367 +		assert(info != NULL);
   9.368 +
   9.369 +		switch (info->type)
   9.370  		{
   9.371 -		case PassType_Basic:
   9.372 +		case SourceHook::PassInfo::PassType_Basic:
   9.373  			{
   9.374 -				Write_PushPOD(jit, pEnc);
   9.375 +				Write_PushPOD(jit, info, offset);
   9.376  				break;
   9.377  			}
   9.378 -		case PassType_Float:
   9.379 +		case SourceHook::PassInfo::PassType_Float:
   9.380  			{
   9.381 -				Write_PushFloat(jit, pEnc);
   9.382 +				Write_PushFloat(jit, info, offset);
   9.383  				break;
   9.384  			}
   9.385 -		case PassType_Object:
   9.386 +		case SourceHook::PassInfo::PassType_Object:
   9.387  			{
   9.388 -				Write_PushObject(jit, pEnc);
   9.389 +				Write_PushObject(jit, info, offset);
   9.390  				break;
   9.391  			}
   9.392  		}
   9.393 @@ -640,7 +618,7 @@
   9.394  		writer.outbase = (jitcode_t)g_SPEngine->AllocatePageMemory(CodeSize);
   9.395  		g_SPEngine->SetReadWrite(writer.outbase);
   9.396  		writer.outptr = writer.outbase;
   9.397 -		pWrapper->m_Addrs[ADDR_CODEBASE] = writer.outbase;
   9.398 +		pWrapper->SetCodeBaseAddr(writer.outbase);
   9.399  		g_StackAlign = (g_StackUsage) ? ((g_StackUsage & 0xFFFFFFF0) + 16) - g_StackUsage : 0;
   9.400  		g_StackUsage = 0;
   9.401  		g_RegDecoder = 0;
   9.402 @@ -648,4 +626,5 @@
   9.403  		goto jit_rewind;
   9.404  	}
   9.405  	g_SPEngine->SetReadExecute(writer.outbase);
   9.406 +	return writer.outbase;
   9.407  }
    10.1 --- a/extensions/bintools/jit_call.h	Wed Jan 07 22:55:40 2009 -0500
    10.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    10.3 @@ -1,40 +0,0 @@
    10.4 -/**
    10.5 - * vim: set ts=4 :
    10.6 - * =============================================================================
    10.7 - * SourceMod BinTools Extension
    10.8 - * Copyright (C) 2004-2008 AlliedModders LLC.  All rights reserved.
    10.9 - * =============================================================================
   10.10 - *
   10.11 - * This program is free software; you can redistribute it and/or modify it under
   10.12 - * the terms of the GNU General Public License, version 3.0, as published by the
   10.13 - * Free Software Foundation.
   10.14 - * 
   10.15 - * This program is distributed in the hope that it will be useful, but WITHOUT
   10.16 - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
   10.17 - * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
   10.18 - * details.
   10.19 - *
   10.20 - * You should have received a copy of the GNU General Public License along with
   10.21 - * this program.  If not, see <http://www.gnu.org/licenses/>.
   10.22 - *
   10.23 - * As a special exception, AlliedModders LLC gives you permission to link the
   10.24 - * code of this program (as well as its derivative works) to "Half-Life 2," the
   10.25 - * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
   10.26 - * by the Valve Corporation.  You must obey the GNU General Public License in
   10.27 - * all respects for all other code used.  Additionally, AlliedModders LLC grants
   10.28 - * this exception to all derivative works.  AlliedModders LLC defines further
   10.29 - * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
   10.30 - * or <http://www.sourcemod.net/license.php>.
   10.31 - *
   10.32 - * Version: $Id$
   10.33 - */
   10.34 -
   10.35 -#ifndef _INCLUDE_SOURCEMOD_JIT_CALL_H_
   10.36 -#define _INCLUDE_SOURCEMOD_JIT_CALL_H_
   10.37 -
   10.38 -#include "CallMaker.h"
   10.39 -#include "CallWrapper.h"
   10.40 -
   10.41 -void JIT_Compile(CallWrapper *pWrapper, FuncAddrMethod method);
   10.42 -
   10.43 -#endif //_INCLUDE_SOURCEMOD_JIT_CALL_H_
    11.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    11.2 +++ b/extensions/bintools/jit_compile.h	Thu Jan 08 18:17:17 2009 +1300
    11.3 @@ -0,0 +1,75 @@
    11.4 +/**
    11.5 + * vim: set ts=4 :
    11.6 + * =============================================================================
    11.7 + * SourceMod BinTools Extension
    11.8 + * Copyright (C) 2004-2008 AlliedModders LLC.  All rights reserved.
    11.9 + * =============================================================================
   11.10 + *
   11.11 + * This program is free software; you can redistribute it and/or modify it under
   11.12 + * the terms of the GNU General Public License, version 3.0, as published by the
   11.13 + * Free Software Foundation.
   11.14 + * 
   11.15 + * This program is distributed in the hope that it will be useful, but WITHOUT
   11.16 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
   11.17 + * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
   11.18 + * details.
   11.19 + *
   11.20 + * You should have received a copy of the GNU General Public License along with
   11.21 + * this program.  If not, see <http://www.gnu.org/licenses/>.
   11.22 + *
   11.23 + * As a special exception, AlliedModders LLC gives you permission to link the
   11.24 + * code of this program (as well as its derivative works) to "Half-Life 2," the
   11.25 + * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
   11.26 + * by the Valve Corporation.  You must obey the GNU General Public License in
   11.27 + * all respects for all other code used.  Additionally, AlliedModders LLC grants
   11.28 + * this exception to all derivative works.  AlliedModders LLC defines further
   11.29 + * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
   11.30 + * or <http://www.sourcemod.net/license.php>.
   11.31 + *
   11.32 + * Version: $Id$
   11.33 + */
   11.34 +
   11.35 +#ifndef _INCLUDE_SOURCEMOD_JIT_COMPILE_H_
   11.36 +#define _INCLUDE_SOURCEMOD_JIT_COMPILE_H_
   11.37 +
   11.38 +#include <jit_helpers.h>
   11.39 +#include <x86_macros.h>
   11.40 +#include "CallWrapper.h"
   11.41 +#include "HookWrapper.h"
   11.42 +
   11.43 +void *JIT_CallCompile(CallWrapper *pWrapper, FuncAddrMethod method);
   11.44 +#if defined HOOKING_ENABLED
   11.45 +void *JIT_HookCompile(HookWrapper *pWrapper);
   11.46 +void JIT_FreeHook(void *addr);
   11.47 +#endif
   11.48 +
   11.49 +/********************
   11.50 + * Assembly Helpers *
   11.51 + ********************/
   11.52 +
   11.53 +inline jit_uint8_t _DecodeRegister3(jit_uint32_t val)
   11.54 +{
   11.55 +	switch (val % 3)
   11.56 +	{
   11.57 +	case 0:
   11.58 +		{
   11.59 +			return REG_EAX;
   11.60 +		}
   11.61 +	case 1:
   11.62 +		{
   11.63 +			return REG_EDX;
   11.64 +		}
   11.65 +	case 2:
   11.66 +		{
   11.67 +			return REG_ECX;
   11.68 +		}
   11.69 +	}
   11.70 +
   11.71 +	/* Should never happen */
   11.72 +	assert(false);
   11.73 +	return 0xFF;
   11.74 +}
   11.75 +
   11.76 +extern jit_uint32_t g_RegDecoder;
   11.77 +
   11.78 +#endif //_INCLUDE_SOURCEMOD_JIT_COMPILE_H_
    12.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    12.2 +++ b/extensions/bintools/jit_hook.cpp	Thu Jan 08 18:17:17 2009 +1300
    12.3 @@ -0,0 +1,430 @@
    12.4 +/**
    12.5 + * vim: set ts=4 :
    12.6 + * =============================================================================
    12.7 + * SourceMod BinTools Extension
    12.8 + * Copyright (C) 2004-2008 AlliedModders LLC.  All rights reserved.
    12.9 + * =============================================================================
   12.10 + *
   12.11 + * This program is free software; you can redistribute it and/or modify it under
   12.12 + * the terms of the GNU General Public License, version 3.0, as published by the
   12.13 + * Free Software Foundation.
   12.14 + * 
   12.15 + * This program is distributed in the hope that it will be useful, but WITHOUT
   12.16 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
   12.17 + * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
   12.18 + * details.
   12.19 + *
   12.20 + * You should have received a copy of the GNU General Public License along with
   12.21 + * this program.  If not, see <http://www.gnu.org/licenses/>.
   12.22 + *
   12.23 + * As a special exception, AlliedModders LLC gives you permission to link the
   12.24 + * code of this program (as well as its derivative works) to "Half-Life 2," the
   12.25 + * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
   12.26 + * by the Valve Corporation.  You must obey the GNU General Public License in
   12.27 + * all respects for all other code used.  Additionally, AlliedModders LLC grants
   12.28 + * this exception to all derivative works.  AlliedModders LLC defines further
   12.29 + * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
   12.30 + * or <http://www.sourcemod.net/license.php>.
   12.31 + *
   12.32 + * Version: $Id: CallMaker.h 1964 2008-03-27 04:54:56Z damagedsoul $
   12.33 + */
   12.34 +
   12.35 +#if defined HOOKING_ENABLED
   12.36 +
   12.37 +#include "jit_compile.h"
   12.38 +#include "sm_platform.h"
   12.39 +#include "extension.h"
   12.40 +
   12.41 +/********************
   12.42 + * Assembly Opcodes *
   12.43 + ********************/
   12.44 +
   12.45 +inline void Write_Function_Prologue(JitWriter *jit, bool RetInMemory)
   12.46 +{
   12.47 +	//push ebp
   12.48 +	//push ebx
   12.49 +	//mov ebp, esp
   12.50 +	IA32_Push_Reg(jit, REG_EBP);
   12.51 +	IA32_Push_Reg(jit, REG_EBX);
   12.52 +	IA32_Mov_Reg_Rm(jit, REG_EBP, REG_ESP, MOD_REG);
   12.53 +#if defined PLATFORM_WINDOWS
   12.54 +	//mov ebx, ecx
   12.55 +	IA32_Mov_Reg_Rm(jit, REG_EBX, REG_ECX, MOD_REG);
   12.56 +#elif defined PLATFORM_LINUX
   12.57 +	//mov ebx, [ebp+12+(RetInMemory)?4:0]
   12.58 +	IA32_Mov_Reg_Rm_Disp8(jit, REG_EBX, REG_EBP, 12+((RetInMemory)?4:0));
   12.59 +#endif
   12.60 +}
   12.61 +
   12.62 +inline void Write_Function_Epilogue(JitWriter *jit, unsigned short size)
   12.63 +{
   12.64 +	//mov esp, ebp
   12.65 +	//pop ebx
   12.66 +	//pop ebp
   12.67 +	//ret <value>
   12.68 +	IA32_Mov_Reg_Rm(jit, REG_ESP, REG_EBP, MOD_REG);
   12.69 +	IA32_Pop_Reg(jit, REG_EBX);
   12.70 +	IA32_Pop_Reg(jit, REG_EBP);
   12.71 +	if (size == 0)
   12.72 +	{
   12.73 +		IA32_Return(jit);
   12.74 +	}
   12.75 +	else
   12.76 +	{
   12.77 +		IA32_Return_Popstack(jit, size);
   12.78 +	}
   12.79 +}
   12.80 +
   12.81 +inline void Write_Stack_Alloc(JitWriter *jit, jit_uint32_t size)
   12.82 +{
   12.83 +	//sub esp, <value>
   12.84 +	if (size <= SCHAR_MAX)
   12.85 +	{
   12.86 +		IA32_Sub_Rm_Imm8(jit, REG_ESP, (jit_int8_t)size, MOD_REG);
   12.87 +	}
   12.88 +	else
   12.89 +	{
   12.90 +		IA32_Sub_Rm_Imm32(jit, REG_ESP, size, MOD_REG);
   12.91 +	}
   12.92 +}
   12.93 +
   12.94 +inline void Write_Copy_Params(JitWriter *jit, bool RetInMemory, jit_uint32_t retsize, jit_uint32_t paramsize)
   12.95 +{
   12.96 +	//:TODO: inline this memcpy!! - For small numbers of params mov's (with clever reg allocation?) would be faster
   12.97 +
   12.98 +	//cld
   12.99 +	//push edi
  12.100 +	//push esi
  12.101 +	//lea edi, [ebp-<retsize>-<paramsize>]
  12.102 +	//lea esi, [ebp+12+(RetInMemory)?4:0]
  12.103 +	//if dwords
  12.104 +	// mov ecx, <dwords>
  12.105 +	// rep movsd
  12.106 +	//if bytes
  12.107 +	// mov ecx, <bytes>
  12.108 +	// rep movsb
  12.109 +	//pop esi
  12.110 +	//pop edi
  12.111 +
  12.112 +	jit_int32_t offs;
  12.113 +	jit_uint32_t dwords = paramsize >> 2;
  12.114 +	jit_uint32_t bytes = paramsize & 0x3;
  12.115 +
  12.116 +	IA32_Cld(jit);
  12.117 +	IA32_Push_Reg(jit, REG_EDI);
  12.118 +	IA32_Push_Reg(jit, REG_ESI);
  12.119 +	offs = -(jit_int32_t)retsize - paramsize;
  12.120 +
  12.121 +	if (offs > SCHAR_MIN)
  12.122 +	{
  12.123 +		IA32_Lea_DispRegImm8(jit, REG_EDI, REG_EBP, (jit_int8_t)offs);
  12.124 +	}
  12.125 +	else
  12.126 +	{
  12.127 +		IA32_Lea_DispRegImm32(jit, REG_EDI, REG_EBP, offs);
  12.128 +	}
  12.129 +	offs = 12 + ((RetInMemory) ? sizeof(void *) : 0);
  12.130 +
  12.131 +#if defined PLATFORM_LINUX
  12.132 +	offs += 4;
  12.133 +#endif
  12.134 +
  12.135 +	if (offs < SCHAR_MAX)
  12.136 +	{
  12.137 +		IA32_Lea_DispRegImm8(jit, REG_ESI, REG_EBP, (jit_int8_t)offs);
  12.138 +	}
  12.139 +	else
  12.140 +	{
  12.141 +		IA32_Lea_DispRegImm32(jit, REG_ESI, REG_EBP, offs);
  12.142 +	}
  12.143 +	if (dwords)
  12.144 +	{
  12.145 +		IA32_Mov_Reg_Imm32(jit, REG_ECX, dwords);
  12.146 +		IA32_Rep(jit);
  12.147 +		IA32_Movsd(jit);
  12.148 +	}
  12.149 +	if (bytes)
  12.150 +	{
  12.151 +		IA32_Mov_Reg_Imm32(jit, REG_ECX, bytes);
  12.152 +		IA32_Rep(jit);
  12.153 +		IA32_Movsb(jit);
  12.154 +	}
  12.155 +	IA32_Pop_Reg(jit, REG_ESI);
  12.156 +	IA32_Pop_Reg(jit, REG_EDI);
  12.157 +}
  12.158 +
  12.159 +inline void Write_Push_Params(JitWriter *jit, 
  12.160 +							  bool isretvoid, 
  12.161 +							  bool isvoid, 
  12.162 +							  jit_uint32_t retsize, 
  12.163 +							  jit_uint32_t paramsize, 
  12.164 +							  HookWrapper *pWrapper)
  12.165 +{
  12.166 +	//and esp, 0xFFFFFFF0
  12.167 +	IA32_And_Rm_Imm8(jit, REG_ESP, MOD_REG, -16);
  12.168 +
  12.169 +	//if retvoid
  12.170 +	// push 0
  12.171 +	//else
  12.172 +	// lea reg, [ebp-<retsize>]
  12.173 +	// push reg
  12.174 +	if (isretvoid)
  12.175 +	{
  12.176 +		IA32_Push_Imm8(jit, 0);
  12.177 +	}
  12.178 +	else
  12.179 +	{
  12.180 +		jit_int32_t offs = -(jit_int32_t)retsize;
  12.181 +		if (offs >= SCHAR_MIN)
  12.182 +		{
  12.183 +			IA32_Lea_DispRegImm8(jit, REG_EAX, REG_EBP, (jit_int8_t)offs);
  12.184 +		}
  12.185 +		else
  12.186 +		{
  12.187 +			IA32_Lea_DispRegImm32(jit, REG_EAX, REG_EBP, offs);
  12.188 +		}
  12.189 +		IA32_Push_Reg(jit, REG_EAX);
  12.190 +	}
  12.191 +
  12.192 +	//if void
  12.193 +	// push 0
  12.194 +	//else
  12.195 +	// lea reg, [ebp-<retsize>-<paramsize>]
  12.196 +	// push reg
  12.197 +	if (isvoid)
  12.198 +	{
  12.199 +		IA32_Push_Imm8(jit, 0);
  12.200 +	}
  12.201 +	else
  12.202 +	{
  12.203 +		jit_int32_t offs = -(jit_int32_t)retsize - paramsize;
  12.204 +		if (offs > SCHAR_MIN)
  12.205 +		{
  12.206 +			IA32_Lea_DispRegImm8(jit, REG_EDX, REG_EBP, (jit_int8_t)offs);
  12.207 +		} else {
  12.208 +			IA32_Lea_DispRegImm32(jit, REG_EDX, REG_EBP, offs);
  12.209 +		}
  12.210 +		IA32_Push_Reg(jit, REG_EDX);
  12.211 +	}
  12.212 +
  12.213 +	//push eax (thisptr)
  12.214 +	//IA32_Push_Reg(jit, REG_ECX);
  12.215 +
  12.216 +	//push ebx
  12.217 +	IA32_Push_Reg(jit, REG_EBX);
  12.218 +
  12.219 +	//push <pWrapper>
  12.220 +	IA32_Push_Imm32(jit, (jit_int32_t)pWrapper);
  12.221 +}
  12.222 +
  12.223 +inline void Write_Call_Handler(JitWriter *jit, void *addr)
  12.224 +{
  12.225 +	//call <addr>
  12.226 +	jitoffs_t call = IA32_Call_Imm32(jit, 0);
  12.227 +	IA32_Write_Jump32_Abs(jit, call, addr);
  12.228 +}
  12.229 +
  12.230 +inline void Write_Copy_RetVal(JitWriter *jit, SourceHook::PassInfo *pRetInfo)
  12.231 +{
  12.232 +	/* If the return value is a reference the size will probably be >sizeof(void *)
  12.233 +	* for objects, we need to fix that so we can actually return the reference.
  12.234 +	*/
  12.235 +	size_t size = pRetInfo->size;
  12.236 +	if (pRetInfo->flags & PASSFLAG_BYREF)
  12.237 +	{
  12.238 +		size = sizeof(void *);
  12.239 +	}
  12.240 +
  12.241 +	if (pRetInfo->type == SourceHook::PassInfo::PassType_Float &&
  12.242 +		pRetInfo->flags & SourceHook::PassInfo::PassFlag_ByVal)
  12.243 +	{
  12.244 +		switch (size)
  12.245 +		{
  12.246 +		case 4:
  12.247 +			{
  12.248 +				//fld DWORD PTR [ebp-4]
  12.249 +				IA32_Fld_Mem32_Disp8(jit, REG_EBP, -4);
  12.250 +				break;
  12.251 +			}
  12.252 +		case 8:
  12.253 +			{
  12.254 +				//fld QWORD PTR [ebp-8]
  12.255 +				IA32_Fld_Mem64_Disp8(jit, REG_EBP, -8);
  12.256 +				break;
  12.257 +			}
  12.258 +		}
  12.259 +	}
  12.260 +	else if (pRetInfo->type == SourceHook::PassInfo::PassType_Object &&
  12.261 +		pRetInfo->flags & SourceHook::PassInfo::PassFlag_ByVal)
  12.262 +	{
  12.263 +		//cld
  12.264 +		//push edi
  12.265 +		//push esi
  12.266 +		//mov edi, [ebp+12]
  12.267 +		//lea esi, [ebp-<retsize>]
  12.268 +		//if dwords
  12.269 +		// mov ecx, <dwords>
  12.270 +		// rep movsd
  12.271 +		//if bytes
  12.272 +		// mov ecx, <bytes>
  12.273 +		// rep movsb
  12.274 +		//pop esi
  12.275 +		//pop edi
  12.276 +
  12.277 +		jit_int32_t offs;
  12.278 +		jit_uint32_t dwords = size >> 2;
  12.279 +		jit_uint32_t bytes = size & 0x3;
  12.280 +
  12.281 +		IA32_Cld(jit);
  12.282 +		IA32_Push_Reg(jit, REG_EDI);
  12.283 +		IA32_Push_Reg(jit, REG_ESI);
  12.284 +
  12.285 +		IA32_Mov_Reg_Rm_Disp8(jit, REG_EDI, REG_EBP, 12);
  12.286 +
  12.287 +		offs = -(jit_int32_t)pRetInfo->size;
  12.288 +		if (offs >= SCHAR_MIN)
  12.289 +		{
  12.290 +			IA32_Lea_DispRegImm8(jit, REG_ESI, REG_EBP, (jit_int8_t)offs);
  12.291 +		}
  12.292 +		else
  12.293 +		{
  12.294 +			IA32_Lea_DispRegImm32(jit, REG_ESI, REG_EBP, offs);
  12.295 +		}
  12.296 +		IA32_Mov_Reg_Rm(jit, REG_EAX, REG_EDI, MOD_REG);
  12.297 +
  12.298 +		if (dwords)
  12.299 +		{
  12.300 +			IA32_Mov_Reg_Imm32(jit, REG_ECX, dwords);
  12.301 +			IA32_Rep(jit);
  12.302 +			IA32_Movsd(jit);
  12.303 +		}
  12.304 +		if (bytes)
  12.305 +		{
  12.306 +			IA32_Mov_Reg_Imm32(jit, REG_ECX, bytes);
  12.307 +			IA32_Rep(jit);
  12.308 +			IA32_Movsb(jit);
  12.309 +		}
  12.310 +		IA32_Pop_Reg(jit, REG_ESI);
  12.311 +		IA32_Pop_Reg(jit, REG_EDI);
  12.312 +	}
  12.313 +	else
  12.314 +	{
  12.315 +		switch (size)
  12.316 +		{
  12.317 +		case 1:
  12.318 +			{
  12.319 +				//mov al, BYTE PTR [ebp-4]
  12.320 +				IA32_Mov_Reg8_Rm8_Disp8(jit, REG_EAX, REG_EBP, -4);
  12.321 +				break;
  12.322 +			}
  12.323 +		case 2:
  12.324 +			{
  12.325 +				//mov ax, WORD PTR [ebp-4]
  12.326 +				jit->write_ubyte(IA32_16BIT_PREFIX);
  12.327 +				IA32_Mov_Reg_Rm_Disp8(jit, REG_EAX, REG_EBP, -4);
  12.328 +				break;
  12.329 +			}
  12.330 +		case 4:
  12.331 +			{
  12.332 +				//mov eax, DWORD PTR [ebp-4]
  12.333 +				IA32_Mov_Reg_Rm_Disp8(jit, REG_EAX, REG_EBP, -4);
  12.334 +				break;
  12.335 +			}
  12.336 +		case 8:
  12.337 +			{
  12.338 +				//mov eax, DWORD PTR [ebp-8]
  12.339 +				//mov edx, DWORD PTR [ebp-4]
  12.340 +				//:TODO: this is broken due to SH
  12.341 +				IA32_Mov_Reg_Rm_Disp8(jit, REG_EAX, REG_EBP, -8);
  12.342 +				IA32_Mov_Reg_Rm_Disp8(jit, REG_EDX, REG_EBP, -4);
  12.343 +				break;
  12.344 +			}
  12.345 +		}
  12.346 +	}
  12.347 +}
  12.348 +
  12.349 +/******************************
  12.350 + * Assembly Compiler Function *
  12.351 + ******************************/
  12.352 +
  12.353 +void *JIT_HookCompile(HookWrapper *pWrapper)
  12.354 +{
  12.355 +	JitWriter writer;
  12.356 +	JitWriter *jit = &writer;
  12.357 +
  12.358 +	jit_uint32_t CodeSize = 0;
  12.359 +	jit_uint32_t ParamSize = pWrapper->GetParamSize();
  12.360 +	jit_uint32_t RetSize = pWrapper->GetRetSize();
  12.361 +
  12.362 +	/* Local variable size allocated in the stack for the param and retval buffers */
  12.363 +	jit_uint32_t LocalVarSize = ParamSize + RetSize;
  12.364 +
  12.365 +	/* Check if the return value is returned in memory */
  12.366 +	bool RetInMemory = false;
  12.367 +	SourceHook::PassInfo *pRetInfo = &pWrapper->GetProtoInfo()->retPassInfo;
  12.368 +	if ((pRetInfo->type == SourceHook::PassInfo::PassType_Object) && 
  12.369 +		(pRetInfo->flags & SourceHook::PassInfo::PassFlag_ByVal))
  12.370 +	{
  12.371 +		RetInMemory = true;
  12.372 +	}
  12.373 +
  12.374 +	writer.outbase = NULL;
  12.375 +	writer.outptr = NULL;
  12.376 +
  12.377 +jit_rewind:
  12.378 +	/* Write the function prologue */
  12.379 +	Write_Function_Prologue(jit, RetInMemory);
  12.380 +
  12.381 +	/* Allocate the local variables into the stack */
  12.382 +	if (LocalVarSize)
  12.383 +	{
  12.384 +		Write_Stack_Alloc(jit, LocalVarSize);
  12.385 +	}
  12.386 +
  12.387 +	/* Copy all the parameters into the buffer */
  12.388 +	if (ParamSize)
  12.389 +	{
  12.390 +		Write_Copy_Params(jit, RetInMemory, RetSize, ParamSize);
  12.391 +	}
  12.392 +
  12.393 +	/* Push the parameters into the handler */
  12.394 +	Write_Push_Params(jit, !RetSize, !ParamSize, RetSize, ParamSize, pWrapper);
  12.395 +
  12.396 +	/* Call the handler function */
  12.397 +	Write_Call_Handler(jit, pWrapper->GetHandlerAddr());
  12.398 +
  12.399 +	/* Copy back the return value into eax or the hidden return buffer */
  12.400 +	if (RetSize)
  12.401 +	{
  12.402 +		Write_Copy_RetVal(jit, pRetInfo);
  12.403 +	}
  12.404 +
  12.405 +	/* Write the function epilogue */
  12.406 +	Write_Function_Epilogue(jit, 
  12.407 +#if defined PLATFORM_WINDOWS
  12.408 +		ParamSize + ((RetInMemory) ? sizeof(void *) : 0)
  12.409 +#elif defined PLATFORM_LINUX
  12.410 +		(RetInMemory) ? sizeof(void *) : 0
  12.411 +#endif
  12.412 +	);
  12.413 +
  12.414 +	if (writer.outbase == NULL)
  12.415 +	{
  12.416 +		CodeSize = writer.get_outputpos();
  12.417 +		writer.outbase = (jitcode_t)g_SPEngine->AllocatePageMemory(CodeSize);
  12.418 +		g_SPEngine->SetReadWrite(writer.outbase);
  12.419 +		writer.outptr = writer.outbase;
  12.420 +		g_RegDecoder = 0;
  12.421 +		goto jit_rewind;
  12.422 +	}
  12.423 +	g_SPEngine->SetReadExecute(writer.outbase);
  12.424 +
  12.425 +	return writer.outbase;
  12.426 +}
  12.427 +
  12.428 +void JIT_FreeHook(void *addr)
  12.429 +{
  12.430 +	g_SPEngine->FreePageMemory(addr);
  12.431 +}
  12.432 +
  12.433 +#endif
    13.1 --- a/extensions/bintools/msvc9/bintools.sln	Wed Jan 07 22:55:40 2009 -0500
    13.2 +++ b/extensions/bintools/msvc9/bintools.sln	Thu Jan 08 18:17:17 2009 +1300
    13.3 @@ -5,14 +5,32 @@
    13.4  EndProject
    13.5  Global
    13.6  	GlobalSection(SolutionConfigurationPlatforms) = preSolution
    13.7 -		Debug|Win32 = Debug|Win32
    13.8 -		Release|Win32 = Release|Win32
    13.9 +		Debug - Episode 1|Win32 = Debug - Episode 1|Win32
   13.10 +		Debug - Left 4 Dead|Win32 = Debug - Left 4 Dead|Win32
   13.11 +		Debug - Old Metamod|Win32 = Debug - Old Metamod|Win32
   13.12 +		Debug - Orange Box|Win32 = Debug - Orange Box|Win32
   13.13 +		Release - Episode 1|Win32 = Release - Episode 1|Win32
   13.14 +		Release - Left 4 Dead|Win32 = Release - Left 4 Dead|Win32
   13.15 +		Release - Old Metamod|Win32 = Release - Old Metamod|Win32
   13.16 +		Release - Orange Box|Win32 = Release - Orange Box|Win32
   13.17  	EndGlobalSection
   13.18  	GlobalSection(ProjectConfigurationPlatforms) = postSolution
   13.19 -		{E38F65D9-74B2-4373-B46A-DBB76F579F98}.Debug|Win32.ActiveCfg = Debug|Win32
   13.20 -		{E38F65D9-74B2-4373-B46A-DBB76F579F98}.Debug|Win32.Build.0 = Debug|Win32
   13.21 -		{E38F65D9-74B2-4373-B46A-DBB76F579F98}.Release|Win32.ActiveCfg = Release|Win32
   13.22 -		{E38F65D9-74B2-4373-B46A-DBB76F579F98}.Release|Win32.Build.0 = Release|Win32
   13.23 +		{E38F65D9-74B2-4373-B46A-DBB76F579F98}.Debug - Episode 1|Win32.ActiveCfg = Debug - Episode 1|Win32
   13.24 +		{E38F65D9-74B2-4373-B46A-DBB76F579F98}.Debug - Episode 1|Win32.Build.0 = Debug - Episode 1|Win32
   13.25 +		{E38F65D9-74B2-4373-B46A-DBB76F579F98}.Debug - Left 4 Dead|Win32.ActiveCfg = Debug - Left 4 Dead|Win32
   13.26 +		{E38F65D9-74B2-4373-B46A-DBB76F579F98}.Debug - Left 4 Dead|Win32.Build.0 = Debug - Left 4 Dead|Win32
   13.27 +		{E38F65D9-74B2-4373-B46A-DBB76F579F98}.Debug - Old Metamod|Win32.ActiveCfg = Debug - Old Metamod|Win32
   13.28 +		{E38F65D9-74B2-4373-B46A-DBB76F579F98}.Debug - Old Metamod|Win32.Build.0 = Debug - Old Metamod|Win32
   13.29 +		{E38F65D9-74B2-4373-B46A-DBB76F579F98}.Debug - Orange Box|Win32.ActiveCfg = Debug - Orange Box|Win32
   13.30 +		{E38F65D9-74B2-4373-B46A-DBB76F579F98}.Debug - Orange Box|Win32.Build.0 = Debug - Orange Box|Win32
   13.31 +		{E38F65D9-74B2-4373-B46A-DBB76F579F98}.Release - Episode 1|Win32.ActiveCfg = Release - Episode 1|Win32
   13.32 +		{E38F65D9-74B2-4373-B46A-DBB76F579F98}.Release - Episode 1|Win32.Build.0 = Release - Episode 1|Win32
   13.33 +		{E38F65D9-74B2-4373-B46A-DBB76F579F98}.Release - Left 4 Dead|Win32.ActiveCfg = Release - Left 4 Dead|Win32
   13.34 +		{E38F65D9-74B2-4373-B46A-DBB76F579F98}.Release - Left 4 Dead|Win32.Build.0 = Release - Left 4 Dead|Win32
   13.35 +		{E38F65D9-74B2-4373-B46A-DBB76F579F98}.Release - Old Metamod|Win32.ActiveCfg = Release - Old Metamod|Win32
   13.36 +		{E38F65D9-74B2-4373-B46A-DBB76F579F98}.Release - Old Metamod|Win32.Build.0 = Release - Old Metamod|Win32
   13.37 +		{E38F65D9-74B2-4373-B46A-DBB76F579F98}.Release - Orange Box|Win32.ActiveCfg = Release - Orange Box|Win32
   13.38 +		{E38F65D9-74B2-4373-B46A-DBB76F579F98}.Release - Orange Box|Win32.Build.0 = Release - Orange Box|Win32
   13.39  	EndGlobalSection
   13.40  	GlobalSection(SolutionProperties) = preSolution
   13.41  		HideSolutionNode = FALSE
    14.1 --- a/extensions/bintools/msvc9/bintools.vcproj	Wed Jan 07 22:55:40 2009 -0500
    14.2 +++ b/extensions/bintools/msvc9/bintools.vcproj	Thu Jan 08 18:17:17 2009 +1300
    14.3 @@ -17,7 +17,7 @@
    14.4  	</ToolFiles>
    14.5  	<Configurations>
    14.6  		<Configuration
    14.7 -			Name="Debug|Win32"
    14.8 +			Name="Debug - Orange Box|Win32"
    14.9  			OutputDirectory="$(SolutionDir)$(ConfigurationName)"
   14.10  			IntermediateDirectory="$(ConfigurationName)"
   14.11  			ConfigurationType="2"
   14.12 @@ -40,9 +40,10 @@
   14.13  			/>
   14.14  			<Tool
   14.15  				Name="VCCLCompilerTool"
   14.16 +				AdditionalOptions="/D SE_EPISODEONE=2 /D SE_ORANGEBOX=3 /D SE_LEFT4DEAD=4"
   14.17  				Optimization="0"
   14.18 -				AdditionalIncludeDirectories="..;..\sdk;..\..\..\public;..\..\..\public\extensions;..\..\..\public\jit;..\..\..\public\jit\x86;..\..\..\public\sourcepawn"
   14.19 -				PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;BINTOOLS_EXPORTS;_CRT_SECURE_NO_DEPRECATE;SOURCEMOD_BUILD"
   14.20 +				AdditionalIncludeDirectories="..;..\sdk;..\..\..\public;..\..\..\public\jit;..\..\..\public\jit\x86;..\..\..\public\extensions;..\..\..\public\sourcepawn;&quot;$(MMSOURCE17)\core&quot;;&quot;$(MMSOURCE17)\core\sourcehook&quot;;&quot;$(HL2SDKOB)\public&quot;;&quot;$(HL2SDKOB)\public\tier0&quot;;&quot;$(HL2SDKOB)\public\tier1&quot;"
   14.21 +				PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;BINTOOLS_EXPORTS;_CRT_SECURE_NO_DEPRECATE;SOURCEMOD_BUILD;ORANGEBOX_BUILD;HOOKING_ENABLED;SOURCE_ENGINE=3"
   14.22  				MinimalRebuild="true"
   14.23  				BasicRuntimeChecks="3"
   14.24  				RuntimeLibrary="1"
   14.25 @@ -64,6 +65,7 @@
   14.26  			/>
   14.27  			<Tool
   14.28  				Name="VCLinkerTool"
   14.29 +				AdditionalDependencies="&quot;$(HL2SDKOB)\lib\public\tier0.lib&quot; &quot;$(HL2SDKOB)\lib\public\tier1.lib&quot; &quot;$(HL2SDKOB)\lib\public\vstdlib.lib&quot; &quot;$(HL2SDKOB)\lib\public\mathlib.lib&quot;"
   14.30  				OutputFile="$(OutDir)\bintools.ext.dll"
   14.31  				LinkIncremental="2"
   14.32  				IgnoreDefaultLibraryNames="LIBC;LIBCD;LIBCMT"
   14.33 @@ -96,7 +98,7 @@
   14.34  			/>
   14.35  		</Configuration>
   14.36  		<Configuration
   14.37 -			Name="Release|Win32"
   14.38 +			Name="Release - Orange Box|Win32"
   14.39  			OutputDirectory="$(SolutionDir)$(ConfigurationName)"
   14.40  			IntermediateDirectory="$(ConfigurationName)"
   14.41  			ConfigurationType="2"
   14.42 @@ -120,9 +122,10 @@
   14.43  			/>
   14.44  			<Tool
   14.45  				Name="VCCLCompilerTool"
   14.46 +				AdditionalOptions="/MP /D SE_EPISODEONE=2 /D SE_ORANGEBOX=3 /D SE_LEFT4DEAD=4"
   14.47  				FavorSizeOrSpeed="1"
   14.48 -				AdditionalIncludeDirectories="..;..\sdk;..\..\..\public;..\..\..\public\extensions;..\..\..\public\jit;..\..\..\public\jit\x86;..\..\..\public\sourcepawn"
   14.49 -				PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;BINTOOLS_EXPORTS;_CRT_SECURE_NO_DEPRECATE;SOURCEMOD_BUILD"
   14.50 +				AdditionalIncludeDirectories="..;..\sdk;..\..\..\public;..\..\..\public\jit;..\..\..\public\jit\x86;..\..\..\public\extensions;..\..\..\public\sourcepawn;&quot;$(MMSOURCE17)\core&quot;;&quot;$(MMSOURCE17)\core\sourcehook&quot;;&quot;$(HL2SDKOB)\public&quot;;&quot;$(HL2SDKOB)\public\tier0&quot;;&quot;$(HL2SDKOB)\public\tier1&quot;"
   14.51 +				PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;BINTOOLS_EXPORTS;_CRT_SECURE_NO_DEPRECATE;SOURCEMOD_BUILD;SOURCE_ENGINE=3"
   14.52  				RuntimeLibrary="0"
   14.53  				EnableEnhancedInstructionSet="1"
   14.54  				RuntimeTypeInfo="false"
   14.55 @@ -142,6 +145,472 @@
   14.56  			/>
   14.57  			<Tool
   14.58  				Name="VCLinkerTool"
   14.59 +				AdditionalDependencies="&quot;$(HL2SDKOB)\lib\public\tier0.lib&quot; &quot;$(HL2SDKOB)\lib\public\tier1.lib&quot; &quot;$(HL2SDKOB)\lib\public\vstdlib.lib&quot; &quot;$(HL2SDKOB)\lib\public\mathlib.lib&quot;"
   14.60 +				OutputFile="$(OutDir)\bintools.ext.dll"
   14.61 +				LinkIncremental="1"
   14.62 +				IgnoreDefaultLibraryNames="LIBC;LIBCD;LIBCMTD"
   14.63 +				GenerateDebugInformation="true"
   14.64 +				SubSystem="2"
   14.65 +				OptimizeReferences="2"
   14.66 +				EnableCOMDATFolding="2"
   14.67 +				RandomizedBaseAddress="1"
   14.68 +				DataExecutionPrevention="0"
   14.69 +				TargetMachine="1"
   14.70 +			/>
   14.71 +			<Tool
   14.72 +				Name="VCALinkTool"
   14.73 +			/>
   14.74 +			<Tool
   14.75 +				Name="VCManifestTool"
   14.76 +			/>
   14.77 +			<Tool
   14.78 +				Name="VCXDCMakeTool"
   14.79 +			/>
   14.80 +			<Tool
   14.81 +				Name="VCBscMakeTool"
   14.82 +			/>
   14.83 +			<Tool
   14.84 +				Name="VCFxCopTool"
   14.85 +			/>
   14.86 +			<Tool
   14.87 +				Name="VCAppVerifierTool"
   14.88 +			/>
   14.89 +			<Tool
   14.90 +				Name="VCPostBuildEventTool"
   14.91 +			/>
   14.92 +		</Configuration>
   14.93 +		<Configuration
   14.94 +			Name="Debug - Left 4 Dead|Win32"
   14.95 +			OutputDirectory="$(SolutionDir)$(ConfigurationName)"
   14.96 +			IntermediateDirectory="$(ConfigurationName)"
   14.97 +			ConfigurationType="2"
   14.98 +			CharacterSet="2"
   14.99 +			>
  14.100 +			<Tool
  14.101 +				Name="VCPreBuildEventTool"
  14.102 +			/>
  14.103 +			<Tool
  14.104 +				Name="VCCustomBuildTool"
  14.105 +			/>
  14.106 +			<Tool
  14.107 +				Name="VCXMLDataGeneratorTool"
  14.108 +			/>
  14.109 +			<Tool
  14.110 +				Name="VCWebServiceProxyGeneratorTool"
  14.111 +			/>
  14.112 +			<Tool
  14.113 +				Name="VCMIDLTool"
  14.114 +			/>
  14.115 +			<Tool
  14.116 +				Name="VCCLCompilerTool"
  14.117 +				AdditionalOptions="/D SE_EPISODEONE=2 /D SE_ORANGEBOX=3 /D SE_LEFT4DEAD=4"
  14.118 +				AdditionalIncludeDirectories="..;..\sdk;..\..\..\public;..\..\..\public\jit;..\..\..\public\jit\x86;..\..\..\public\extensions;..\..\..\public\sourcepawn;&quot;$(MMSOURCE17)\core&quot;;&quot;$(MMSOURCE17)\core\sourcehook&quot;;&quot;$(HL2SDKL4D)\public&quot;;&quot;$(HL2SDKL4D)\public\tier0&quot;;&quot;$(HL2SDKL4D)\public\tier1&quot;"
  14.119 +				PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;BINTOOLS_EXPORTS;_CRT_SECURE_NO_DEPRECATE;SOURCEMOD_BUILD;HOOKING_ENABLED;SOURCE_ENGINE=4"
  14.120 +				MinimalRebuild="true"
  14.121 +				BasicRuntimeChecks="3"
  14.122 +				RuntimeLibrary="1"
  14.123 +				EnableEnhancedInstructionSet="1"
  14.124 +				WarningLevel="3"
  14.125 +				DebugInformationFormat="4"
  14.126 +			/>
  14.127 +			<Tool
  14.128 +				Name="VCManagedResourceCompilerTool"
  14.129 +			/>
  14.130 +			<Tool
  14.131 +				Name="VCResourceCompilerTool"
  14.132 +			/>
  14.133 +			<Tool
  14.134 +				Name="VCPreLinkEventTool"
  14.135 +			/>
  14.136 +			<Tool
  14.137 +				Name="VCLinkerTool"
  14.138 +				AdditionalDependencies="&quot;$(HL2SDKL4D)\lib\public\tier0.lib&quot; &quot;$(HL2SDKL4D)\lib\public\tier1.lib&quot; &quot;$(HL2SDKL4D)\lib\public\vstdlib.lib&quot; &quot;$(HL2SDKL4D)\lib\public\mathlib.lib&quot;"
  14.139 +				OutputFile="$(OutDir)\bintools.ext.dll"
  14.140 +				LinkIncremental="2"
  14.141 +				IgnoreDefaultLibraryNames="LIBC;LIBCD;LIBCMT"
  14.142 +				GenerateDebugInformation="true"
  14.143 +			/>
  14.144 +			<Tool
  14.145 +				Name="VCALinkTool"
  14.146 +			/>
  14.147 +			<Tool
  14.148 +				Name="VCManifestTool"
  14.149 +			/>
  14.150 +			<Tool
  14.151 +				Name="VCXDCMakeTool"
  14.152 +			/>
  14.153 +			<Tool
  14.154 +				Name="VCBscMakeTool"
  14.155 +			/>
  14.156 +			<Tool
  14.157 +				Name="VCFxCopTool"
  14.158 +			/>
  14.159 +			<Tool
  14.160 +				Name="VCAppVerifierTool"
  14.161 +			/>
  14.162 +			<Tool
  14.163 +				Name="VCPostBuildEventTool"
  14.164 +			/>
  14.165 +		</Configuration>
  14.166 +		<Configuration
  14.167 +			Name="Debug - Old Metamod|Win32"
  14.168 +			OutputDirectory="$(SolutionDir)$(ConfigurationName)"
  14.169 +			IntermediateDirectory="$(ConfigurationName)"
  14.170 +			ConfigurationType="2"
  14.171 +			CharacterSet="2"
  14.172 +			>
  14.173 +			<Tool
  14.174 +				Name="VCPreBuildEventTool"
  14.175 +			/>
  14.176 +			<Tool
  14.177 +				Name="VCCustomBuildTool"
  14.178 +			/>
  14.179 +			<Tool
  14.180 +				Name="VCXMLDataGeneratorTool"
  14.181 +			/>
  14.182 +			<Tool
  14.183 +				Name="VCWebServiceProxyGeneratorTool"
  14.184 +			/>
  14.185 +			<Tool
  14.186 +				Name="VCMIDLTool"
  14.187 +			/>
  14.188 +			<Tool
  14.189 +				Name="VCCLCompilerTool"
  14.190 +				AdditionalOptions="/D SE_EPISODEONE=2 /D SE_ORANGEBOX=3 /D SE_LEFT4DEAD=4"
  14.191 +				AdditionalIncludeDirectories="..;..\sdk;..\..\..\public;..\..\..\public\jit;..\..\..\public\jit\x86;..\..\..\public\extensions;..\..\..\public\sourcepawn;&quot;$(MMSOURCE17)\core\sourcehook&quot;;&quot;$(HL2SDK)\public&quot;;&quot;$(HL2SDK)\public\tier0&quot;;&quot;$(HL2SDK)\public\tier1&quot;"
  14.192 +				PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;BINTOOLS_EXPORTS;_CRT_SECURE_NO_DEPRECATE;SOURCEMOD_BUILD;SOURCE_ENGINE=2"
  14.193 +				MinimalRebuild="true"
  14.194 +				BasicRuntimeChecks="3"
  14.195 +				RuntimeLibrary="1"
  14.196 +				EnableEnhancedInstructionSet="1"
  14.197 +				WarningLevel="3"
  14.198 +				DebugInformationFormat="4"
  14.199 +			/>
  14.200 +			<Tool
  14.201 +				Name="VCManagedResourceCompilerTool"
  14.202 +			/>
  14.203 +			<Tool
  14.204 +				Name="VCResourceCompilerTool"
  14.205 +			/>
  14.206 +			<Tool
  14.207 +				Name="VCPreLinkEventTool"
  14.208 +			/>
  14.209 +			<Tool
  14.210 +				Name="VCLinkerTool"
  14.211 +				AdditionalDependencies="&quot;$(HL2SDK)\lib\public\tier0.lib&quot; &quot;$(HL2SDK)\lib\public\tier1.lib&quot; &quot;$(HL2SDK)\lib\public\vstdlib.lib&quot; &quot;$(HL2SDK)\lib\public\mathlib.lib&quot;"
  14.212 +				OutputFile="$(OutDir)\bintools.ext.dll"
  14.213 +				LinkIncremental="2"
  14.214 +				IgnoreDefaultLibraryNames="LIBC;LIBCD;LIBCMT"
  14.215 +				GenerateDebugInformation="true"
  14.216 +			/>
  14.217 +			<Tool
  14.218 +				Name="VCALinkTool"
  14.219 +			/>
  14.220 +			<Tool
  14.221 +				Name="VCManifestTool"
  14.222 +			/>
  14.223 +			<Tool
  14.224 +				Name="VCXDCMakeTool"
  14.225 +			/>
  14.226 +			<Tool
  14.227 +				Name="VCBscMakeTool"
  14.228 +			/>
  14.229 +			<Tool
  14.230 +				Name="VCFxCopTool"
  14.231 +			/>
  14.232 +			<Tool
  14.233 +				Name="VCAppVerifierTool"
  14.234 +			/>
  14.235 +			<Tool
  14.236 +				Name="VCPostBuildEventTool"
  14.237 +			/>
  14.238 +		</Configuration>
  14.239 +		<Configuration
  14.240 +			Name="Debug - Episode 1|Win32"
  14.241 +			OutputDirectory="$(SolutionDir)$(ConfigurationName)"
  14.242 +			IntermediateDirectory="$(ConfigurationName)"
  14.243 +			ConfigurationType="2"
  14.244 +			CharacterSet="2"
  14.245 +			>
  14.246 +			<Tool
  14.247 +				Name="VCPreBuildEventTool"
  14.248 +			/>
  14.249 +			<Tool
  14.250 +				Name="VCCustomBuildTool"
  14.251 +			/>
  14.252 +			<Tool
  14.253 +				Name="VCXMLDataGeneratorTool"
  14.254 +			/>
  14.255 +			<Tool
  14.256 +				Name="VCWebServiceProxyGeneratorTool"
  14.257 +			/>
  14.258 +			<Tool
  14.259 +				Name="VCMIDLTool"
  14.260 +			/>
  14.261 +			<Tool
  14.262 +				Name="VCCLCompilerTool"
  14.263 +				AdditionalOptions="/D SE_EPISODEONE=2 /D SE_ORANGEBOX=3 /D SE_LEFT4DEAD=4"
  14.264 +				AdditionalIncludeDirectories="..;..\sdk;..\..\..\public;..\..\..\public\jit;..\..\..\public\jit\x86;..\..\..\public\extensions;..\..\..\public\sourcepawn;&quot;$(MMSOURCE17)\core&quot;;&quot;$(MMSOURCE17)\core\sourcehook&quot;;&quot;$(HL2SDK)\public&quot;;&quot;$(HL2SDK)\public\tier0&quot;;&quot;$(HL2SDK)\public\tier1&quot;"
  14.265 +				PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;BINTOOLS_EXPORTS;_CRT_SECURE_NO_DEPRECATE;SOURCEMOD_BUILD;HOOKING_ENABLED;SOURCE_ENGINE=2"
  14.266 +				MinimalRebuild="true"
  14.267 +				BasicRuntimeChecks="3"
  14.268 +				RuntimeLibrary="1"
  14.269 +				EnableEnhancedInstructionSet="1"
  14.270 +				WarningLevel="3"
  14.271 +				DebugInformationFormat="4"
  14.272 +			/>
  14.273 +			<Tool
  14.274 +				Name="VCManagedResourceCompilerTool"
  14.275 +			/>
  14.276 +			<Tool
  14.277 +				Name="VCResourceCompilerTool"
  14.278 +			/>
  14.279 +			<Tool
  14.280 +				Name="VCPreLinkEventTool"
  14.281 +			/>
  14.282 +			<Tool
  14.283 +				Name="VCLinkerTool"
  14.284 +				AdditionalDependencies="&quot;$(HL2SDK)\lib\public\tier0.lib&quot; &quot;$(HL2SDK)\lib\public\tier1.lib&quot; &quot;$(HL2SDK)\lib\public\vstdlib.lib&quot; &quot;$(HL2SDK)\lib\public\mathlib.lib&quot;"
  14.285 +				OutputFile="$(OutDir)\bintools.ext.dll"
  14.286 +				LinkIncremental="2"
  14.287 +				IgnoreDefaultLibraryNames="LIBC;LIBCD;LIBCMT"
  14.288 +				GenerateDebugInformation="true"
  14.289 +			/>
  14.290 +			<Tool
  14.291 +				Name="VCALinkTool"
  14.292 +			/>
  14.293 +			<Tool
  14.294 +				Name="VCManifestTool"
  14.295 +			/>
  14.296 +			<Tool
  14.297 +				Name="VCXDCMakeTool"
  14.298 +			/>
  14.299 +			<Tool
  14.300 +				Name="VCBscMakeTool"
  14.301 +			/>
  14.302 +			<Tool
  14.303 +				Name="VCFxCopTool"
  14.304 +			/>
  14.305 +			<Tool
  14.306 +				Name="VCAppVerifierTool"
  14.307 +			/>
  14.308 +			<Tool
  14.309 +				Name="VCPostBuildEventTool"
  14.310 +			/>
  14.311 +		</Configuration>
  14.312 +		<Configuration
  14.313 +			Name="Release - Left 4 Dead|Win32"
  14.314 +			OutputDirectory="$(SolutionDir)$(ConfigurationName)"
  14.315 +			IntermediateDirectory="$(ConfigurationName)"
  14.316 +			ConfigurationType="2"
  14.317 +			CharacterSet="2"
  14.318 +			WholeProgramOptimization="1"
  14.319 +			>
  14.320 +			<Tool
  14.321 +				Name="VCPreBuildEventTool"
  14.322 +			/>
  14.323 +			<Tool
  14.324 +				Name="VCCustomBuildTool"
  14.325 +			/>
  14.326 +			<Tool
  14.327 +				Name="VCXMLDataGeneratorTool"
  14.328 +			/>
  14.329 +			<Tool
  14.330 +				Name="VCWebServiceProxyGeneratorTool"
  14.331 +			/>
  14.332 +			<Tool
  14.333 +				Name="VCMIDLTool"
  14.334 +			/>
  14.335 +			<Tool
  14.336 +				Name="VCCLCompilerTool"
  14.337 +				AdditionalOptions="/D SE_EPISODEONE=2 /D SE_ORANGEBOX=3 /D SE_LEFT4DEAD=4"
  14.338 +				FavorSizeOrSpeed="1"
  14.339 +				AdditionalIncludeDirectories="..;..\sdk;..\..\..\public;..\..\..\public\jit;..\..\..\public\jit\x86;..\..\..\public\extensions;..\..\..\public\sourcepawn;&quot;$(MMSOURCE17)\core&quot;;&quot;$(MMSOURCE17)\core\sourcehook&quot;;&quot;$(HL2SDKL4D)\public&quot;;&quot;$(HL2SDKL4D)\public\tier0&quot;;&quot;$(HL2SDKL4D)\public\tier1&quot;"
  14.340 +				PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;BINTOOLS_EXPORTS;_CRT_SECURE_NO_DEPRECATE;SOURCEMOD_BUILD;HOOKING_ENABLED;SOURCE_ENGINE=4"
  14.341 +				RuntimeLibrary="0"
  14.342 +				EnableEnhancedInstructionSet="1"
  14.343 +				RuntimeTypeInfo="false"
  14.344 +				UsePrecompiledHeader="0"
  14.345 +				WarningLevel="3"
  14.346 +				Detect64BitPortabilityProblems="false"
  14.347 +				DebugInformationFormat="3"
  14.348 +			/>
  14.349 +			<Tool
  14.350 +				Name="VCManagedResourceCompilerTool"
  14.351 +			/>
  14.352 +			<Tool
  14.353 +				Name="VCResourceCompilerTool"
  14.354 +			/>
  14.355 +			<Tool
  14.356 +				Name="VCPreLinkEventTool"
  14.357 +			/>
  14.358 +			<Tool
  14.359 +				Name="VCLinkerTool"
  14.360 +				AdditionalDependencies="&quot;$(HL2SDKL4D)\lib\public\tier0.lib&quot; &quot;$(HL2SDKL4D)\lib\public\tier1.lib&quot; &quot;$(HL2SDKL4D)\lib\public\vstdlib.lib&quot; &quot;$(HL2SDKL4D)\lib\public\mathlib.lib&quot;"
  14.361 +				OutputFile="$(OutDir)\bintools.ext.dll"
  14.362 +				LinkIncremental="1"
  14.363 +				IgnoreDefaultLibraryNames="LIBC;LIBCD;LIBCMTD"
  14.364 +				GenerateDebugInformation="true"
  14.365 +				SubSystem="2"
  14.366 +				OptimizeReferences="2"
  14.367 +				EnableCOMDATFolding="2"
  14.368 +				RandomizedBaseAddress="1"
  14.369 +				DataExecutionPrevention="0"
  14.370 +				TargetMachine="1"
  14.371 +			/>
  14.372 +			<Tool
  14.373 +				Name="VCALinkTool"
  14.374 +			/>
  14.375 +			<Tool
  14.376 +				Name="VCManifestTool"
  14.377 +			/>
  14.378 +			<Tool
  14.379 +				Name="VCXDCMakeTool"
  14.380 +			/>
  14.381 +			<Tool
  14.382 +				Name="VCBscMakeTool"
  14.383 +			/>
  14.384 +			<Tool
  14.385 +				Name="VCFxCopTool"
  14.386 +			/>
  14.387 +			<Tool
  14.388 +				Name="VCAppVerifierTool"
  14.389 +			/>
  14.390 +			<Tool
  14.391 +				Name="VCPostBuildEventTool"
  14.392 +			/>
  14.393 +		</Configuration>
  14.394 +		<Configuration
  14.395 +			Name="Release - Old Metamod|Win32"
  14.396 +			OutputDirectory="$(SolutionDir)$(ConfigurationName)"
  14.397 +			IntermediateDirectory="$(ConfigurationName)"
  14.398 +			ConfigurationType="2"
  14.399 +			CharacterSet="2"
  14.400 +			WholeProgramOptimization="1"
  14.401 +			>
  14.402 +			<Tool
  14.403 +				Name="VCPreBuildEventTool"
  14.404 +			/>
  14.405 +			<Tool
  14.406 +				Name="VCCustomBuildTool"
  14.407 +			/>
  14.408 +			<Tool
  14.409 +				Name="VCXMLDataGeneratorTool"
  14.410 +			/>
  14.411 +			<Tool
  14.412 +				Name="VCWebServiceProxyGeneratorTool"
  14.413 +			/>
  14.414 +			<Tool
  14.415 +				Name="VCMIDLTool"
  14.416 +			/>
  14.417 +			<Tool
  14.418 +				Name="VCCLCompilerTool"
  14.419 +				AdditionalOptions="/D SE_EPISODEONE=2 /D SE_ORANGEBOX=3 /D SE_LEFT4DEAD=4"
  14.420 +				FavorSizeOrSpeed="1"
  14.421 +				AdditionalIncludeDirectories="..;..\sdk;..\..\..\public;..\..\..\public\jit;..\..\..\public\jit\x86;..\..\..\public\extensions;..\..\..\public\sourcepawn;&quot;$(MMSOURCE17)\core\sourcehook&quot;;&quot;$(HL2SDK)\public&quot;;&quot;$(HL2SDK)\public\tier0&quot;;&quot;$(HL2SDK)\public\tier1&quot;"
  14.422 +				PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;BINTOOLS_EXPORTS;_CRT_SECURE_NO_DEPRECATE;SOURCEMOD_BUILD;SOURCE_ENGINE=2"
  14.423 +				RuntimeLibrary="0"
  14.424 +				EnableEnhancedInstructionSet="1"
  14.425 +				RuntimeTypeInfo="false"
  14.426 +				UsePrecompiledHeader="0"
  14.427 +				WarningLevel="3"
  14.428 +				Detect64BitPortabilityProblems="false"
  14.429 +				DebugInformationFormat="3"
  14.430 +			/>
  14.431 +			<Tool
  14.432 +				Name="VCManagedResourceCompilerTool"
  14.433 +			/>
  14.434 +			<Tool
  14.435 +				Name="VCResourceCompilerTool"
  14.436 +			/>
  14.437 +			<Tool
  14.438 +				Name="VCPreLinkEventTool"
  14.439 +			/>
  14.440 +			<Tool
  14.441 +				Name="VCLinkerTool"
  14.442 +				AdditionalDependencies="&quot;$(HL2SDK)\lib\public\tier0.lib&quot; &quot;$(HL2SDK)\lib\public\tier1.lib&quot; &quot;$(HL2SDK)\lib\public\vstdlib.lib&quot; &quot;$(HL2SDK)\lib\public\mathlib.lib&quot;"
  14.443 +				OutputFile="$(OutDir)\bintools.ext.dll"
  14.444 +				LinkIncremental="1"
  14.445 +				IgnoreDefaultLibraryNames="LIBC;LIBCD;LIBCMTD"
  14.446 +				GenerateDebugInformation="true"
  14.447 +				SubSystem="2"
  14.448 +				OptimizeReferences="2"
  14.449 +				EnableCOMDATFolding="2"
  14.450 +				RandomizedBaseAddress="1"
  14.451 +				DataExecutionPrevention="0"
  14.452 +				TargetMachine="1"
  14.453 +			/>
  14.454 +			<Tool
  14.455 +				Name="VCALinkTool"
  14.456 +			/>
  14.457 +			<Tool
  14.458 +				Name="VCManifestTool"
  14.459 +			/>
  14.460 +			<Tool
  14.461 +				Name="VCXDCMakeTool"
  14.462 +			/>
  14.463 +			<Tool
  14.464 +				Name="VCBscMakeTool"
  14.465 +			/>
  14.466 +			<Tool
  14.467 +				Name="VCFxCopTool"
  14.468 +			/>
  14.469 +			<Tool
  14.470 +				Name="VCAppVerifierTool"
  14.471 +			/>
  14.472 +			<Tool
  14.473 +				Name="VCPostBuildEventTool"
  14.474 +			/>
  14.475 +		</Configuration>
  14.476 +		<Configuration
  14.477 +			Name="Release - Episode 1|Win32"
  14.478 +			OutputDirectory="$(SolutionDir)$(ConfigurationName)"
  14.479 +			IntermediateDirectory="$(ConfigurationName)"
  14.480 +			ConfigurationType="2"
  14.481 +			CharacterSet="2"
  14.482 +			WholeProgramOptimization="1"
  14.483 +			>
  14.484 +			<Tool
  14.485 +				Name="VCPreBuildEventTool"
  14.486 +			/>
  14.487 +			<Tool
  14.488 +				Name="VCCustomBuildTool"
  14.489 +			/>
  14.490 +			<Tool
  14.491 +				Name="VCXMLDataGeneratorTool"
  14.492 +			/>
  14.493 +			<Tool
  14.494 +				Name="VCWebServiceProxyGeneratorTool"
  14.495 +			/>
  14.496 +			<Tool
  14.497 +				Name="VCMIDLTool"
  14.498 +			/>
  14.499 +			<Tool
  14.500 +				Name="VCCLCompilerTool"
  14.501 +				AdditionalOptions="/D SE_EPISODEONE=2 /D SE_ORANGEBOX=3 /D SE_LEFT4DEAD=4"
  14.502 +				FavorSizeOrSpeed="1"
  14.503 +				AdditionalIncludeDirectories="..;..\sdk;..\..\..\public;..\..\..\public\jit;..\..\..\public\jit\x86;..\..\..\public\extensions;..\..\..\public\sourcepawn;&quot;$(MMSOURCE17)\core&quot;;&quot;$(MMSOURCE17)\core\sourcehook&quot;;&quot;$(HL2SDK)\public&quot;;&quot;$(HL2SDK)\public\tier0&quot;;&quot;$(HL2SDK)\public\tier1&quot;"
  14.504 +				PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;BINTOOLS_EXPORTS;_CRT_SECURE_NO_DEPRECATE;SOURCEMOD_BUILD;HOOKING_ENABLED;SOURCE_ENGINE=2"
  14.505 +				RuntimeLibrary="0"
  14.506 +				EnableEnhancedInstructionSet="1"
  14.507 +				RuntimeTypeInfo="false"
  14.508 +				UsePrecompiledHeader="0"
  14.509 +				WarningLevel="3"
  14.510 +				Detect64BitPortabilityProblems="false"
  14.511 +				DebugInformationFormat="3"
  14.512 +			/>
  14.513 +			<Tool
  14.514 +				Name="VCManagedResourceCompilerTool"
  14.515 +			/>
  14.516 +			<Tool
  14.517 +				Name="VCResourceCompilerTool"
  14.518 +			/>
  14.519 +			<Tool
  14.520 +				Name="VCPreLinkEventTool"
  14.521 +			/>
  14.522 +			<Tool
  14.523 +				Name="VCLinkerTool"
  14.524 +				AdditionalDependencies="&quot;$(HL2SDK)\lib\public\tier0.lib&quot; &quot;$(HL2SDK)\lib\public\tier1.lib&quot; &quot;$(HL2SDK)\lib\public\vstdlib.lib&quot; &quot;$(HL2SDK)\lib\public\mathlib.lib&quot;"
  14.525  				OutputFile="$(OutDir)\bintools.ext.dll"
  14.526  				LinkIncremental="1"
  14.527  				IgnoreDefaultLibraryNames="LIBC;LIBCD;LIBCMTD"
  14.528 @@ -227,7 +696,11 @@
  14.529  					>
  14.530  				</File>
  14.531  				<File
  14.532 -					RelativePath="..\jit_call.h"
  14.533 +					RelativePath="..\HookWrapper.h"
  14.534 +					>
  14.535 +				</File>
  14.536 +				<File
  14.537 +					RelativePath="..\jit_compile.h"
  14.538  					>
  14.539  				</File>
  14.540  			</Filter>
  14.541 @@ -245,9 +718,17 @@
  14.542  					>
  14.543  				</File>
  14.544  				<File
  14.545 +					RelativePath="..\HookWrapper.cpp"
  14.546 +					>
  14.547 +				</File>
  14.548 +				<File
  14.549  					RelativePath="..\jit_call.cpp"
  14.550  					>
  14.551  				</File>
  14.552 +				<File
  14.553 +					RelativePath="..\jit_hook.cpp"
  14.554 +					>
  14.555 +				</File>
  14.556  			</Filter>
  14.557  		</Filter>
  14.558  		<Filter
    15.1 --- a/extensions/bintools/sdk/smsdk_config.h	Wed Jan 07 22:55:40 2009 -0500
    15.2 +++ b/extensions/bintools/sdk/smsdk_config.h	Thu Jan 08 18:17:17 2009 +1300
    15.3 @@ -57,7 +57,9 @@
    15.4   * @brief Sets whether or not this plugin required Metamod.
    15.5   * NOTE: Uncomment to enable, comment to disable.
    15.6   */
    15.7 -//#define SMEXT_CONF_METAMOD		
    15.8 +#if defined HOOKING_ENABLED
    15.9 +#define SMEXT_CONF_METAMOD
   15.10 +#endif
   15.11  
   15.12  /** Enable interfaces you want to use here by uncommenting lines */
   15.13  //#define SMEXT_ENABLE_FORWARDSYS
   15.14 @@ -65,5 +67,17 @@
   15.15  //#define SMEXT_ENABLE_PLAYERHELPERS
   15.16  //#define SMEXT_ENABLE_DBMANAGER
   15.17  //#define SMEXT_ENABLE_GAMECONF
   15.18 +//#define SMEXT_ENABLE_MEMUTILS
   15.19 +//#define SMEXT_ENABLE_GAMEHELPERS
   15.20 +//#define SMEXT_ENABLE_TIMERSYS
   15.21 +//#define SMEXT_ENABLE_THREADER
   15.22 +//#define SMEXT_ENABLE_LIBSYS
   15.23 +//#define SMEXT_ENABLE_MENUS
   15.24 +//#define SMEXT_ENABLE_ADTFACTORY
   15.25 +//#define SMEXT_ENABLE_PLUGINSYS
   15.26 +//#define SMEXT_ENABLE_ADMINSYS
   15.27 +//#define SMEXT_ENABLE_TEXTPARSERS
   15.28 +//#define SMEXT_ENABLE_USERMSGS
   15.29 +//#define SMEXT_ENABLE_TRANSLATOR
   15.30  
   15.31  #endif // _INCLUDE_SOURCEMOD_EXTENSION_CONFIG_H_
    16.1 --- a/extensions/bintools/sdk/smsdk_ext.cpp	Wed Jan 07 22:55:40 2009 -0500
    16.2 +++ b/extensions/bintools/sdk/smsdk_ext.cpp	Thu Jan 08 18:17:17 2009 +1300
    16.3 @@ -97,6 +97,24 @@
    16.4  #if defined SMEXT_ENABLE_TRANSLATOR
    16.5  ITranslator *translator = NULL;
    16.6  #endif
    16.7 +#if defined SMEXT_ENABLE_PLUGINSYS
    16.8 +SourceMod::IPluginManager *plsys;
    16.9 +#endif
   16.10 +#if defined SMEXT_ENABLE_MENUS
   16.11 +IMenuManager *menus = NULL;
   16.12 +#endif
   16.13 +#if defined SMEXT_ENABLE_ADMINSYS
   16.14 +IAdminSystem *adminsys = NULL;
   16.15 +#endif
   16.16 +#if defined SMEXT_ENABLE_TEXTPARSERS
   16.17 +ITextParsers *textparsers = NULL;
   16.18 +#endif
   16.19 +#if defined SMEXT_ENABLE_USERMSGS
   16.20 +IUserMessages *usermsgs = NULL;
   16.21 +#endif
   16.22 +#if defined SMEXT_ENABLE_TRANSLATOR
   16.23 +ITranslator *translator = NULL;
   16.24 +#endif
   16.25  
   16.26  /** Exports the main interface */
   16.27  PLATFORM_EXTERN_C IExtensionInterface *GetSMExtAPI()
   16.28 @@ -185,6 +203,24 @@
   16.29  #if defined SMEXT_ENABLE_TRANSLATOR
   16.30  	SM_GET_IFACE(TRANSLATOR, translator);
   16.31  #endif
   16.32 +#if defined SMEXT_ENABLE_PLUGINSYS
   16.33 +	SM_GET_IFACE(PLUGINSYSTEM, plsys);
   16.34 +#endif
   16.35 +#if defined SMEXT_ENABLE_MENUS
   16.36 +	SM_GET_IFACE(MENUMANAGER, menus);
   16.37 +#endif
   16.38 +#if defined SMEXT_ENABLE_ADMINSYS
   16.39 +	SM_GET_IFACE(ADMINSYS, adminsys);
   16.40 +#endif
   16.41 +#if defined SMEXT_ENABLE_TEXTPARSERS
   16.42 +	SM_GET_IFACE(TEXTPARSERS, textparsers);
   16.43 +#endif
   16.44 +#if defined SMEXT_ENABLE_USERMSGS
   16.45 +	SM_GET_IFACE(USERMSGS, usermsgs);
   16.46 +#endif
   16.47 +#if defined SMEXT_ENABLE_TRANSLATOR
   16.48 +	SM_GET_IFACE(TRANSLATOR, translator);
   16.49 +#endif
   16.50  
   16.51  	if (SDK_OnLoad(error, maxlength, late))
   16.52  	{
    17.1 --- a/extensions/bintools/sdk/smsdk_ext.h	Wed Jan 07 22:55:40 2009 -0500
    17.2 +++ b/extensions/bintools/sdk/smsdk_ext.h	Thu Jan 08 18:17:17 2009 +1300
    17.3 @@ -73,6 +73,24 @@
    17.4  #if defined SMEXT_ENABLE_LIBSYS
    17.5  #include <ILibrarySys.h>
    17.6  #endif
    17.7 +#if defined SMEXT_ENABLE_PLUGINSYS
    17.8 +#include <IPluginSys.h>
    17.9 +#endif
   17.10 +#if defined SMEXT_ENABLE_MENUS
   17.11 +#include <IMenuManager.h>
   17.12 +#endif
   17.13 +#if defined SMEXT_ENABLE_ADMINSYS
   17.14 +#include <IAdminSystem.h>
   17.15 +#endif
   17.16 +#if defined SMEXT_ENABLE_TEXTPARSERS
   17.17 +#include <ITextParsers.h>
   17.18 +#endif
   17.19 +#if defined SMEXT_ENABLE_USERMSGS
   17.20 +#include <IUserMessages.h>
   17.21 +#endif
   17.22 +#if defined SMEXT_ENABLE_TRANSLATOR
   17.23 +#include <ITranslator.h>
   17.24 +#endif
   17.25  
   17.26  #if defined SMEXT_CONF_METAMOD
   17.27  #include <ISmmPlugin.h>
   17.28 @@ -256,6 +274,21 @@
   17.29  #if defined SMEXT_ENABLE_LIBSYS
   17.30  extern ILibrarySys *libsys;
   17.31  #endif
   17.32 +#if defined SMEXT_ENABLE_PLUGINSYS
   17.33 +extern SourceMod::IPluginManager *plsys;
   17.34 +#endif
   17.35 +#if defined SMEXT_ENABLE_MENUS
   17.36 +extern IMenuManager *menus;
   17.37 +#endif
   17.38 +#if defined SMEXT_ENABLE_ADMINSYS
   17.39 +extern IAdminSystem *adminsys;
   17.40 +#endif
   17.41 +#if defined SMEXT_ENABLE_USERMSGS
   17.42 +extern IUserMessages *usermsgs;
   17.43 +#endif
   17.44 +#if defined SMEXT_ENABLE_TRANSLATOR
   17.45 +extern ITranslator *translator;
   17.46 +#endif
   17.47  
   17.48  #if defined SMEXT_CONF_METAMOD
   17.49  PLUGIN_GLOBALVARS();
    18.1 --- a/public/extensions/IBinTools.h	Wed Jan 07 22:55:40 2009 -0500
    18.2 +++ b/public/extensions/IBinTools.h	Thu Jan 08 18:17:17 2009 +1300
    18.3 @@ -34,8 +34,16 @@
    18.4  
    18.5  #include <IShareSys.h>
    18.6  
    18.7 +
    18.8  #define SMINTERFACE_BINTOOLS_NAME		"IBinTools"
    18.9 -#define SMINTERFACE_BINTOOLS_VERSION	2
   18.10 +#define SMINTERFACE_BINTOOLS_VERSION	3
   18.11 +
   18.12 +#if defined HOOKING_ENABLED
   18.13 +#include <sourcehook_pibuilder.h>
   18.14 +
   18.15 +#define SMINTERFACE_BINTOOLS2_NAME		"IBinTools2"
   18.16 +#define SMINTERFACE_BINTOOLS2_VERSION	1
   18.17 +#endif
   18.18  
   18.19  /**
   18.20   * @brief Function calling encoding utilities
   18.21 @@ -135,8 +143,109 @@
   18.22  		 * @brief Destroys all resources used by this object.
   18.23  		 */
   18.24  		virtual void Destroy() =0;
   18.25 +
   18.26 +#if defined HOOKING_ENABLED
   18.27 +
   18.28 +		/**
   18.29 +		 * @brief Gets the Return type info.
   18.30 +		 *
   18.31 +		 * @return				A PassInfo pointer.
   18.32 +		 */
   18.33 +		virtual const SourceHook::PassInfo *GetSHReturnInfo() =0;
   18.34 +
   18.35 +		/**
   18.36 +		* @brief Returns the calling convention.
   18.37 +		*
   18.38 +		* @return				CallConvention value.
   18.39 +		*/
   18.40 +		virtual SourceHook::ProtoInfo::CallConvention GetSHCallConvention() =0;
   18.41 +
   18.42 +		/**
   18.43 +		* @brief Returns parameter info.
   18.44 +		*
   18.45 +		* @param num			Parameter number to get (starting from 0).
   18.46 +		* @return				A PassInfo pointer.
   18.47 +		*/
   18.48 +		virtual const SourceHook::PassInfo *GetSHParamInfo(unsigned int num) =0;
   18.49 +
   18.50 +		/**
   18.51 +		 * @brief Returns the offset of a given param.
   18.52 +		 *
   18.53 +		 * @param num			Parameter number to get (starting from 0).
   18.54 +		 * @return				Parameter offset.
   18.55 +		 */
   18.56 +		virtual unsigned int GetParamOffset(unsigned int num) =0;
   18.57 +
   18.58 +#endif
   18.59  	};
   18.60  
   18.61 +#if defined HOOKING_ENABLED
   18.62 +
   18.63 +	/**
   18.64 +	 * @brief Delegate object that intermediates between SourceHook and the callback function.
   18.65 +	 */
   18.66 +	class ISMDelegate : public SourceHook::ISHDelegate
   18.67 +	{
   18.68 +	private:
   18.69 +		/**
   18.70 +		 * @brief Internally used callback function - Do not call!
   18.71 +		 */
   18.72 +		virtual void Call() =0;        /**< Do not call */
   18.73 +	public:
   18.74 +		/**
   18.75 +		 * @brief Retrieves the User data buffer.
   18.76 +		 *
   18.77 +		 * @return					User data pointer.
   18.78 +		 */
   18.79 +		virtual void *GetUserData() =0;
   18.80 +	};
   18.81 +
   18.82 +	/**
   18.83 +	 * @brief Wrapper around a virtual hook.
   18.84 +	 */
   18.85 +	class IHookWrapper
   18.86 +	{
   18.87 +	public:
   18.88 +		/**
   18.89 +		 * @brief Creates a hook delegate to pass to SourceHook.
   18.90 +		 *
   18.91 +		 * @param data				User data pointer.
   18.92 +		 * @return					A new ISMDelegate for the hook.
   18.93 +		 */
   18.94 +		virtual ISMDelegate *CreateDelegate(void *data) =0;
   18.95 +
   18.96 +		/**
   18.97 +		 * @brief Gets the number of params in the hooked function.
   18.98 +		 *
   18.99 +		 * @return					Number of params.
  18.100 +		 */
  18.101 +		virtual unsigned int GetParamCount() =0;
  18.102 +
  18.103 +		/**
  18.104 +		 * @brief Returns the offset of a given param.
  18.105 +		 *
  18.106 +		 * @param argnum			Parameter number from 0 to GetParamCount-1.
  18.107 +		 * @param size				Optional buffer to store the size of the param.
  18.108 +		 * @return					Parameter offset or -1 on error.
  18.109 +		 */
  18.110 +		virtual unsigned int GetParamOffset(unsigned int argnum, unsigned int *size) =0;
  18.111 +
  18.112 +		/**
  18.113 +		 * @brief Initiates a recall on the function.
  18.114 +		 *
  18.115 +		 * @param params			Parameter buffer.
  18.116 +		 * @param retval			Buffer to store the return value in.
  18.117 +		 */
  18.118 +		virtual void PerformRecall(void *params, void *retval) =0;
  18.119 +
  18.120 +		/**
  18.121 +		 * @brief Destroys this HookWrapper.
  18.122 +		 */
  18.123 +		virtual void Destroy() =0;
  18.124 +	};
  18.125 +
  18.126 +#endif
  18.127 +
  18.128  	/**
  18.129  	 * @brief Binary tools interface.
  18.130  	 */
  18.131 @@ -196,6 +305,82 @@
  18.132  											const PassInfo paramInfo[],
  18.133  											unsigned int numParams) =0;
  18.134  	};
  18.135 +
  18.136 +#if defined HOOKING_ENABLED
  18.137 +
  18.138 +	/**
  18.139 +	 * @brief Binary tools interface.
  18.140 +	 */
  18.141 +	class IBinTools2 : public SMInterface
  18.142 +	{
  18.143 +	public:
  18.144 +		virtual const char *GetInterfaceName()
  18.145 +		{
  18.146 +			return SMINTERFACE_BINTOOLS2_NAME;
  18.147 +		}
  18.148 +		virtual unsigned int GetInterfaceVersion()
  18.149 +		{
  18.150 +			return SMINTERFACE_BINTOOLS2_VERSION;
  18.151 +		}
  18.152 +	public:
  18.153 +
  18.154 +		/**
  18.155 +		 * @brief Creates a call decoder.
  18.156 +		 *
  18.157 +		 * Note: CallConv_ThisCall requires an implicit first parameter
  18.158 +		 * of PassType_Basic / PASSFLAG_BYVAL / sizeof(void *).  However,
  18.159 +		 * this should only be given to the Execute() function, and never
  18.160 +		 * listed in the paramInfo array.
  18.161 +		 *
  18.162 +		 * @param address			Address to use as a call.
  18.163 +		 * @param protoInfo			Parameter type information.
  18.164 +		 * @return					A new ICallWrapper function.
  18.165 +		 */
  18.166 +		virtual ICallWrapper *CreateCall(void *address,
  18.167 +			const SourceHook::ProtoInfo *protoInfo) =0;
  18.168 +
  18.169 +		/**
  18.170 +		 * @brief Creates a vtable call decoder.
  18.171 +		 *
  18.172 +		 * Note: CallConv_ThisCall requires an implicit first parameter
  18.173 +		 * of PassType_Basic / PASSFLAG_BYVAL / sizeof(void *).  However,
  18.174 +		 * this should only be given to the Execute() function, and never
  18.175 +		 * listed in the paramInfo array.
  18.176 +		 *
  18.177 +		 * @param protoInfo			Parameter type information.
  18.178 +		 * @param info				Function offset information.
  18.179 +		 * @return					A new ICallWrapper function.
  18.180 +		 */
  18.181 +		virtual ICallWrapper *CreateVirtualCall(const SourceHook::ProtoInfo *protoInfo,
  18.182 +			const SourceHook::MemFuncInfo *info) =0;
  18.183 +		
  18.184 +
  18.185 +		/**
  18.186 +		 * @brief Callback function pointer for Virtual Hooks.
  18.187 +		 *
  18.188 +		 * @param wrapper			Call wrapper for this hook.
  18.189 +		 * @param deleg				Delegate for this call.
  18.190 +		 * @param params				Array of parameters.
  18.191 +		 * @param ret				Storage buffer for the return value.
  18.192 +		 */
  18.193 +		typedef void (*VIRTUAL_HOOK_PROTO)(IHookWrapper *wrapper, ISMDelegate *deleg, void *params, void *ret);
  18.194 +
  18.195 +		/**
  18.196 +		 * @brief Creates a hook on a virtual function.
  18.197 +		 *
  18.198 +		 * @param pSH				Global SourceHook pointer.
  18.199 +		 * @param protoInfo			Parameter type information.
  18.200 +		 * @param info				Function offset information.
  18.201 +		 * @param f					Callback function pointer.
  18.202 +		 */
  18.203 +		virtual IHookWrapper *CreateVirtualHook(SourceHook::ISourceHook *pSH, 
  18.204 +			const SourceHook::ProtoInfo *protoInfo, 
  18.205 +			const SourceHook::MemFuncInfo *info, 
  18.206 +			VIRTUAL_HOOK_PROTO f) =0;
  18.207 +	};
  18.208 +
  18.209 +#endif
  18.210 +
  18.211  }
  18.212  
  18.213  #endif //_INCLUDE_SMEXT_BINTOOLS_H_
    19.1 --- a/tools/builder/PkgCore.cs	Wed Jan 07 22:55:40 2009 -0500
    19.2 +++ b/tools/builder/PkgCore.cs	Thu Jan 08 18:17:17 2009 +1300
    19.3 @@ -202,12 +202,37 @@
    19.4  			libraries.Add(lib);
    19.5  
    19.6  			lib = new Library();
    19.7 -			lib.package_path = "addons/sourcemod/extensions";
    19.8 +			lib.package_path = "addons/sourcemod/extensions/auto.1.ep1";
    19.9  			lib.source_path = "extensions/bintools";
   19.10  			lib.binary_name = "bintools.ext";
   19.11  			lib.vcproj_name = "bintools";
   19.12 +            lib.build_mode = BuildMode.BuildMode_OldMetamod;
   19.13  			libraries.Add(lib);
   19.14  
   19.15 +            lib = new Library();
   19.16 +            lib.package_path = "addons/sourcemod/extensions/auto.2.ep1";
   19.17 +            lib.source_path = "extensions/bintools";
   19.18 +            lib.binary_name = "bintools.ext";
   19.19 +            lib.vcproj_name = "bintools";
   19.20 +            lib.build_mode = BuildMode.BuildMode_Episode1;
   19.21 +            libraries.Add(lib);
   19.22 +
   19.23 +            lib = new Library();
   19.24 +            lib.package_path = "addons/sourcemod/extensions/auto.2.ep2";
   19.25 +            lib.source_path = "extensions/bintools";
   19.26 +            lib.binary_name = "bintools.ext";
   19.27 +            lib.vcproj_name = "bintools";
   19.28 +            lib.build_mode = BuildMode.BuildMode_Episode2;
   19.29 +            libraries.Add(lib);
   19.30 +
   19.31 +            lib = new Library();
   19.32 +            lib.package_path = "addons/sourcemod/extensions/auto.2.l4d";
   19.33 +            lib.source_path = "extensions/bintools";
   19.34 +            lib.binary_name = "bintools.ext";
   19.35 +            lib.vcproj_name = "bintools";
   19.36 +            lib.build_mode = BuildMode.BuildMode_Left4Dead;
   19.37 +            libraries.Add(lib);
   19.38 +
   19.39  			lib = new Library();
   19.40  			lib.package_path = "addons/sourcemod/extensions";
   19.41  			lib.source_path = "extensions/mysql";