• Main Page
  • Related Pages
  • Classes
  • Files
  • File List
  • File Members

public/IHandleSys.h

Go to the documentation of this file.
00001 /**
00002  * vim: set ts=4 :
00003  * =============================================================================
00004  * SourceMod
00005  * Copyright (C) 2004-2008 AlliedModders LLC.  All rights reserved.
00006  * =============================================================================
00007  *
00008  * This program is free software; you can redistribute it and/or modify it under
00009  * the terms of the GNU General Public License, version 3.0, as published by the
00010  * Free Software Foundation.
00011  * 
00012  * This program is distributed in the hope that it will be useful, but WITHOUT
00013  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
00014  * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
00015  * details.
00016  *
00017  * You should have received a copy of the GNU General Public License along with
00018  * this program.  If not, see <http://www.gnu.org/licenses/>.
00019  *
00020  * As a special exception, AlliedModders LLC gives you permission to link the
00021  * code of this program (as well as its derivative works) to "Half-Life 2," the
00022  * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
00023  * by the Valve Corporation.  You must obey the GNU General Public License in
00024  * all respects for all other code used.  Additionally, AlliedModders LLC grants
00025  * this exception to all derivative works.  AlliedModders LLC defines further
00026  * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
00027  * or <http://www.sourcemod.net/license.php>.
00028  *
00029  * Version: $Id$
00030  */
00031 
00032 #ifndef _INCLUDE_SOURCEMOD_HANDLESYSTEM_INTERFACE_H_
00033 #define _INCLUDE_SOURCEMOD_HANDLESYSTEM_INTERFACE_H_
00034 
00035 /**
00036  * @file IHandleSys.h
00037  * @brief Defines the interface for creating, reading, and removing Handles.
00038  * 
00039  *  The Handle system abstracts generic pointers into typed objects represented by 
00040  * 32bit codes.  This is extremely useful for verifying data integrity and cross-platform
00041  * support in SourcePawn scripts.  When a Plugin unloads, all its Handles are freed, ensuring 
00042  * that no memory leaks are present,  They have reference counts and thus can be duplicated, 
00043  * or cloned, and are safe to pass between Plugins even if one is unloaded.
00044  *
00045  *  Handles are created with a given type (custom types may be created).  They can have
00046  * per-Identity permissions for deletion, reading, and cloning.  They also support generic
00047  * operations.  For example, deleting a Handle will call that type's destructor on the generic
00048  * pointer, making cleanup easier for users and eliminating memory leaks.
00049  */
00050 
00051 #include <IShareSys.h>
00052 #include <sp_vm_types.h>
00053 
00054 #define SMINTERFACE_HANDLESYSTEM_NAME                       "IHandleSys"
00055 #define SMINTERFACE_HANDLESYSTEM_VERSION                    4
00056 
00057 /** Specifies no Identity */
00058 #define DEFAULT_IDENTITY                          NULL
00059 /** Specifies no Type.  This is invalid for everything but reading a Handle. */
00060 #define NO_HANDLE_TYPE                                      0
00061 /** Specifies an invalid/NULL Handle */
00062 #define BAD_HANDLE                                          0
00063 
00064 namespace SourceMod
00065 {
00066           /**
00067            * @brief Represents a Handle Type ID.
00068            */
00069           typedef unsigned int HandleType_t;
00070 
00071           /**
00072            * @brief Represents a Handle ID.
00073            */
00074           typedef unsigned int Handle_t;
00075 
00076 
00077           /*
00078            * About type checking:
00079            * Types can be inherited - a Parent type ("Supertype") can have child types.
00080            * When accessing handles, type checking is done.  This table shows how this is resolved:
00081            *
00082            * HANDLE           CHECK               ->  RESULT
00083            * ------           -----                         ------
00084            * Parent           Parent                        Success
00085            * Parent           Child                         Fail
00086            * Child            Parent                        Success
00087            * Child            Child                         Success
00088            */
00089 
00090           /**
00091            * @brief Lists the possible handle error codes.
00092            */
00093           enum HandleError
00094           {
00095                     HandleError_None = 0,                   /**< No error */
00096                     HandleError_Changed,                    /**< The handle has been freed and reassigned */
00097                     HandleError_Type,                       /**< The handle has a different type registered */
00098                     HandleError_Freed,                      /**< The handle has been freed */
00099                     HandleError_Index,                      /**< generic internal indexing error */
00100                     HandleError_Access,                     /**< No access permitted to free this handle */
00101                     HandleError_Limit,                      /**< The limited number of handles has been reached */
00102                     HandleError_Identity,                   /**< The identity token was not usable */
00103                     HandleError_Owner,                      /**< Owners do not match for this operation */
00104                     HandleError_Version,                    /**< Unrecognized security structure version */
00105                     HandleError_Parameter,                  /**< An invalid parameter was passed */
00106                     HandleError_NoInherit,                  /**< This type cannot be inherited */
00107           };
00108 
00109           /**
00110            * @brief Lists access rights specific to a type.
00111            */
00112           enum HTypeAccessRight
00113           {
00114                     HTypeAccess_Create = 0,                 /**< Handles of this type can be created (DEFAULT=false) */
00115                     HTypeAccess_Inherit,                    /**< Sub-types can inherit this type (DEFAULT=false) */
00116                     /* -------------- */
00117                     HTypeAccess_TOTAL,                      /**< Total number of type access rights */
00118           };
00119 
00120           /**
00121            * @brief Lists access rights specific to a Handle.  
00122            * 
00123            * These rights are exclusive. For example, you do not need "read" access to delete or clone.
00124            */
00125           enum HandleAccessRight
00126           {
00127                     HandleAccess_Read,                      /**< Can be read (DEFAULT=ident only) */
00128                     HandleAccess_Delete,                    /**< Can be deleted (DEFAULT=owner only) */
00129                     HandleAccess_Clone,                     /**< Can be cloned (DEFAULT=any) */
00130                     /* ------------- */
00131                     HandleAccess_TOTAL,                     /**< Total number of access rights */
00132           };
00133 
00134           /** Access is restricted to the identity */
00135           #define HANDLE_RESTRICT_IDENTITY        (1<<0)    
00136           /** Access is restricted to the owner */
00137           #define HANDLE_RESTRICT_OWNER           (1<<1)
00138 
00139           /**
00140            * @brief This is used to define per-type access rights.
00141            */
00142           struct TypeAccess
00143           {
00144                     /** Constructor */
00145                     TypeAccess()
00146                     {
00147                               hsVersion = SMINTERFACE_HANDLESYSTEM_VERSION;
00148                     }
00149                     unsigned int hsVersion;                           /**< Handle API version */
00150                     IdentityToken_t *ident;                           /**< Identity owning this type */
00151                     bool access[HTypeAccess_TOTAL];         /**< Access array */
00152           };
00153 
00154           /**
00155            * @brief This is used to define per-Handle access rights.
00156            */
00157           struct HandleAccess
00158           {
00159                     /** Constructor */
00160                     HandleAccess()
00161                     {
00162                               hsVersion = SMINTERFACE_HANDLESYSTEM_VERSION;
00163                     }
00164                     unsigned int hsVersion;                                                         /**< Handle API version */
00165                     unsigned int access[HandleAccess_TOTAL];          /**< Access array */
00166           };
00167 
00168           /**
00169            * @brief This pair of tokens is used for identification.
00170            */
00171           struct HandleSecurity
00172           {
00173                     HandleSecurity()
00174                     {
00175                     }
00176                     HandleSecurity(IdentityToken_t *owner, IdentityToken_t *identity)
00177                               : pOwner(owner), pIdentity(identity)
00178                     {
00179                     }
00180                     IdentityToken_t *pOwner;                          /**< Owner of the Handle */
00181                     IdentityToken_t *pIdentity;                       /**< Owner of the Type */
00182           };
00183 
00184           /**
00185            * @brief Hooks type-specific Handle operations.
00186            */
00187           class IHandleTypeDispatch
00188           {
00189           public:
00190                     /** Returns the Handle API version */
00191                     virtual unsigned int GetDispatchVersion()
00192                     {
00193                               return SMINTERFACE_HANDLESYSTEM_VERSION;
00194                     }
00195           public:
00196                     /**
00197                      * @brief Called when destroying a handle.  Must be implemented.
00198                      *
00199                      * @param type                Handle type.
00200                      * @param object    Handle internal object.
00201                      */
00202                     virtual void OnHandleDestroy(HandleType_t type, void *object) =0;
00203 
00204                     /**
00205                      * @brief Called to get the size of a handle's memory usage in bytes.
00206                      * Implementation is optional.
00207                      *
00208                      * @param type                Handle type.
00209                      * @param object    Handle internal object.
00210                      * @param pSize               Pointer to store the approximate memory usage in bytes.
00211                      * @return                              True on success, false if not implemented.
00212                      */
00213                     virtual bool GetHandleApproxSize(HandleType_t type, void *object, unsigned int *pSize)
00214                     {
00215                               return false;
00216                     }
00217           };
00218 
00219           /**
00220            * @brief Provides functions for managing Handles.
00221            */
00222           class IHandleSys : public SMInterface
00223           {
00224           public:
00225                     virtual unsigned int GetInterfaceVersion()
00226                     {
00227                               return SMINTERFACE_HANDLESYSTEM_VERSION;
00228                     }
00229                     virtual const char *GetInterfaceName()
00230                     {
00231                               return SMINTERFACE_HANDLESYSTEM_NAME;
00232                     }
00233           public:
00234                     /**
00235                      * @brief Creates a new Handle type.
00236                      * NOTE: Currently, a child type may not have its own children.
00237                      * NOTE: Handle names must be unique if not private.
00238                      *
00239                      * @param name                Name of handle type (NULL or "" to be anonymous)
00240                      * @param dispatch  Pointer to a valid IHandleTypeDispatch object.
00241                      * @param parent    Parent handle to inherit from, 0 for none.
00242                      * @param typeAccess          Pointer to a TypeAccess object, NULL to use default 
00243                      *                                                          or inherited permissions.  Pointer can be temporary.
00244                      * @param hndlAccess          Pointer to a HandleAccess object to define default
00245                      *                                                          default permissions on each Handle.  NULL to use default
00246                      *                                                          permissions.
00247                      * @param ident               Security token for any permissions.  If typeAccess is NULL, this 
00248                      *                                                becomes the owning identity.
00249                      * @param err                 Optional pointer to store an error code on failure (undefined on success).
00250                      * @return                              A new HandleType_t unique ID, or 0 on failure.
00251                      */
00252                     virtual HandleType_t CreateType(const char *name,
00253                                                                                                       IHandleTypeDispatch *dispatch,
00254                                                                                                       HandleType_t parent,
00255                                                                                                       const TypeAccess *typeAccess,
00256                                                                                                       const HandleAccess *hndlAccess,
00257                                                                                                       IdentityToken_t *ident,
00258                                                                                                       HandleError *err) =0;
00259 
00260                     /**
00261                      * @brief Removes a handle type.
00262                      * NOTE: This removes all child types.
00263                      *
00264                      * @param type                Type chain to remove.
00265                      * @param ident               Identity token.  Removal fails if the token does not match.
00266                      * @return                              True on success, false on failure.
00267                      */
00268                     virtual bool RemoveType(HandleType_t type, IdentityToken_t *ident) =0;
00269 
00270                     /**
00271                      * @brief Finds a handle type by name.
00272                      *
00273                      * @param name                Name of handle type to find (anonymous not allowed).
00274                      * @param type                Address to store found handle in (if not found, undefined).
00275                      * @return                              True if found, false otherwise.
00276                      */
00277                     virtual bool FindHandleType(const char *name, HandleType_t *type) =0;
00278 
00279                     /**
00280                      * @brief Creates a new handle.
00281                      * 
00282                      * @param type                Type to use on the handle.
00283                      * @param object    Object to bind to the handle.
00284                      * @param owner               Owner of the new Handle (may be NULL).
00285                      * @param ident               Identity for type access if needed (may be NULL).
00286                      * @param err                 Optional pointer to store an error code on failure (undefined on success).
00287                      * @return                              A new Handle_t, or 0 on failure.
00288                      */
00289                     virtual Handle_t CreateHandle(HandleType_t type, 
00290                                                                                             void *object,
00291                                                                                             IdentityToken_t *owner,
00292                                                                                             IdentityToken_t *ident,
00293                                                                                             HandleError *err) =0;
00294 
00295                     /**
00296                      * @brief Frees the memory associated with a handle and calls any destructors.
00297                      * NOTE: This function will decrement the internal reference counter.  It will
00298                      * only perform any further action if the counter hits 0.
00299                      *
00300                      * @param handle    Handle_t identifier to destroy.
00301                      * @param pSecurity Security information struct (may be NULL).
00302                      * @return                              A HandleError error code.
00303                      */
00304                     virtual HandleError FreeHandle(Handle_t handle, const HandleSecurity *pSecurity) =0;
00305 
00306                     /**
00307                      * @brief Clones a handle by adding to its internal reference count.  Its data,
00308                      * type, and security permissions remain the same.
00309                      *
00310                      * @param handle    Handle to duplicate.  Any non-free handle target is valid.
00311                      * @param newhandle Stores the duplicated handle in the pointer (must not be NULL).
00312                      * @param newOwner  New owner of cloned handle.
00313                      * @param pSecurity Security information struct (may be NULL).
00314                      * @return                              A HandleError error code.
00315                      */
00316                     virtual HandleError CloneHandle(Handle_t handle, 
00317                                                                                                     Handle_t *newhandle, 
00318                                                                                                     IdentityToken_t *newOwner,
00319                                                                                                     const HandleSecurity *pSecurity) =0;
00320 
00321                     /**
00322                      * @brief Retrieves the contents of a handle.
00323                      *
00324                      * @param handle    Handle_t from which to retrieve contents.
00325                      * @param type                Expected type to read as.  0 ignores typing rules.
00326                      * @param pSecurity Security information struct (may be NULL).
00327                      * @param object    Optional address to store object in.
00328                      * @return                              HandleError error code.
00329                      */
00330                     virtual HandleError ReadHandle(Handle_t handle, 
00331                                                                                              HandleType_t type, 
00332                                                                                              const HandleSecurity *pSecurity,
00333                                                                                              void **object) =0;
00334 
00335                     /**
00336                      * @brief Sets access permissions on one or more structures.
00337                      *
00338                      * @param pTypeAccess         Optional TypeAccess buffer to initialize with the default values.
00339                      * @param pHandleAccess       Optional HandleAccess buffer to initialize with the default values.
00340                      * @return                                        True on success, false if version is unsupported.
00341                      */
00342                     virtual bool InitAccessDefaults(TypeAccess *pTypeAccess, HandleAccess *pHandleAccess) =0;
00343 
00344                     /**
00345                      * @brief Creates a new handle.
00346                      * 
00347                      * @param type                Type to use on the handle.
00348                      * @param object    Object to bind to the handle.
00349                      * @param pSec                Security pointer; pOwner is written as the owner,
00350                      *                                                pIdent is used as the parent identity for authorization.
00351                      * @param pAccess   Access right descriptor for the Handle; NULL for type defaults.
00352                      * @param err                 Optional pointer to store an error code on failure (undefined on success).
00353                      * @return                              A new Handle_t, or 0 on failure.
00354                      */
00355                     virtual Handle_t CreateHandleEx(HandleType_t type, 
00356                                                                                                     void *object,
00357                                                                                                     const HandleSecurity *pSec,
00358                                                                                                     const HandleAccess *pAccess,
00359                                                                                                     HandleError *err) =0;
00360 
00361                     /**
00362                      * @brief Clones a handle, bypassing security checks.
00363                      *
00364                      * @return          A new Handle_t, or 0 on failure.
00365                      */
00366                     virtual Handle_t FastCloneHandle(Handle_t hndl) =0;
00367           };
00368 }
00369 
00370 #endif //_INCLUDE_SOURCEMOD_HANDLESYSTEM_INTERFACE_H_
00371 

Generated on Wed Dec 7 2011 18:50:02 for SourceMod SDK by  doxygen 1.7.1