Added ProcessTargetString simple filter API (bug 4404, r=ds).
authorDavid Anderson <dvander@alliedmods.net>
Thu May 13 12:28:51 2010 -0700 (2010-05-13)
changeset 299645be5b449233
parent 2995 716c412891ce
child 2997 558d6fec66ad
Added ProcessTargetString simple filter API (bug 4404, r=ds).
core/logic/AMBuilder
core/logic/AutoHandleRooter.h
core/logic/Makefile
core/logic/common_logic.cpp
core/logic/common_logic.h
core/logic/intercom.h
core/logic/smn_players.cpp
core/logic_bridge.cpp
plugins/include/commandfilters.inc
plugins/testsuite/ptstest.sp
public/IHandleSys.h
     1.1 --- a/core/logic/AMBuilder	Thu May 13 04:54:31 2010 -0500
     1.2 +++ b/core/logic/AMBuilder	Thu May 13 12:28:51 2010 -0700
     1.3 @@ -31,6 +31,7 @@
     1.4  	'Profiler.cpp',
     1.5  	'smn_functions.cpp',
     1.6  	'smn_timers.cpp',
     1.7 +	'smn_players.cpp',
     1.8  	'sm_crc32.cpp'
     1.9  	]
    1.10  if AMBuild.target['platform'] == 'windows':
     2.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     2.2 +++ b/core/logic/AutoHandleRooter.h	Thu May 13 12:28:51 2010 -0700
     2.3 @@ -0,0 +1,92 @@
     2.4 +/**
     2.5 + * vim: set ts=4 sw=4 tw=99 noet :
     2.6 + * =============================================================================
     2.7 + * SourceMod
     2.8 + * Copyright (C) 2004-2009 AlliedModders LLC.  All rights reserved.
     2.9 + * =============================================================================
    2.10 + *
    2.11 + * This program is free software; you can redistribute it and/or modify it under
    2.12 + * the terms of the GNU General Public License, version 3.0, as published by the
    2.13 + * Free Software Foundation.
    2.14 + * 
    2.15 + * This program is distributed in the hope that it will be useful, but WITHOUT
    2.16 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
    2.17 + * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
    2.18 + * details.
    2.19 + *
    2.20 + * You should have received a copy of the GNU General Public License along with
    2.21 + * this program.  If not, see <http://www.gnu.org/licenses/>.
    2.22 + *
    2.23 + * As a special exception, AlliedModders LLC gives you permission to link the
    2.24 + * code of this program (as well as its derivative works) to "Half-Life 2," the
    2.25 + * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
    2.26 + * by the Valve Corporation.  You must obey the GNU General Public License in
    2.27 + * all respects for all other code used.  Additionally, AlliedModders LLC grants
    2.28 + * this exception to all derivative works.  AlliedModders LLC defines further
    2.29 + * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
    2.30 + * or <http://www.sourcemod.net/license.php>.
    2.31 + *
    2.32 + * Version: $Id$
    2.33 + */
    2.34 +
    2.35 +#ifndef _INCLUDE_SOURCEMOD_AUTO_HANDLE_ROOTER_H_
    2.36 +#define _INCLUDE_SOURCEMOD_AUTO_HANDLE_ROOTER_H_
    2.37 +
    2.38 +#include "common_logic.h"
    2.39 +#include <IHandleSys.h>
    2.40 +
    2.41 +class AutoHandleRooter
    2.42 +{
    2.43 +public:
    2.44 +	AutoHandleRooter(Handle_t hndl)
    2.45 +	{
    2.46 +		if (hndl != BAD_HANDLE)
    2.47 +			this->hndl = handlesys->FastCloneHandle(hndl);
    2.48 +		else
    2.49 +			this->hndl = BAD_HANDLE;
    2.50 +	}
    2.51 +
    2.52 +	~AutoHandleRooter()
    2.53 +	{
    2.54 +		if (hndl != BAD_HANDLE)
    2.55 +		{
    2.56 +			HandleSecurity sec(g_pCoreIdent, g_pCoreIdent);
    2.57 +			handlesys->FreeHandle(hndl, &sec);
    2.58 +		}
    2.59 +	}
    2.60 +
    2.61 +	Handle_t getHandle()
    2.62 +	{
    2.63 +		return hndl;
    2.64 +	}
    2.65 +private:
    2.66 +	Handle_t hndl;
    2.67 +};
    2.68 +
    2.69 +class AutoHandleCloner
    2.70 +{
    2.71 +	Handle_t original;
    2.72 +	HandleSecurity sec;
    2.73 +	AutoHandleRooter ahr;
    2.74 +public:
    2.75 +	AutoHandleCloner(Handle_t original, HandleSecurity sec)
    2.76 +	  : original(original), sec(sec), ahr(original)
    2.77 +	{
    2.78 +	}
    2.79 +
    2.80 +	~AutoHandleCloner()
    2.81 +	{
    2.82 +		if (original != BAD_HANDLE)
    2.83 +		{
    2.84 +			handlesys->FreeHandle(original, &sec);
    2.85 +		}
    2.86 +	}
    2.87 +
    2.88 +	Handle_t getClone()
    2.89 +	{
    2.90 +		return ahr.getHandle();
    2.91 +	}
    2.92 +};
    2.93 +
    2.94 +#endif /* _INCLUDE_SOURCEMOD_AUTO_HANDLE_ROOTER_H_ */
    2.95 +
     3.1 --- a/core/logic/Makefile	Thu May 13 04:54:31 2010 -0500
     3.2 +++ b/core/logic/Makefile	Thu May 13 12:28:51 2010 -0700
     3.3 @@ -27,7 +27,8 @@
     3.4  	Profiler.cpp		\
     3.5  	smn_functions.cpp   \
     3.6  	sm_crc32.cpp		\
     3.7 -	smn_timers.cpp
     3.8 +	smn_timers.cpp		\
     3.9 +	smn_players.cpp
    3.10  
    3.11  ##############################################
    3.12  ### CONFIGURE ANY OTHER FLAGS/OPTIONS HERE ###
     4.1 --- a/core/logic/common_logic.cpp	Thu May 13 04:54:31 2010 -0500
     4.2 +++ b/core/logic/common_logic.cpp	Thu May 13 12:28:51 2010 -0700
     4.3 @@ -52,6 +52,7 @@
     4.4  IForwardManager *forwardsys;
     4.5  ITimerSystem *timersys;
     4.6  ServerGlobals serverGlobals;
     4.7 +IPlayerManager *playerhelpers;
     4.8  
     4.9  static sm_logic_t logic =
    4.10  {
    4.11 @@ -79,6 +80,7 @@
    4.12  	pluginsys = core->pluginsys;
    4.13  	forwardsys = core->forwardsys;
    4.14  	timersys = core->timersys;
    4.15 +	playerhelpers = core->playerhelpers;
    4.16  }
    4.17  
    4.18  PLATFORM_EXTERN_C ITextParsers *get_textparsers()
     5.1 --- a/core/logic/common_logic.h	Thu May 13 04:54:31 2010 -0500
     5.2 +++ b/core/logic/common_logic.h	Thu May 13 12:28:51 2010 -0700
     5.3 @@ -49,6 +49,7 @@
     5.4  extern IForwardManager *forwardsys;
     5.5  extern ITimerSystem *timersys;
     5.6  extern ServerGlobals serverGlobals;
     5.7 +extern IPlayerManager *playerhelpers;
     5.8  
     5.9  #endif /* _INCLUDE_SOURCEMOD_COMMON_LOGIC_H_ */
    5.10  
     6.1 --- a/core/logic/intercom.h	Thu May 13 04:54:31 2010 -0500
     6.2 +++ b/core/logic/intercom.h	Thu May 13 12:28:51 2010 -0700
     6.3 @@ -42,7 +42,7 @@
     6.4   * Add 1 to the RHS of this expression to bump the intercom file
     6.5   * This is to prevent mismatching core/logic binaries
     6.6   */
     6.7 -#define SM_LOGIC_MAGIC		(0x0F47C0DE - 4)
     6.8 +#define SM_LOGIC_MAGIC		(0x0F47C0DE - 5)
     6.9  
    6.10  #if defined SM_LOGIC
    6.11  class IVEngineServer
    6.12 @@ -64,6 +64,7 @@
    6.13  	class IPluginManager;
    6.14  	class IForwardManager;
    6.15  	class ITimerSystem;
    6.16 +	class IPlayerManager;
    6.17  }
    6.18  
    6.19  class IVEngineServer;
    6.20 @@ -89,6 +90,7 @@
    6.21  	IPluginManager	*pluginsys;
    6.22  	IForwardManager	*forwardsys;
    6.23  	ITimerSystem    *timersys;
    6.24 +	IPlayerManager  *playerhelpers;
    6.25  	/* Functions */
    6.26  	void			(*AddNatives)(sp_nativeinfo_t* nlist);
    6.27  	ConVar *		(*FindConVar)(const char*);
     7.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     7.2 +++ b/core/logic/smn_players.cpp	Thu May 13 12:28:51 2010 -0700
     7.3 @@ -0,0 +1,235 @@
     7.4 +/**
     7.5 + * vim: set ts=4 sw=4 tw=99 noet :
     7.6 + * =============================================================================
     7.7 + * SourceMod
     7.8 + * Copyright (C) 2004-2008 AlliedModders LLC.  All rights reserved.
     7.9 + * =============================================================================
    7.10 + *
    7.11 + * This program is free software; you can redistribute it and/or modify it under
    7.12 + * the terms of the GNU General Public License, version 3.0, as published by the
    7.13 + * Free Software Foundation.
    7.14 + * 
    7.15 + * This program is distributed in the hope that it will be useful, but WITHOUT
    7.16 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
    7.17 + * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
    7.18 + * details.
    7.19 + *
    7.20 + * You should have received a copy of the GNU General Public License along with
    7.21 + * this program.  If not, see <http://www.gnu.org/licenses/>.
    7.22 + *
    7.23 + * As a special exception, AlliedModders LLC gives you permission to link the
    7.24 + * code of this program (as well as its derivative works) to "Half-Life 2," the
    7.25 + * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
    7.26 + * by the Valve Corporation.  You must obey the GNU General Public License in
    7.27 + * all respects for all other code used.  Additionally, AlliedModders LLC grants
    7.28 + * this exception to all derivative works.  AlliedModders LLC defines further
    7.29 + * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
    7.30 + * or <http://www.sourcemod.net/license.php>.
    7.31 + *
    7.32 + * Version: $Id$
    7.33 + */
    7.34 +
    7.35 +#include "common_logic.h"
    7.36 +#include <IPluginSys.h>
    7.37 +#include <IPlayerHelpers.h>
    7.38 +#include <sh_string.h>
    7.39 +#include <sh_list.h>
    7.40 +#include "AutoHandleRooter.h"
    7.41 +#include "CellArray.h"
    7.42 +
    7.43 +using namespace SourceHook;
    7.44 +using namespace SourceMod;
    7.45 +
    7.46 +class PlayerLogicHelpers : 
    7.47 +	public SMGlobalClass,
    7.48 +	public IPluginsListener,
    7.49 +	public ICommandTargetProcessor
    7.50 +{
    7.51 +	struct SimpleMultiTargetFilter
    7.52 +	{
    7.53 +		IPlugin *plugin;
    7.54 +		SourceHook::String pattern;
    7.55 +		IPluginFunction *fun;
    7.56 +		SourceHook::String phrase;
    7.57 +		bool phraseIsML;
    7.58 +
    7.59 +		SimpleMultiTargetFilter(IPlugin *plugin, const char *pattern, IPluginFunction *fun,
    7.60 +		                        const char *phrase, bool phraseIsML)
    7.61 +		  : plugin(plugin), pattern(pattern), fun(fun), phrase(phrase), phraseIsML(phraseIsML)
    7.62 +		{
    7.63 +		}
    7.64 +	};
    7.65 +
    7.66 +	List<SimpleMultiTargetFilter *> simpleMultis;
    7.67 +	bool filterEnabled;
    7.68 +
    7.69 +public:
    7.70 +	void AddMultiTargetFilter(IPlugin *plugin, const char *pattern, IPluginFunction *fun,
    7.71 +	                          const char *phrase, bool phraseIsML)
    7.72 +	{
    7.73 +		SimpleMultiTargetFilter *smtf = new SimpleMultiTargetFilter(plugin, pattern, fun, phrase,
    7.74 +		                                                            phraseIsML);
    7.75 +
    7.76 +		simpleMultis.push_back(smtf);
    7.77 +
    7.78 +		if (!filterEnabled) {
    7.79 +			playerhelpers->RegisterCommandTargetProcessor(this);
    7.80 +			filterEnabled = true;
    7.81 +		}
    7.82 +	}
    7.83 +
    7.84 +	void RemoveMultiTargetFilter(const char *pattern, IPluginFunction *fun)
    7.85 +	{
    7.86 +		List<SimpleMultiTargetFilter *>::iterator iter = simpleMultis.begin();
    7.87 +
    7.88 +		while (iter != simpleMultis.end()) {
    7.89 +			if ((*iter)->fun == fun && strcmp((*iter)->pattern.c_str(), pattern) == 0) {
    7.90 +				delete (*iter);
    7.91 +				iter = simpleMultis.erase(iter);
    7.92 +				break;
    7.93 +			}
    7.94 +			iter++;
    7.95 +		}
    7.96 +	}
    7.97 +
    7.98 +	PlayerLogicHelpers()
    7.99 +	 : filterEnabled(false)
   7.100 +	{
   7.101 +	}
   7.102 +
   7.103 +public: //ICommandTargetProcessor
   7.104 +	bool ProcessCommandTarget(cmd_target_info_t *info)
   7.105 +	{
   7.106 +		List<SimpleMultiTargetFilter *>::iterator iter;
   7.107 +
   7.108 +		for (iter = simpleMultis.begin(); iter != simpleMultis.end(); iter++) {
   7.109 +			SimpleMultiTargetFilter *smtf = (*iter);
   7.110 +			if (strcmp(smtf->pattern.c_str(), info->pattern) == 0) {
   7.111 +				CellArray *array = new CellArray(1);
   7.112 +				HandleSecurity sec(g_pCoreIdent, g_pCoreIdent);
   7.113 +				Handle_t hndl = handlesys->CreateHandleEx(htCellArray, array, &sec, NULL, NULL);
   7.114 +				AutoHandleCloner ahc(hndl, sec);
   7.115 +				if (ahc.getClone() == BAD_HANDLE) {
   7.116 +					smcore.LogError("[SM] Could not allocate a handle (%s, %d)", __FILE__, __LINE__);
   7.117 +					delete array;
   7.118 +					return false;
   7.119 +				}
   7.120 +
   7.121 +				smtf->fun->PushString(info->pattern);
   7.122 +				smtf->fun->PushCell(ahc.getClone());
   7.123 +				cell_t result = 0;
   7.124 +				if (smtf->fun->Execute(&result) != SP_ERROR_NONE || !result)
   7.125 +					return false;
   7.126 +
   7.127 +				IGamePlayer *pAdmin = info->admin
   7.128 +				                      ? playerhelpers->GetGamePlayer(info->admin)
   7.129 +				                      : NULL;
   7.130 +
   7.131 +				info->num_targets = 0;
   7.132 +				for (size_t i = 0; i < array->size(); i++) {
   7.133 +					cell_t client = *array->at(i);
   7.134 +					IGamePlayer *pClient = playerhelpers->GetGamePlayer(client);
   7.135 +					if (pClient == NULL || !pClient->IsConnected())
   7.136 +						continue;
   7.137 +					if (playerhelpers->FilterCommandTarget(pAdmin, pClient, info->flags) ==
   7.138 +					    COMMAND_TARGET_VALID)
   7.139 +					{
   7.140 +						info->targets[info->num_targets++] = client;
   7.141 +						if (info->num_targets >= unsigned(info->max_targets))
   7.142 +							break;
   7.143 +					}
   7.144 +				}
   7.145 +
   7.146 +				info->reason = info->num_targets > 0
   7.147 +				               ? COMMAND_TARGET_VALID
   7.148 +				               : COMMAND_TARGET_EMPTY_FILTER;
   7.149 +				if (info->num_targets) {
   7.150 +					smcore.strncopy(info->target_name, smtf->phrase.c_str(), info->target_name_maxlength);
   7.151 +					info->target_name_style = smtf->phraseIsML
   7.152 +					                          ? COMMAND_TARGETNAME_ML
   7.153 +					                          : COMMAND_TARGETNAME_RAW;
   7.154 +				}
   7.155 +
   7.156 +				return true;
   7.157 +			}
   7.158 +		}
   7.159 +
   7.160 +		return false;
   7.161 +	}
   7.162 +
   7.163 +public: //SMGlobalClass
   7.164 +	void OnSourceModAllInitialized()
   7.165 +	{
   7.166 +		pluginsys->AddPluginsListener(this);
   7.167 +	}
   7.168 +
   7.169 +	void OnSourceModShutdown()
   7.170 +	{
   7.171 +		pluginsys->RemovePluginsListener(this);
   7.172 +		if (filterEnabled) {
   7.173 +			playerhelpers->UnregisterCommandTargetProcessor(this);
   7.174 +			filterEnabled = false;
   7.175 +		}
   7.176 +	}
   7.177 +
   7.178 +public: //IPluginsListener
   7.179 +
   7.180 +	void OnPluginDestroyed(IPlugin *plugin)
   7.181 +	{
   7.182 +		List<SimpleMultiTargetFilter *>::iterator iter = simpleMultis.begin();
   7.183 +
   7.184 +		while (iter != simpleMultis.end()) {
   7.185 +			if ((*iter)->plugin != plugin) {
   7.186 +				iter++;
   7.187 +			} else {
   7.188 +				delete (*iter);
   7.189 +				iter = simpleMultis.erase(iter);
   7.190 +			}
   7.191 +		}
   7.192 +	}
   7.193 +} s_PlayerLogicHelpers;
   7.194 +
   7.195 +static cell_t
   7.196 +AddMultiTargetFilter(IPluginContext *ctx, const cell_t *params)
   7.197 +{
   7.198 +	IPluginFunction *fun = ctx->GetFunctionById(funcid_t(params[2]));
   7.199 +	if (fun == NULL)
   7.200 +		return ctx->ThrowNativeError("Invalid function id (%X)", params[2]);
   7.201 +
   7.202 +	char *pattern;
   7.203 +	char *phrase;
   7.204 +
   7.205 +	ctx->LocalToString(params[1], &pattern);
   7.206 +	ctx->LocalToString(params[3], &phrase);
   7.207 +
   7.208 +	bool phraseIsML = !!params[4];
   7.209 +	IPlugin *plugin = pluginsys->FindPluginByContext(ctx->GetContext());
   7.210 +
   7.211 +	s_PlayerLogicHelpers.AddMultiTargetFilter(plugin, pattern, fun, phrase, phraseIsML);
   7.212 +
   7.213 +	return 1;
   7.214 +}
   7.215 +
   7.216 +static cell_t
   7.217 +RemoveMultiTargetFilter(IPluginContext *ctx, const cell_t *params)
   7.218 +{
   7.219 +	IPluginFunction *fun = ctx->GetFunctionById(funcid_t(params[2]));
   7.220 +	if (fun == NULL)
   7.221 +		return ctx->ThrowNativeError("Invalid function id (%X)", params[2]);
   7.222 +
   7.223 +	char *pattern;
   7.224 +
   7.225 +	ctx->LocalToString(params[1], &pattern);
   7.226 +
   7.227 +	s_PlayerLogicHelpers.RemoveMultiTargetFilter(pattern, fun);
   7.228 +
   7.229 +	return 1;
   7.230 +}
   7.231 +
   7.232 +REGISTER_NATIVES(playernatives)
   7.233 +{
   7.234 +	{"AddMultiTargetFilter",	AddMultiTargetFilter},
   7.235 +	{"RemoveMultiTargetFilter",	RemoveMultiTargetFilter},
   7.236 +	{NULL,						NULL}
   7.237 +};
   7.238 +
     8.1 --- a/core/logic_bridge.cpp	Thu May 13 04:54:31 2010 -0500
     8.2 +++ b/core/logic_bridge.cpp	Thu May 13 12:28:51 2010 -0700
     8.3 @@ -46,6 +46,7 @@
     8.4  #include "TimerSys.h"
     8.5  #include "logic_bridge.h"
     8.6  #include "DebugReporter.h"
     8.7 +#include "PlayerManager.h"
     8.8  
     8.9  static ILibrary *g_pLogic = NULL;
    8.10  static LogicInitFunction logic_init_fn;
    8.11 @@ -113,6 +114,7 @@
    8.12  	&g_PluginSys,
    8.13  	&g_Forwards,
    8.14  	&g_Timers,
    8.15 +	&g_Players,
    8.16  	/* Functions */
    8.17  	add_natives,
    8.18  	find_convar,
     9.1 --- a/plugins/include/commandfilters.inc	Thu May 13 04:54:31 2010 -0500
     9.2 +++ b/plugins/include/commandfilters.inc	Thu May 13 12:28:51 2010 -0700
     9.3 @@ -132,3 +132,34 @@
     9.4  		}
     9.5  	}
     9.6  }
     9.7 +
     9.8 +/**
     9.9 + * Adds clients to a multi-target filter.
    9.10 + *
    9.11 + * @param pattern       Pattern name.
    9.12 + * @param clients       Array to fill with unique, valid client indexes.
    9.13 + * @return              True if pattern was recognized, false otherwise.
    9.14 + */
    9.15 +functag public bool:MultiTargetFilter(const String:pattern[], Handle:clients);
    9.16 +
    9.17 +/**
    9.18 + * Adds a multi-target filter function for ProcessTargetString().
    9.19 + *
    9.20 + * @param pattern       Pattern to match (case sensitive).
    9.21 + * @param filter        Filter function.
    9.22 + * @param phrase        Descriptive phrase to display on successful match.
    9.23 + * @param phraseIsML    True if phrase is multi-lingual, false otherwise.
    9.24 + * @noreturn
    9.25 + */
    9.26 +native AddMultiTargetFilter(const String:pattern[], MultiTargetFilter:filter,
    9.27 +                            const String:phrase[], bool:phraseIsML);
    9.28 +
    9.29 +/**
    9.30 + * Removes a multi-target filter function from ProcessTargetString().
    9.31 + *
    9.32 + * @param pattern       Pattern to match (case sensitive).
    9.33 + * @param filter        Filter function.
    9.34 + * @noreturn
    9.35 + */
    9.36 +native RemoveMultiTargetFilter(const String:pattern[], MultiTargetFilter:filter);
    9.37 +
    10.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    10.2 +++ b/plugins/testsuite/ptstest.sp	Thu May 13 12:28:51 2010 -0700
    10.3 @@ -0,0 +1,26 @@
    10.4 +#include <sourcemod>
    10.5 +
    10.6 +public Plugin:myinfo = 
    10.7 +{
    10.8 +	name = "Test target filters",
    10.9 +	author = "AlliedModders LLC",
   10.10 +	description = "Tests target filters",
   10.11 +	version = "1.0.0.0",
   10.12 +	url = "http://www.sourcemod.net/"
   10.13 +};
   10.14 +
   10.15 +public OnPluginStart()
   10.16 +{
   10.17 +	AddMultiTargetFilter("@crab", filter, "all players", true)
   10.18 +}
   10.19 +
   10.20 +public bool:filter(const String:pattern[], Handle:clients)
   10.21 +{
   10.22 +	for (new i = 1; i <= MaxClients; i++) {
   10.23 +		if (IsPlayerInGame(i))
   10.24 +			PushArrayCell(clients, i)
   10.25 +	}
   10.26 +
   10.27 +	return true
   10.28 +}
   10.29 +
    11.1 --- a/public/IHandleSys.h	Thu May 13 04:54:31 2010 -0500
    11.2 +++ b/public/IHandleSys.h	Thu May 13 12:28:51 2010 -0700
    11.3 @@ -52,7 +52,7 @@
    11.4  #include <sp_vm_types.h>
    11.5  
    11.6  #define SMINTERFACE_HANDLESYSTEM_NAME			"IHandleSys"
    11.7 -#define SMINTERFACE_HANDLESYSTEM_VERSION		3
    11.8 +#define SMINTERFACE_HANDLESYSTEM_VERSION		4
    11.9  
   11.10  /** Specifies no Identity */
   11.11  #define DEFAULT_IDENTITY			NULL
   11.12 @@ -357,6 +357,13 @@
   11.13  										const HandleSecurity *pSec,
   11.14  										const HandleAccess *pAccess,
   11.15  										HandleError *err) =0;
   11.16 +
   11.17 +		/**
   11.18 +		 * @brief Clones a handle, bypassing security checks.
   11.19 +		 *
   11.20 +		 * @return          A new Handle_t, or 0 on failure.
   11.21 +		 */
   11.22 +		virtual Handle_t FastCloneHandle(Handle_t hndl) =0;
   11.23  	};
   11.24  }
   11.25