public/IHandleSys.h
author Scott Ehlert <ds@alliedmods.net>
Wed Aug 15 06:19:30 2007 +0000 (2007-08-15)
changeset 1330 ab94316bb52b
parent 1226 478550a4d5ec
child 1766 d30c252089be
permissions -rw-r--r--
Updated license headers on virtually all files with extremely minor changes in the name of some sort of strange consistency.
All plugin and include file headers also have been changed to say about GPL3 instead of GPL2.

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