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