public/IHandleSys.h
author Scott Ehlert <ds@alliedmods.net>
Mon Feb 05 08:58:03 2007 +0000 (2007-02-05)
changeset 432 77112e9620fa
parent 379 b3c99c22ba80
child 528 ea61550036b5
permissions -rw-r--r--
Worst commit ever, but I have removed some unnecessary things
     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		1
    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 		IdentityToken_t *pOwner;			/**< Owner of the Handle */
   161 		IdentityToken_t *pIdentity;			/**< Owner of the Type */
   162 	};
   163 
   164 	/**
   165 	 * @brief Hooks type-specific Handle operations.
   166 	 */
   167 	class IHandleTypeDispatch
   168 	{
   169 	public:
   170 		/** Returns the Handle API version */
   171 		virtual unsigned int GetDispatchVersion()
   172 		{
   173 			return SMINTERFACE_HANDLESYSTEM_VERSION;
   174 		}
   175 	public:
   176 		/**
   177 		 * @brief Called when destroying a handle.  Must be implemented.
   178 		 */
   179 		virtual void OnHandleDestroy(HandleType_t type, void *object) =0;
   180 	};
   181 
   182 	/**
   183 	 * @brief Provides functions for managing Handles.
   184 	 */
   185 	class IHandleSys : public SMInterface
   186 	{
   187 	public:
   188 		virtual unsigned int GetInterfaceVersion()
   189 		{
   190 			return SMINTERFACE_HANDLESYSTEM_VERSION;
   191 		}
   192 		virtual const char *GetInterfaceName()
   193 		{
   194 			return SMINTERFACE_HANDLESYSTEM_NAME;
   195 		}
   196 	public:
   197 		/**
   198 		 * @brief Creates a new Handle type.
   199 		 * NOTE: Currently, a child type may not have its own children.
   200 		 * NOTE: Handle names must be unique if not private.
   201 		 *
   202 		 * @param name		Name of handle type (NULL or "" to be anonymous)
   203 		 * @param dispatch	Pointer to a valid IHandleTypeDispatch object.
   204 		 * @param parent	Parent handle to inherit from, 0 for none.
   205 		 * @param typeAccess	Pointer to a TypeAccess object, NULL to use default 
   206 		 *						or inherited permissions.  Pointer can be temporary.
   207 		 * @param hndlAccess	Pointer to a HandleAccess object to define default
   208 		 *						default permissions on each Handle.  NULL to use default
   209 		 *						permissions.
   210 		 * @param ident		Security token for any permissions.  If typeAccess is NULL, this 
   211 		 *					becomes the owning identity.
   212 		 * @param err		Optional pointer to store an error code.
   213 		 * @return			A new HandleType_t unique ID, or 0 on failure.
   214 		 */
   215 		virtual HandleType_t CreateType(const char *name,
   216 										  IHandleTypeDispatch *dispatch,
   217 										  HandleType_t parent,
   218 										  const TypeAccess *typeAccess,
   219 										  const HandleAccess *hndlAccess,
   220 										  IdentityToken_t *ident,
   221 										  HandleError *err) =0;
   222 
   223 		/**
   224 		 * @brief Removes a handle type.
   225 		 * NOTE: This removes all child types.
   226 		 *
   227 		 * @param type		Type chain to remove.
   228 		 * @param ident		Identity token.  Removal fails if the token does not match.
   229 		 * @return			True on success, false on failure.
   230 		 */
   231 		virtual bool RemoveType(HandleType_t type, IdentityToken_t *ident) =0;
   232 
   233 		/**
   234 		 * @brief Finds a handle type by name.
   235 		 *
   236 		 * @param name		Name of handle type to find (anonymous not allowed).
   237 		 * @param type		Address to store found handle in (if not found, undefined).
   238 		 * @return			True if found, false otherwise.
   239 		 */
   240 		virtual bool FindHandleType(const char *name, HandleType_t *type) =0;
   241 
   242 		/**
   243 		 * @brief Creates a new handle.
   244 		 * 
   245 		 * @param type		Type to use on the handle.
   246 		 * @param object	Object to bind to the handle.
   247 		 * @param owner		Owner of the new Handle (may be NULL).
   248 		 * @param ident		Identity for type access if needed (may be NULL).
   249 		 * @param err		Optional pointer to store an error code.
   250 		 * @return			A new Handle_t, or 0 on failure.
   251 		 */
   252 		virtual Handle_t CreateHandle(HandleType_t type, 
   253 									  void *object,
   254 									  IdentityToken_t *owner,
   255 									  IdentityToken_t *ident,
   256 									  HandleError *err) =0;
   257 
   258 		/**
   259 		 * @brief Frees the memory associated with a handle and calls any destructors.
   260 		 * NOTE: This function will decrement the internal reference counter.  It will
   261 		 * only perform any further action if the counter hits 0.
   262 		 *
   263 		 * @param handle	Handle_t identifier to destroy.
   264 		 * @param pSecurity	Security information struct (may be NULL).
   265 		 * @return			A HandleError error code.
   266 		 */
   267 		virtual HandleError FreeHandle(Handle_t handle, const HandleSecurity *pSecurity) =0;
   268 
   269 		/**
   270 		 * @brief Clones a handle by adding to its internal reference count.  Its data,
   271 		 * type, and security permissions remain the same.
   272 		 *
   273 		 * @param handle	Handle to duplicate.  Any non-free handle target is valid.
   274 		 * @param newhandle	Stores the duplicated handle in the pointer (must not be NULL).
   275 		 * @param newOwner	New owner of cloned handle.
   276 		 * @param pSecurity	Security information struct (may be NULL).
   277 		 * @return			A HandleError error code.
   278 		 */
   279 		virtual HandleError CloneHandle(Handle_t handle, 
   280 										Handle_t *newhandle, 
   281 										IdentityToken_t *newOwner,
   282 										const HandleSecurity *pSecurity) =0;
   283 
   284 		/**
   285 		 * @brief Retrieves the contents of a handle.
   286 		 *
   287 		 * @param handle	Handle_t from which to retrieve contents.
   288 		 * @param type		Expected type to read as.  0 ignores typing rules.
   289 		 * @param pSecurity	Security information struct (may be NULL).
   290 		 * @param object	Optional address to store object in.
   291 		 * @return			HandleError error code.
   292 		 */
   293 		virtual HandleError ReadHandle(Handle_t handle, 
   294 									   HandleType_t type, 
   295 									   const HandleSecurity *pSecurity,
   296 									   void **object) =0;
   297 
   298 		/**
   299 		 * @brief Sets access permissions on one or more structures.
   300 		 *
   301 		 * @param pTypeAccess	Optional TypeAccess buffer to initialize with the default values.
   302 		 * @param pHandleAccess	Optional HandleAccess buffer to initialize with the default values.
   303 		 * @return				True on success, false if version is unsupported.
   304 		 */
   305 		virtual bool InitAccessDefaults(TypeAccess *pTypeAccess, HandleAccess *pHandleAccess) =0;
   306 	};
   307 }
   308 
   309 #endif //_INCLUDE_SOURCEMOD_HANDLESYSTEM_INTERFACE_H_