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
1.7.1