public/IHandleSys.h
author David Anderson <dvander@alliedmods.net>
Wed Aug 01 01:54:53 2007 +0000 (2007-08-01)
changeset 1226 478550a4d5ec
parent 857 11471aa66e06
child 1330 ab94316bb52b
permissions -rw-r--r--
updated license headers for most extensions
updated sdk bases for most extensions
     1 /**
     2  * vim: set ts=4 :
     3  * ================================================================
     4  * SourceMod
     5  * Copyright (C) 2004-2007 AlliedModders LLC.  All rights reserved.
     6  * ================================================================
     7  *
     8  * This program is free software; you can redistribute it and/or 
     9  * modify it under the terms of the GNU General Public License, 
    10  * version 3.0, as published by the Free Software Foundation.
    11  * 
    12  * This program is distributed in the hope that it will be useful,
    13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
    14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    15  * GNU General Public License for more details.
    16  *
    17  * You should have received a copy of the GNU General Public License
    18  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
    19  *
    20  * As a special exception, AlliedModders LLC gives you permission to 
    21  * link the code of this program (as well as its derivative works) to 
    22  * "Half-Life 2," the "Source Engine," the "SourcePawn JIT," and any 
    23  * Game MODs that run on software by the Valve Corporation.  You must 
    24  * obey the GNU General Public License in all respects for all other 
    25  * code used. Additionally, AlliedModders LLC grants this exception 
    26  * to all derivative works. AlliedModders LLC defines further 
    27  * exceptions, found in LICENSE.txt (as of this writing, version 
    28  * JULY-31-2007), or <http://www.sourcemod.net/license.php>.
    29  *
    30  * Version: $Id$
    31  */
    32 
    33 #ifndef _INCLUDE_SOURCEMOD_HANDLESYSTEM_INTERFACE_H_
    34 #define _INCLUDE_SOURCEMOD_HANDLESYSTEM_INTERFACE_H_
    35 
    36 /**
    37  * @file IHandleSys.h
    38  * @brief Defines the interface for creating, reading, and removing Handles.
    39  * 
    40  *  The Handle system abstracts generic pointers into typed objects represented by 
    41  * 32bit codes.  This is extremely useful for verifying data integrity and cross-platform
    42  * support in SourcePawn scripts.  When a Plugin unloads, all its Handles are freed, ensuring 
    43  * that no memory leaks are present,  They have reference counts and thus can be duplicated, 
    44  * or cloned, and are safe to pass between Plugins even if one is unloaded.
    45  *
    46  *  Handles are created with a given type (custom types may be created).  They can have
    47  * per-Identity permissions for deletion, reading, and cloning.  They also support generic
    48  * operations.  For example, deleting a Handle will call that type's destructor on the generic
    49  * pointer, making cleanup easier for users and eliminating memory leaks.
    50  */
    51 
    52 #include <IShareSys.h>
    53 #include <sp_vm_types.h>
    54 
    55 #define SMINTERFACE_HANDLESYSTEM_NAME			"IHandleSys"
    56 #define SMINTERFACE_HANDLESYSTEM_VERSION		2
    57 
    58 /** Specifies no Identity */
    59 #define DEFAULT_IDENTITY			NULL
    60 /** Specifies no Type.  This is invalid for everything but reading a Handle. */
    61 #define NO_HANDLE_TYPE				0
    62 /** Specifies an invalid/NULL Handle */
    63 #define BAD_HANDLE					0
    64 
    65 namespace SourceMod
    66 {
    67 	/**
    68 	 * @brief Represents a Handle Type ID.
    69 	 */
    70 	typedef unsigned int HandleType_t;
    71 
    72 	/**
    73 	 * @brief Represents a Handle ID.
    74 	 */
    75 	typedef unsigned int Handle_t;
    76 
    77 
    78 	/*
    79 	 * About type checking:
    80 	 * Types can be inherited - a Parent type ("Supertype") can have child types.
    81 	 * When accessing handles, type checking is done.  This table shows how this is resolved:
    82 	 *
    83 	 * HANDLE		CHECK		->  RESULT
    84 	 * ------		-----			------
    85 	 * Parent		Parent			Success
    86 	 * Parent		Child			Fail
    87 	 * Child		Parent			Success
    88 	 * Child		Child			Success
    89 	 */
    90 
    91 	/**
    92 	 * @brief Lists the possible handle error codes.
    93 	 */
    94 	enum HandleError
    95 	{
    96 		HandleError_None = 0,		/**< No error */
    97 		HandleError_Changed,		/**< The handle has been freed and reassigned */
    98 		HandleError_Type,			/**< The handle has a different type registered */
    99 		HandleError_Freed,			/**< The handle has been freed */
   100 		HandleError_Index,			/**< generic internal indexing error */
   101 		HandleError_Access,			/**< No access permitted to free this handle */
   102 		HandleError_Limit,			/**< The limited number of handles has been reached */
   103 		HandleError_Identity,		/**< The identity token was not usable */
   104 		HandleError_Owner,			/**< Owners do not match for this operation */
   105 		HandleError_Version,		/**< Unrecognized security structure version */
   106 		HandleError_Parameter,		/**< An invalid parameter was passed */
   107 		HandleError_NoInherit,		/**< This type cannot be inherited */
   108 	};
   109 
   110 	/**
   111 	 * @brief Lists access rights specific to a type.
   112 	 */
   113 	enum HTypeAccessRight
   114 	{
   115 		HTypeAccess_Create = 0,		/**< Handles of this type can be created (DEFAULT=false) */
   116 		HTypeAccess_Inherit,		/**< Sub-types can inherit this type (DEFAULT=false) */
   117 		/* -------------- */
   118 		HTypeAccess_TOTAL,			/**< Total number of type access rights */
   119 	};
   120 
   121 	/**
   122 	 * @brief Lists access rights specific to a Handle.  
   123 	 * 
   124 	 * These rights are exclusive. For example, you do not need "read" access to delete or clone.
   125 	 */
   126 	enum HandleAccessRight
   127 	{
   128 		HandleAccess_Read,			/**< Can be read (DEFAULT=ident only) */
   129 		HandleAccess_Delete,		/**< Can be deleted (DEFAULT=owner only) */
   130 		HandleAccess_Clone,			/**< Can be cloned (DEFAULT=any) */
   131 		/* ------------- */
   132 		HandleAccess_TOTAL,			/**< Total number of access rights */
   133 	};
   134 
   135 	/** Access is restricted to the identity */
   136 	#define HANDLE_RESTRICT_IDENTITY	(1<<0)	
   137 	/** Access is restricted to the owner */
   138 	#define HANDLE_RESTRICT_OWNER		(1<<1)
   139 
   140 	/**
   141 	 * @brief This is used to define per-type access rights.
   142 	 */
   143 	struct TypeAccess
   144 	{
   145 		/** Constructor */
   146 		TypeAccess()
   147 		{
   148 			hsVersion = SMINTERFACE_HANDLESYSTEM_VERSION;
   149 		}
   150 		unsigned int hsVersion;			/**< Handle API version */
   151 		IdentityToken_t *ident;			/**< Identity owning this type */
   152 		bool access[HTypeAccess_TOTAL];	/**< Access array */
   153 	};
   154 
   155 	/**
   156 	 * @brief This is used to define per-Handle access rights.
   157 	 */
   158 	struct HandleAccess
   159 	{
   160 		/** Constructor */
   161 		HandleAccess()
   162 		{
   163 			hsVersion = SMINTERFACE_HANDLESYSTEM_VERSION;
   164 		}
   165 		unsigned int hsVersion;						/**< Handle API version */
   166 		unsigned int access[HandleAccess_TOTAL];	/**< Access array */
   167 	};
   168 
   169 	/**
   170 	 * @brief This pair of tokens is used for identification.
   171 	 */
   172 	struct HandleSecurity
   173 	{
   174 		HandleSecurity()
   175 		{
   176 		}
   177 		HandleSecurity(IdentityToken_t *owner, IdentityToken_t *identity)
   178 			: pOwner(owner), pIdentity(identity)
   179 		{
   180 		}
   181 		IdentityToken_t *pOwner;			/**< Owner of the Handle */
   182 		IdentityToken_t *pIdentity;			/**< Owner of the Type */
   183 	};
   184 
   185 	/**
   186 	 * @brief Hooks type-specific Handle operations.
   187 	 */
   188 	class IHandleTypeDispatch
   189 	{
   190 	public:
   191 		/** Returns the Handle API version */
   192 		virtual unsigned int GetDispatchVersion()
   193 		{
   194 			return SMINTERFACE_HANDLESYSTEM_VERSION;
   195 		}
   196 	public:
   197 		/**
   198 		 * @brief Called when destroying a handle.  Must be implemented.
   199 		 */
   200 		virtual void OnHandleDestroy(HandleType_t type, void *object) =0;
   201 	};
   202 
   203 	/**
   204 	 * @brief Provides functions for managing Handles.
   205 	 */
   206 	class IHandleSys : public SMInterface
   207 	{
   208 	public:
   209 		virtual unsigned int GetInterfaceVersion()
   210 		{
   211 			return SMINTERFACE_HANDLESYSTEM_VERSION;
   212 		}
   213 		virtual const char *GetInterfaceName()
   214 		{
   215 			return SMINTERFACE_HANDLESYSTEM_NAME;
   216 		}
   217 	public:
   218 		/**
   219 		 * @brief Creates a new Handle type.
   220 		 * NOTE: Currently, a child type may not have its own children.
   221 		 * NOTE: Handle names must be unique if not private.
   222 		 *
   223 		 * @param name		Name of handle type (NULL or "" to be anonymous)
   224 		 * @param dispatch	Pointer to a valid IHandleTypeDispatch object.
   225 		 * @param parent	Parent handle to inherit from, 0 for none.
   226 		 * @param typeAccess	Pointer to a TypeAccess object, NULL to use default 
   227 		 *						or inherited permissions.  Pointer can be temporary.
   228 		 * @param hndlAccess	Pointer to a HandleAccess object to define default
   229 		 *						default permissions on each Handle.  NULL to use default
   230 		 *						permissions.
   231 		 * @param ident		Security token for any permissions.  If typeAccess is NULL, this 
   232 		 *					becomes the owning identity.
   233 		 * @param err		Optional pointer to store an error code.
   234 		 * @return			A new HandleType_t unique ID, or 0 on failure.
   235 		 */
   236 		virtual HandleType_t CreateType(const char *name,
   237 										  IHandleTypeDispatch *dispatch,
   238 										  HandleType_t parent,
   239 										  const TypeAccess *typeAccess,
   240 										  const HandleAccess *hndlAccess,
   241 										  IdentityToken_t *ident,
   242 										  HandleError *err) =0;
   243 
   244 		/**
   245 		 * @brief Removes a handle type.
   246 		 * NOTE: This removes all child types.
   247 		 *
   248 		 * @param type		Type chain to remove.
   249 		 * @param ident		Identity token.  Removal fails if the token does not match.
   250 		 * @return			True on success, false on failure.
   251 		 */
   252 		virtual bool RemoveType(HandleType_t type, IdentityToken_t *ident) =0;
   253 
   254 		/**
   255 		 * @brief Finds a handle type by name.
   256 		 *
   257 		 * @param name		Name of handle type to find (anonymous not allowed).
   258 		 * @param type		Address to store found handle in (if not found, undefined).
   259 		 * @return			True if found, false otherwise.
   260 		 */
   261 		virtual bool FindHandleType(const char *name, HandleType_t *type) =0;
   262 
   263 		/**
   264 		 * @brief Creates a new handle.
   265 		 * 
   266 		 * @param type		Type to use on the handle.
   267 		 * @param object	Object to bind to the handle.
   268 		 * @param owner		Owner of the new Handle (may be NULL).
   269 		 * @param ident		Identity for type access if needed (may be NULL).
   270 		 * @param err		Optional pointer to store an error code.
   271 		 * @return			A new Handle_t, or 0 on failure.
   272 		 */
   273 		virtual Handle_t CreateHandle(HandleType_t type, 
   274 									  void *object,
   275 									  IdentityToken_t *owner,
   276 									  IdentityToken_t *ident,
   277 									  HandleError *err) =0;
   278 
   279 		/**
   280 		 * @brief Frees the memory associated with a handle and calls any destructors.
   281 		 * NOTE: This function will decrement the internal reference counter.  It will
   282 		 * only perform any further action if the counter hits 0.
   283 		 *
   284 		 * @param handle	Handle_t identifier to destroy.
   285 		 * @param pSecurity	Security information struct (may be NULL).
   286 		 * @return			A HandleError error code.
   287 		 */
   288 		virtual HandleError FreeHandle(Handle_t handle, const HandleSecurity *pSecurity) =0;
   289 
   290 		/**
   291 		 * @brief Clones a handle by adding to its internal reference count.  Its data,
   292 		 * type, and security permissions remain the same.
   293 		 *
   294 		 * @param handle	Handle to duplicate.  Any non-free handle target is valid.
   295 		 * @param newhandle	Stores the duplicated handle in the pointer (must not be NULL).
   296 		 * @param newOwner	New owner of cloned handle.
   297 		 * @param pSecurity	Security information struct (may be NULL).
   298 		 * @return			A HandleError error code.
   299 		 */
   300 		virtual HandleError CloneHandle(Handle_t handle, 
   301 										Handle_t *newhandle, 
   302 										IdentityToken_t *newOwner,
   303 										const HandleSecurity *pSecurity) =0;
   304 
   305 		/**
   306 		 * @brief Retrieves the contents of a handle.
   307 		 *
   308 		 * @param handle	Handle_t from which to retrieve contents.
   309 		 * @param type		Expected type to read as.  0 ignores typing rules.
   310 		 * @param pSecurity	Security information struct (may be NULL).
   311 		 * @param object	Optional address to store object in.
   312 		 * @return			HandleError error code.
   313 		 */
   314 		virtual HandleError ReadHandle(Handle_t handle, 
   315 									   HandleType_t type, 
   316 									   const HandleSecurity *pSecurity,
   317 									   void **object) =0;
   318 
   319 		/**
   320 		 * @brief Sets access permissions on one or more structures.
   321 		 *
   322 		 * @param pTypeAccess	Optional TypeAccess buffer to initialize with the default values.
   323 		 * @param pHandleAccess	Optional HandleAccess buffer to initialize with the default values.
   324 		 * @return				True on success, false if version is unsupported.
   325 		 */
   326 		virtual bool InitAccessDefaults(TypeAccess *pTypeAccess, HandleAccess *pHandleAccess) =0;
   327 
   328 		/**
   329 		 * @brief Creates a new handle.
   330 		 * 
   331 		 * @param type		Type to use on the handle.
   332 		 * @param object	Object to bind to the handle.
   333 		 * @param pSec		Security pointer; pOwner is written as the owner,
   334 		 *					pIdent is used as the parent identity for authorization.
   335 		 * @param pAccess	Access right descriptor for the Handle; NULL for type defaults.
   336 		 * @param err		Optional pointer to store an error code.
   337 		 * @return			A new Handle_t, or 0 on failure.
   338 		 */
   339 		virtual Handle_t CreateHandleEx(HandleType_t type, 
   340 										void *object,
   341 										const HandleSecurity *pSec,
   342 										const HandleAccess *pAccess,
   343 										HandleError *err) =0;
   344 	};
   345 }
   346 
   347 #endif //_INCLUDE_SOURCEMOD_HANDLESYSTEM_INTERFACE_H_