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