restructure of HandleSys admin permissions and interface
removal of HandleSys helper functions removed useless BaseContext stuff from Engine put SourceMod specific stuff in BaseContext cleaned up broken Handle code --HG-- extra : convert_revision : svn%3A39bc706e-5318-0410-9160-8a85361fbb7c/trunk%40267
This commit is contained in:
		
							parent
							
								
									15beb5afb0
								
							
						
					
					
						commit
						4bd40d69e1
					
				@ -43,34 +43,72 @@ namespace SourceMod
 | 
			
		||||
		HandleError_Limit,			/* The limited number of handles has been reached */
 | 
			
		||||
		HandleError_Identity,		/* The identity token was not usable */
 | 
			
		||||
		HandleError_Owner,			/* Owners do not match for this operation */
 | 
			
		||||
		HandleError_Version,		/* Unrecognized security structure version */
 | 
			
		||||
		HandleError_Parameter,		/* An invalid parameter was passed */
 | 
			
		||||
		HandleError_NoInherit,		/* This type cannot be inherited */
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Access rights specific to a type
 | 
			
		||||
	 */
 | 
			
		||||
	enum HTypeAccessRight
 | 
			
		||||
	{
 | 
			
		||||
		HTypeAccess_Create = 0,		/* Handles of this type can be created (DEFAULT=false) */
 | 
			
		||||
		HTypeAccess_Inherit,		/* Sub-types can inherit this type (DEFAULT=false) */
 | 
			
		||||
		/* -------------- */
 | 
			
		||||
		HTypeAccess_TOTAL,			/* Total number of type access rights */
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * Access rights specific to a Handle.  These rights are exclusive.
 | 
			
		||||
	 * For example, you do not need "read" access to delete or clone.
 | 
			
		||||
	 */
 | 
			
		||||
	enum HandleAccessRight
 | 
			
		||||
	{
 | 
			
		||||
		HandleAccess_Create,		/* TYPE: Instances can be created by other objects (this makes it searchable) */
 | 
			
		||||
		HandleAccess_Read,			/* HANDLES: Can be read by other objects */
 | 
			
		||||
		HandleAccess_IdentDelete,	/* HANDLES: Can be deleted by other identities */
 | 
			
		||||
		HandleAccess_OwnerDelete,	/* HANDLES: Can be deleted by other owners */
 | 
			
		||||
		HandleAccess_Inherit,		/* TYPE: Can be inherited by new types */
 | 
			
		||||
		HandleAccess_Clone,			/* HANDLES: Can be cloned */
 | 
			
		||||
		HandleAccess_Read,			/* Can be read (DEFAULT=ident only) */
 | 
			
		||||
		HandleAccess_Delete,		/* Can be deleted (DEFAULT=owner only) */
 | 
			
		||||
		HandleAccess_Clone,			/* Can be cloned (DEFAULT=any) */
 | 
			
		||||
		/* ------------- */
 | 
			
		||||
		HandleAccess_TOTAL,			/* Total number of access rights */
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	#define HANDLE_RESTRICT_IDENTITY	(1<<0)	/* Access is restricted to the identity */
 | 
			
		||||
	#define HANDLE_RESTRICT_OWNER		(1<<1)	/* Access is restricted to the owner */
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * This is used to define per-type access rights.
 | 
			
		||||
	 */
 | 
			
		||||
	struct TypeAccess
 | 
			
		||||
	{
 | 
			
		||||
		TypeAccess()
 | 
			
		||||
		{
 | 
			
		||||
			hsVersion = SMINTERFACE_HANDLESYSTEM_VERSION;
 | 
			
		||||
		}
 | 
			
		||||
		unsigned int hsVersion;
 | 
			
		||||
		IdentityToken_t *ident;
 | 
			
		||||
		bool access[HTypeAccess_TOTAL];
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * This is used to define per-Handle access rights.
 | 
			
		||||
	 */
 | 
			
		||||
	struct HandleAccess
 | 
			
		||||
	{
 | 
			
		||||
		HandleAccess()
 | 
			
		||||
		{
 | 
			
		||||
			hsVersion = SMINTERFACE_HANDLESYSTEM_VERSION;
 | 
			
		||||
		}
 | 
			
		||||
		unsigned int hsVersion;
 | 
			
		||||
		unsigned int access[HandleAccess_TOTAL];
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
	 * This pair of tokens is used for identification.
 | 
			
		||||
	 */
 | 
			
		||||
	struct HandleSecurity
 | 
			
		||||
	{
 | 
			
		||||
		HandleSecurity()
 | 
			
		||||
		{
 | 
			
		||||
			owner = NULL;
 | 
			
		||||
			access[HandleAccess_Create] = true;
 | 
			
		||||
			access[HandleAccess_Read] = true;
 | 
			
		||||
			access[HandleAccess_IdentDelete] = true;
 | 
			
		||||
			access[HandleAccess_Inherit] = true;
 | 
			
		||||
			access[HandleAccess_Clone] = true;
 | 
			
		||||
			access[HandleAccess_OwnerDelete] = false;
 | 
			
		||||
		}
 | 
			
		||||
		IdentityToken_t *owner;				/* Owner of the handle */
 | 
			
		||||
		bool access[HandleAccess_TOTAL];	/* World access rights */
 | 
			
		||||
		IdentityToken_t *pOwner;			/* Owner of the Handle */
 | 
			
		||||
		IdentityToken_t *pIdentity;			/* Owner of the Type */
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
	class IHandleTypeDispatch
 | 
			
		||||
@ -99,17 +137,6 @@ namespace SourceMod
 | 
			
		||||
			return SMINTERFACE_HANDLESYSTEM_NAME;
 | 
			
		||||
		}
 | 
			
		||||
	public:
 | 
			
		||||
		/**
 | 
			
		||||
		 * @brief Creates a new Handle type.  
 | 
			
		||||
		 * NOTE: Handle names must be unique if not private.
 | 
			
		||||
		 *
 | 
			
		||||
		 * @param name		Name of handle type (NULL or "" to be anonymous)
 | 
			
		||||
		 * @param dispatch	Pointer to a valid IHandleTypeDispatch object.
 | 
			
		||||
		 * @return			A new HandleType_t unique ID, or 0 on failure.
 | 
			
		||||
		 */
 | 
			
		||||
		virtual HandleType_t CreateType(const char *name, 
 | 
			
		||||
										IHandleTypeDispatch *dispatch) =0;
 | 
			
		||||
 | 
			
		||||
		/**
 | 
			
		||||
		 * @brief Creates a new Handle type.
 | 
			
		||||
		 * NOTE: Currently, a child type may not have its own children.
 | 
			
		||||
@ -118,39 +145,30 @@ namespace SourceMod
 | 
			
		||||
		 * @param name		Name of handle type (NULL or "" to be anonymous)
 | 
			
		||||
		 * @param dispatch	Pointer to a valid IHandleTypeDispatch object.
 | 
			
		||||
		 * @param parent	Parent handle to inherit from, 0 for none.
 | 
			
		||||
		 * @param security	Pointer to a temporary HandleSecurity object, NULL to use default 
 | 
			
		||||
		 *					or inherited permissions.
 | 
			
		||||
		 * @param ident		Security token for any permissions.
 | 
			
		||||
		 * @param typeAccess	Pointer to a TypeAccess object, NULL to use default 
 | 
			
		||||
		 *						or inherited permissions.  Pointer can be temporary.
 | 
			
		||||
		 * @param hndlAccess	Pointer to a HandleAccess object to define default
 | 
			
		||||
		 *						default permissions on each Handle.  NULL to use default
 | 
			
		||||
		 *						permissions.
 | 
			
		||||
		 * @param ident		Security token for any permissions.  If typeAccess is NULL, this 
 | 
			
		||||
		 *					becomes the owning identity.
 | 
			
		||||
		 * @param err		Optional pointer to store an error code.
 | 
			
		||||
		 * @return			A new HandleType_t unique ID, or 0 on failure.
 | 
			
		||||
		 */
 | 
			
		||||
		virtual HandleType_t CreateTypeEx(const char *name,
 | 
			
		||||
		virtual HandleType_t CreateType(const char *name,
 | 
			
		||||
										  IHandleTypeDispatch *dispatch,
 | 
			
		||||
										  HandleType_t parent,
 | 
			
		||||
										  const HandleSecurity *security,
 | 
			
		||||
										  IdentityToken_t *ident) =0;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		/**
 | 
			
		||||
		 * @brief Creates a sub-type for a Handle.
 | 
			
		||||
		 * NOTE: Currently, a child type may not have its own children.
 | 
			
		||||
		 * NOTE: Handle names must be unique if not private.
 | 
			
		||||
		 * NOTE: This is a wrapper around the above.
 | 
			
		||||
		 *
 | 
			
		||||
		 * @param name		Name of a handle.
 | 
			
		||||
		 * @param parent	Parent handle type.
 | 
			
		||||
		 * @param dispatch	Pointer to a valid IHandleTypeDispatch object.
 | 
			
		||||
		 * @return			A new HandleType_t unique ID.
 | 
			
		||||
		 */
 | 
			
		||||
		virtual HandleType_t CreateChildType(const char *name, 
 | 
			
		||||
										     HandleType_t parent, 
 | 
			
		||||
										     IHandleTypeDispatch *dispatch) =0;
 | 
			
		||||
										  const TypeAccess *typeAccess,
 | 
			
		||||
										  const HandleAccess *hndlAccess,
 | 
			
		||||
										  IdentityToken_t *ident,
 | 
			
		||||
										  HandleError *err) =0;
 | 
			
		||||
 | 
			
		||||
		/**
 | 
			
		||||
		 * @brief Removes a handle type.
 | 
			
		||||
		 * NOTE: This removes all child types.
 | 
			
		||||
		 *
 | 
			
		||||
		 * @param token		Identity token.  Removal fails if the token does not match.
 | 
			
		||||
		 * @param type		Type chain to remove.
 | 
			
		||||
		 * @param ident		Identity token.  Removal fails if the token does not match.
 | 
			
		||||
		 * @return			True on success, false on failure.
 | 
			
		||||
		 */
 | 
			
		||||
		virtual bool RemoveType(HandleType_t type, IdentityToken_t *ident) =0;
 | 
			
		||||
@ -169,29 +187,16 @@ namespace SourceMod
 | 
			
		||||
		 * 
 | 
			
		||||
		 * @param type		Type to use on the handle.
 | 
			
		||||
		 * @param object	Object to bind to the handle.
 | 
			
		||||
		 * @param owner		Owner for the handle.  NULL means anonymous (no owner).
 | 
			
		||||
		 * @param ident		Identity token if any security rights are needed.
 | 
			
		||||
		 * @param owner		Owner of the new Handle (may be NULL).
 | 
			
		||||
		 * @param ident		Identity for type access if needed (may be NULL).
 | 
			
		||||
		 * @param err		Optional pointer to store an error code.
 | 
			
		||||
		 * @return			A new Handle_t, or 0 on failure.
 | 
			
		||||
		 */
 | 
			
		||||
		virtual Handle_t CreateHandle(HandleType_t type, 
 | 
			
		||||
										void *object, 
 | 
			
		||||
										IdentityToken_t *owner, 
 | 
			
		||||
										IdentityToken_t *ident) =0;
 | 
			
		||||
 | 
			
		||||
		/**
 | 
			
		||||
		 * @brief Creates a new handle.
 | 
			
		||||
		 * NOTE: This is a wrapper around the above function.
 | 
			
		||||
		 * 
 | 
			
		||||
		 * @param type		Type to use on the handle.
 | 
			
		||||
		 * @param object	Object to bind to the handle.
 | 
			
		||||
		 * @param pOwner	Plugin context that will own this handle.  NULL for none.
 | 
			
		||||
		 * @param ident		Identity token if any security rights are needed.
 | 
			
		||||
		 * @return			A new Handle_t.
 | 
			
		||||
		 */
 | 
			
		||||
		virtual Handle_t CreateScriptHandle(HandleType_t type, 
 | 
			
		||||
											void *object, 
 | 
			
		||||
											SourcePawn::IPluginContext *pOwner,
 | 
			
		||||
											IdentityToken_t *ident) =0;
 | 
			
		||||
									  void *object,
 | 
			
		||||
									  IdentityToken_t *owner,
 | 
			
		||||
									  IdentityToken_t *ident,
 | 
			
		||||
									  HandleError *err) =0;
 | 
			
		||||
 | 
			
		||||
		/**
 | 
			
		||||
		 * @brief Frees the memory associated with a handle and calls any destructors.
 | 
			
		||||
@ -199,34 +204,48 @@ namespace SourceMod
 | 
			
		||||
		 * only perform any further action if the counter hits 0.
 | 
			
		||||
		 *
 | 
			
		||||
		 * @param type		Handle_t identifier to destroy.
 | 
			
		||||
		 * @param owner		Owner of handle (NULL for none).
 | 
			
		||||
		 * @param ident		Identity token, for destroying secure handles (NULL for none).
 | 
			
		||||
		 * @param pSecurity	Security information struct (may be NULL).
 | 
			
		||||
		 * @return			A HandleError error code.
 | 
			
		||||
		 */
 | 
			
		||||
		virtual HandleError FreeHandle(Handle_t handle, IdentityToken_t *owner, IdentityToken_t *ident) =0;
 | 
			
		||||
		virtual HandleError FreeHandle(Handle_t handle, const HandleSecurity *pSecurity) =0;
 | 
			
		||||
 | 
			
		||||
		/**
 | 
			
		||||
		 * @brief Clones a handle by adding to its internal reference count.  Its data,
 | 
			
		||||
		 * type, and security permissions remain the same.
 | 
			
		||||
		 *
 | 
			
		||||
		 * @param handle	Handle to duplicate.  Any non-free handle target is valid.
 | 
			
		||||
		 * @param newhandle	If non-NULL, stores the duplicated handle in the pointer.
 | 
			
		||||
		 * @param owner		New owner of cloned handle.
 | 
			
		||||
		 * @param ident		Security token, if needed.
 | 
			
		||||
		 * @param newhandle	Stores the duplicated handle in the pointer (must not be NULL).
 | 
			
		||||
		 * @param newOwner	New owner of cloned handle.
 | 
			
		||||
		 * @param pSecurity	Security information struct (may be NULL).
 | 
			
		||||
		 * @return			A HandleError error code.
 | 
			
		||||
		 */
 | 
			
		||||
		virtual HandleError CloneHandle(Handle_t handle, Handle_t *newhandle, IdentityToken_t *owner, IdentityToken_t *ident) =0;
 | 
			
		||||
		virtual HandleError CloneHandle(Handle_t handle, 
 | 
			
		||||
										Handle_t *newhandle, 
 | 
			
		||||
										IdentityToken_t *newOwner,
 | 
			
		||||
										const HandleSecurity *pSecurity) =0;
 | 
			
		||||
 | 
			
		||||
		/**
 | 
			
		||||
		 * @brief Retrieves the contents of a handle.
 | 
			
		||||
		 *
 | 
			
		||||
		 * @param handle	Handle_t from which to retrieve contents.
 | 
			
		||||
		 * @param type		Expected type to read as.  0 ignores typing rules.
 | 
			
		||||
		 * @param ident		Identity token to validate as.
 | 
			
		||||
		 * @param pSecurity	Security information struct (may be NULL).
 | 
			
		||||
		 * @param object	Optional address to store object in.
 | 
			
		||||
		 * @return			HandleError error code.
 | 
			
		||||
		 */
 | 
			
		||||
		virtual HandleError ReadHandle(Handle_t handle, HandleType_t type, IdentityToken_t *ident, void **object) =0;
 | 
			
		||||
		virtual HandleError ReadHandle(Handle_t handle, 
 | 
			
		||||
									   HandleType_t type, 
 | 
			
		||||
									   const HandleSecurity *pSecurity,
 | 
			
		||||
									   void **object) =0;
 | 
			
		||||
 | 
			
		||||
		/**
 | 
			
		||||
		 * @brief Sets access permissions on one or more structures.
 | 
			
		||||
		 *
 | 
			
		||||
		 * @param pTypeAccess	Optional TypeAccess buffer to initialize with the default values.
 | 
			
		||||
		 * @param pHandleAccess	Optional HandleAccess buffer to initialize with the default values.
 | 
			
		||||
		 * @return			True on success, false if version is unsupported.
 | 
			
		||||
		 */
 | 
			
		||||
		virtual bool InitAccessDefaults(TypeAccess *pTypeAccess, HandleAccess *pHandleAccess) =0;
 | 
			
		||||
	};
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -41,7 +41,7 @@
 | 
			
		||||
				Name="VCCLCompilerTool"
 | 
			
		||||
				Optimization="0"
 | 
			
		||||
				AdditionalIncludeDirectories="..\interfaces;..\;..\systems;..\..\sourcepawn\include"
 | 
			
		||||
				PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;SOURCEMOD_MM_EXPORTS;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE"
 | 
			
		||||
				PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;SOURCEMOD_MM_EXPORTS;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;SOURCEMOD_BUILD"
 | 
			
		||||
				MinimalRebuild="true"
 | 
			
		||||
				BasicRuntimeChecks="3"
 | 
			
		||||
				RuntimeLibrary="1"
 | 
			
		||||
 | 
			
		||||
@ -12,13 +12,8 @@ class FileNatives :
 | 
			
		||||
public:
 | 
			
		||||
	virtual void OnSourceModAllInitialized()
 | 
			
		||||
	{
 | 
			
		||||
		HandleSecurity sec;
 | 
			
		||||
		sec.owner = g_pCoreIdent;
 | 
			
		||||
		sec.access[HandleAccess_Inherit] = false;
 | 
			
		||||
		sec.access[HandleAccess_Create] = false;
 | 
			
		||||
 | 
			
		||||
		g_FileType = g_HandleSys.CreateTypeEx("File", this, 0, &sec, NULL);
 | 
			
		||||
		g_DirType = g_HandleSys.CreateTypeEx("Directory", this, 0, &sec, NULL);
 | 
			
		||||
		g_FileType = g_HandleSys.CreateType("File", this, 0, NULL, NULL, g_pCoreIdent, NULL);
 | 
			
		||||
		g_DirType = g_HandleSys.CreateType("Directory", this, 0, NULL, NULL, g_pCoreIdent, NULL);
 | 
			
		||||
	}
 | 
			
		||||
	virtual void OnSourceModShutdown()
 | 
			
		||||
	{
 | 
			
		||||
@ -60,17 +55,21 @@ cell_t sm_OpenDirectory(IPluginContext *pContext, const cell_t *params)
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return g_HandleSys.CreateScriptHandle(g_DirType, pDir, pContext, g_pCoreIdent);
 | 
			
		||||
	return g_HandleSys.CreateHandle(g_DirType, pDir, pContext->GetIdentity(), g_pCoreIdent, NULL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
cell_t sm_ReadDirEntry(IPluginContext *pContext, const cell_t *params)
 | 
			
		||||
{
 | 
			
		||||
	Handle_t hndl = static_cast<Handle_t>(params[1]);
 | 
			
		||||
 | 
			
		||||
	IDirectory *pDir;
 | 
			
		||||
	HandleError herr;
 | 
			
		||||
	HandleSecurity sec;
 | 
			
		||||
	int err;
 | 
			
		||||
	if ((herr=g_HandleSys.ReadHandle(hndl, g_DirType, g_pCoreIdent, (void **)&pDir))
 | 
			
		||||
 | 
			
		||||
	sec.pOwner = NULL;
 | 
			
		||||
	sec.pIdentity = g_pCoreIdent;
 | 
			
		||||
 | 
			
		||||
	if ((herr=g_HandleSys.ReadHandle(hndl, g_DirType, &sec, (void **)&pDir))
 | 
			
		||||
		!= HandleError_None)
 | 
			
		||||
	{
 | 
			
		||||
		return pContext->ThrowNativeError("Invalid file handle %x (error %d)", hndl, herr);
 | 
			
		||||
 | 
			
		||||
@ -24,7 +24,12 @@ static cell_t sm_CloseHandle(IPluginContext *pContext, const cell_t *params)
 | 
			
		||||
	/* :TODO: make this a little bit cleaner, eh? */
 | 
			
		||||
	IPlugin *pPlugin = g_PluginSys.FindPluginByContext(pContext->GetContext());
 | 
			
		||||
 | 
			
		||||
	HandleError err = g_HandleSys.FreeHandle(hndl, pPlugin->GetIdentity(), NULL);
 | 
			
		||||
	HandleSecurity sec;
 | 
			
		||||
 | 
			
		||||
	sec.pIdentity = NULL;
 | 
			
		||||
	sec.pOwner = pContext->GetIdentity();
 | 
			
		||||
 | 
			
		||||
	HandleError err = g_HandleSys.FreeHandle(hndl, &sec);
 | 
			
		||||
  
 | 
			
		||||
	if (err == HandleError_None)
 | 
			
		||||
	{
 | 
			
		||||
 | 
			
		||||
@ -14,7 +14,7 @@ inline HandleType_t TypeParent(HandleType_t type)
 | 
			
		||||
 | 
			
		||||
inline HandleError IdentityHandle(IdentityToken_t *token, unsigned int *index)
 | 
			
		||||
{
 | 
			
		||||
	return g_HandleSys.GetHandle(token->ident, g_ShareSys.GetIdentRoot(), &ignore_handle, index, HandleAccess_Read);
 | 
			
		||||
	return g_HandleSys.GetHandle(token->ident, g_ShareSys.GetIdentRoot(), &ignore_handle, index);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
HandleSystem::HandleSystem()
 | 
			
		||||
@ -39,24 +39,39 @@ HandleSystem::~HandleSystem()
 | 
			
		||||
	delete m_strtab;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
HandleType_t HandleSystem::CreateType(const char *name, IHandleTypeDispatch *dispatch)
 | 
			
		||||
{
 | 
			
		||||
	return CreateTypeEx(name, dispatch, 0, NULL, NULL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
HandleType_t HandleSystem::CreateChildType(const char *name, HandleType_t parent, IHandleTypeDispatch *dispatch)
 | 
			
		||||
{
 | 
			
		||||
	return CreateTypeEx(name, dispatch, parent, NULL, NULL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
HandleType_t HandleSystem::CreateTypeEx(const char *name, 
 | 
			
		||||
										IHandleTypeDispatch *dispatch, 
 | 
			
		||||
										HandleType_t parent, 
 | 
			
		||||
										const HandleSecurity *security,
 | 
			
		||||
										IdentityToken_t *ident)
 | 
			
		||||
HandleType_t HandleSystem::CreateType(const char *name, 
 | 
			
		||||
									  IHandleTypeDispatch *dispatch, 
 | 
			
		||||
									  HandleType_t parent, 
 | 
			
		||||
									  const TypeAccess *typeAccess, 
 | 
			
		||||
									  const HandleAccess *hndlAccess, 
 | 
			
		||||
									  IdentityToken_t *ident,
 | 
			
		||||
									  HandleError *err)
 | 
			
		||||
{
 | 
			
		||||
	if (!dispatch)
 | 
			
		||||
	{
 | 
			
		||||
		if (err)
 | 
			
		||||
		{
 | 
			
		||||
			*err = HandleError_Parameter;
 | 
			
		||||
		}
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (typeAccess && typeAccess->hsVersion > SMINTERFACE_HANDLESYSTEM_VERSION)
 | 
			
		||||
	{
 | 
			
		||||
		if (err)
 | 
			
		||||
		{
 | 
			
		||||
			*err = HandleError_Version;
 | 
			
		||||
		}
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (hndlAccess && hndlAccess->hsVersion > SMINTERFACE_HANDLESYSTEM_VERSION)
 | 
			
		||||
	{
 | 
			
		||||
		if (err)
 | 
			
		||||
		{
 | 
			
		||||
			*err = HandleError_Version;
 | 
			
		||||
		}
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
@ -67,34 +82,44 @@ HandleType_t HandleSystem::CreateTypeEx(const char *name,
 | 
			
		||||
		isChild = true;
 | 
			
		||||
		if (parent & HANDLESYS_SUBTYPE_MASK)
 | 
			
		||||
		{
 | 
			
		||||
			if (err)
 | 
			
		||||
			{
 | 
			
		||||
				*err = HandleError_NoInherit;
 | 
			
		||||
			}
 | 
			
		||||
			return 0;
 | 
			
		||||
		}
 | 
			
		||||
		if (parent >= HANDLESYS_TYPEARRAY_SIZE
 | 
			
		||||
			|| m_Types[parent].dispatch == NULL
 | 
			
		||||
			|| (m_Types[parent].sec.access[HandleAccess_Inherit] == false
 | 
			
		||||
				&& m_Types[parent].sec.owner != ident))
 | 
			
		||||
			|| m_Types[parent].dispatch == NULL)
 | 
			
		||||
		{
 | 
			
		||||
			if (err)
 | 
			
		||||
			{
 | 
			
		||||
				*err = HandleError_Parameter;
 | 
			
		||||
			}
 | 
			
		||||
			return 0;
 | 
			
		||||
		}
 | 
			
		||||
		if (m_Types[parent].typeSec.access[HTypeAccess_Inherit] == false
 | 
			
		||||
			&& (m_Types[parent].typeSec.ident != ident))
 | 
			
		||||
		{
 | 
			
		||||
			if (err)
 | 
			
		||||
			{
 | 
			
		||||
				*err = HandleError_Access;
 | 
			
		||||
			}
 | 
			
		||||
			return 0;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (!security)
 | 
			
		||||
	if (name && name[0] != '\0')
 | 
			
		||||
	{
 | 
			
		||||
		if (isChild)
 | 
			
		||||
		if (sm_trie_retrieve(m_TypeLookup, name, NULL))
 | 
			
		||||
		{
 | 
			
		||||
			security = &m_Types[parent].sec;
 | 
			
		||||
		} else {
 | 
			
		||||
			static HandleSecurity def_h;
 | 
			
		||||
			security = &def_h;
 | 
			
		||||
			if (err)
 | 
			
		||||
			{
 | 
			
		||||
				*err = HandleError_Parameter;
 | 
			
		||||
			}
 | 
			
		||||
			return 0;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (security->access[HandleAccess_Create]
 | 
			
		||||
		&& sm_trie_retrieve(m_TypeLookup, name, NULL))
 | 
			
		||||
	{
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	unsigned int index;
 | 
			
		||||
 | 
			
		||||
	if (isChild)
 | 
			
		||||
@ -102,6 +127,10 @@ HandleType_t HandleSystem::CreateTypeEx(const char *name,
 | 
			
		||||
		QHandleType *pParent = &m_Types[parent];
 | 
			
		||||
		if (pParent->children >= HANDLESYS_MAX_SUBTYPES)
 | 
			
		||||
		{
 | 
			
		||||
			if (err)
 | 
			
		||||
			{
 | 
			
		||||
				*err = HandleError_Limit;
 | 
			
		||||
			}
 | 
			
		||||
			return 0;
 | 
			
		||||
		}
 | 
			
		||||
		index = 0;
 | 
			
		||||
@ -115,6 +144,10 @@ HandleType_t HandleSystem::CreateTypeEx(const char *name,
 | 
			
		||||
		}
 | 
			
		||||
		if (!index)
 | 
			
		||||
		{
 | 
			
		||||
			if (err)
 | 
			
		||||
			{
 | 
			
		||||
				*err = HandleError_Limit;
 | 
			
		||||
			}
 | 
			
		||||
			return 0;
 | 
			
		||||
		}
 | 
			
		||||
		pParent->children++;
 | 
			
		||||
@ -124,6 +157,10 @@ HandleType_t HandleSystem::CreateTypeEx(const char *name,
 | 
			
		||||
			/* Reserve another index */
 | 
			
		||||
			if (m_TypeTail >= HANDLESYS_TYPEARRAY_SIZE)
 | 
			
		||||
			{
 | 
			
		||||
				if (err)
 | 
			
		||||
				{
 | 
			
		||||
					*err = HandleError_Limit;
 | 
			
		||||
				}
 | 
			
		||||
				return 0;
 | 
			
		||||
			} else {
 | 
			
		||||
				m_TypeTail += (HANDLESYS_MAX_SUBTYPES + 1);
 | 
			
		||||
@ -145,9 +182,24 @@ HandleType_t HandleSystem::CreateTypeEx(const char *name,
 | 
			
		||||
	} else {
 | 
			
		||||
		pType->nameIdx = -1;
 | 
			
		||||
	}
 | 
			
		||||
	pType->sec = *security;
 | 
			
		||||
 | 
			
		||||
	pType->opened = 0;
 | 
			
		||||
 | 
			
		||||
	if (typeAccess)
 | 
			
		||||
	{
 | 
			
		||||
		pType->typeSec = *typeAccess;
 | 
			
		||||
	} else {
 | 
			
		||||
		InitAccessDefaults(&pType->typeSec, NULL);
 | 
			
		||||
		pType->typeSec.ident = ident;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (hndlAccess)
 | 
			
		||||
	{
 | 
			
		||||
		pType->hndlSec = *hndlAccess;
 | 
			
		||||
	} else {
 | 
			
		||||
		InitAccessDefaults(NULL, &pType->hndlSec);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (!isChild)
 | 
			
		||||
	{
 | 
			
		||||
		pType->children = 0;
 | 
			
		||||
@ -264,33 +316,46 @@ void HandleSystem::SetTypeSecurityOwner(HandleType_t type, IdentityToken_t *pTok
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	m_Types[type].sec.owner = pToken;
 | 
			
		||||
	m_Types[type].typeSec.ident = pToken;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Handle_t HandleSystem::CreateHandle(HandleType_t type, void *object, IdentityToken_t *source, IdentityToken_t *ident)
 | 
			
		||||
Handle_t HandleSystem::CreateHandle(HandleType_t type, void *object, IdentityToken_t *owner, IdentityToken_t *ident, HandleError *err)
 | 
			
		||||
{
 | 
			
		||||
	if (!type 
 | 
			
		||||
		|| type >= HANDLESYS_TYPEARRAY_SIZE
 | 
			
		||||
		|| m_Types[type].dispatch == NULL)
 | 
			
		||||
	{
 | 
			
		||||
		if (err)
 | 
			
		||||
		{
 | 
			
		||||
			*err = HandleError_Parameter;
 | 
			
		||||
		}
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Check the security of this handle */
 | 
			
		||||
	/* Check to see if we're allowed to create this handle type */
 | 
			
		||||
	QHandleType *pType = &m_Types[type];
 | 
			
		||||
	if (!pType->sec.access[HandleAccess_Create]
 | 
			
		||||
		&& pType->sec.owner != ident)
 | 
			
		||||
	if (!pType->typeSec.access[HTypeAccess_Create]
 | 
			
		||||
		&& (!pType->typeSec.ident
 | 
			
		||||
			|| pType->typeSec.ident != ident))
 | 
			
		||||
	{
 | 
			
		||||
		if (err)
 | 
			
		||||
		{
 | 
			
		||||
			*err = HandleError_Access;
 | 
			
		||||
		}
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	unsigned int index;
 | 
			
		||||
	Handle_t handle;
 | 
			
		||||
	QHandle *pHandle;
 | 
			
		||||
	HandleError err;
 | 
			
		||||
	HandleError _err;
 | 
			
		||||
 | 
			
		||||
	if ((err=MakePrimHandle(type, &pHandle, &index, &handle, source)) != HandleError_None)
 | 
			
		||||
	if ((_err=MakePrimHandle(type, &pHandle, &index, &handle, owner)) != HandleError_None)
 | 
			
		||||
	{
 | 
			
		||||
		if (err)
 | 
			
		||||
		{
 | 
			
		||||
			*err = _err;
 | 
			
		||||
		}
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
@ -300,16 +365,6 @@ Handle_t HandleSystem::CreateHandle(HandleType_t type, void *object, IdentityTok
 | 
			
		||||
	return handle;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Handle_t HandleSystem::CreateScriptHandle(HandleType_t type, 
 | 
			
		||||
										  void *object, 
 | 
			
		||||
										  IPluginContext *pContext, 
 | 
			
		||||
										  IdentityToken_t *ident)
 | 
			
		||||
{
 | 
			
		||||
	IPlugin *pPlugin = g_PluginSys.FindPluginByContext(pContext->GetContext());
 | 
			
		||||
 | 
			
		||||
	return CreateHandle(type, object, pPlugin->GetIdentity(), ident);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool HandleSystem::TypeCheck(HandleType_t intype, HandleType_t outtype)
 | 
			
		||||
{
 | 
			
		||||
	/* Check the type inheritance */
 | 
			
		||||
@ -334,7 +389,6 @@ HandleError HandleSystem::GetHandle(Handle_t handle,
 | 
			
		||||
									IdentityToken_t *ident, 
 | 
			
		||||
									QHandle **in_pHandle, 
 | 
			
		||||
									unsigned int *in_index,
 | 
			
		||||
									HandleAccessRight access,
 | 
			
		||||
									bool ignoreFree)
 | 
			
		||||
{
 | 
			
		||||
	unsigned int serial = (handle >> 16);
 | 
			
		||||
@ -348,11 +402,6 @@ HandleError HandleSystem::GetHandle(Handle_t handle,
 | 
			
		||||
	QHandle *pHandle = &m_Handles[index];
 | 
			
		||||
	QHandleType *pType = &m_Types[pHandle->type];
 | 
			
		||||
 | 
			
		||||
	if ((access != HandleAccess_TOTAL)
 | 
			
		||||
		&& (!pType->sec.access[access] && pType->sec.owner != ident))
 | 
			
		||||
	{
 | 
			
		||||
		return HandleError_Access;
 | 
			
		||||
	}
 | 
			
		||||
	if (!pHandle->set
 | 
			
		||||
		|| (pHandle->set == HandleSet_Freed && !ignoreFree))
 | 
			
		||||
	{
 | 
			
		||||
@ -374,13 +423,44 @@ HandleError HandleSystem::GetHandle(Handle_t handle,
 | 
			
		||||
	return HandleError_None;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
HandleError HandleSystem::CloneHandle(Handle_t handle, Handle_t *out_newhandle, IdentityToken_t *source, IdentityToken_t *ident)
 | 
			
		||||
bool HandleSystem::CheckAccess(QHandle *pHandle, HandleAccessRight right, const HandleSecurity *pSecurity)
 | 
			
		||||
{
 | 
			
		||||
	QHandleType *pType = &m_Types[pHandle->type];
 | 
			
		||||
	unsigned int access = pType->hndlSec.access[right];
 | 
			
		||||
 | 
			
		||||
	/* Check if the type's identity matches */
 | 
			
		||||
	if (access & HANDLE_RESTRICT_IDENTITY)
 | 
			
		||||
	{
 | 
			
		||||
		IdentityToken_t *owner = pType->typeSec.ident;
 | 
			
		||||
		if (!owner
 | 
			
		||||
			|| (!pSecurity || pSecurity->pIdentity != owner))
 | 
			
		||||
		{
 | 
			
		||||
			return false;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Check if the owner is allowed */
 | 
			
		||||
	if (access & HANDLE_RESTRICT_OWNER)
 | 
			
		||||
	{
 | 
			
		||||
		IdentityToken_t *owner = pHandle->owner;
 | 
			
		||||
		if (owner
 | 
			
		||||
			&& (!pSecurity || pSecurity->pOwner != owner))
 | 
			
		||||
		{
 | 
			
		||||
			return false;
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
HandleError HandleSystem::CloneHandle(Handle_t handle, Handle_t *newhandle, IdentityToken_t *newOwner, const HandleSecurity *pSecurity)
 | 
			
		||||
{
 | 
			
		||||
	HandleError err;
 | 
			
		||||
	QHandle *pHandle;
 | 
			
		||||
	unsigned int index;
 | 
			
		||||
	IdentityToken_t *ident = pSecurity ? pSecurity->pIdentity : NULL;
 | 
			
		||||
 | 
			
		||||
	if ((err=GetHandle(handle, ident, &pHandle, &index, HandleAccess_Clone)) != HandleError_None)
 | 
			
		||||
	if ((err=GetHandle(handle, ident, &pHandle, &index)) != HandleError_None)
 | 
			
		||||
	{
 | 
			
		||||
		return err;
 | 
			
		||||
	}
 | 
			
		||||
@ -391,49 +471,49 @@ HandleError HandleSystem::CloneHandle(Handle_t handle, Handle_t *out_newhandle,
 | 
			
		||||
		return HandleError_Identity;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	QHandleType *pType = &m_Types[pHandle->type];
 | 
			
		||||
	/* Check if the handle can be cloned */
 | 
			
		||||
	if (!CheckAccess(pHandle, HandleAccess_Clone, pSecurity))
 | 
			
		||||
	{
 | 
			
		||||
		return HandleError_Access;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Get a new Handle ID */
 | 
			
		||||
	unsigned int new_index;
 | 
			
		||||
	QHandle *pNewHandle;
 | 
			
		||||
	Handle_t new_handle;
 | 
			
		||||
 | 
			
		||||
	if ((err=MakePrimHandle(pHandle->type, &pNewHandle, &new_index, &new_handle, source)) != HandleError_None)
 | 
			
		||||
	if ((err=MakePrimHandle(pHandle->type, &pNewHandle, &new_index, &new_handle, newOwner)) != HandleError_None)
 | 
			
		||||
	{
 | 
			
		||||
		return err;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	pNewHandle->clone = handle;
 | 
			
		||||
	pNewHandle->clone = index;
 | 
			
		||||
	pHandle->refcount++;
 | 
			
		||||
 | 
			
		||||
	if (out_newhandle)
 | 
			
		||||
	{
 | 
			
		||||
		*out_newhandle = new_handle;
 | 
			
		||||
	}
 | 
			
		||||
	*newhandle = new_handle;
 | 
			
		||||
 | 
			
		||||
	return HandleError_None;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
HandleError HandleSystem::FreeHandle(Handle_t handle, IdentityToken_t *pOwner, IdentityToken_t *ident)
 | 
			
		||||
HandleError HandleSystem::FreeHandle(Handle_t handle, const HandleSecurity *pSecurity)
 | 
			
		||||
{
 | 
			
		||||
	unsigned int index;
 | 
			
		||||
	QHandle *pHandle;
 | 
			
		||||
	HandleError err;
 | 
			
		||||
	IdentityToken_t *ident = pSecurity ? pSecurity->pIdentity : NULL;
 | 
			
		||||
 | 
			
		||||
	if ((err=GetHandle(handle, ident, &pHandle, &index, HandleAccess_IdentDelete)) != HandleError_None)
 | 
			
		||||
	if ((err=GetHandle(handle, ident, &pHandle, &index)) != HandleError_None)
 | 
			
		||||
	{
 | 
			
		||||
		return err;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	QHandleType *pType = &m_Types[pHandle->type];
 | 
			
		||||
 | 
			
		||||
	if (pType->sec.access[HandleAccess_OwnerDelete] == false
 | 
			
		||||
		&& pHandle->owner
 | 
			
		||||
		&& pHandle->owner != pOwner)
 | 
			
		||||
	if (!CheckAccess(pHandle, HandleAccess_Delete, pSecurity))
 | 
			
		||||
	{
 | 
			
		||||
		return HandleError_Access;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	QHandleType *pType = &m_Types[pHandle->type];
 | 
			
		||||
 | 
			
		||||
	bool dofree = false;
 | 
			
		||||
	if (pHandle->clone)
 | 
			
		||||
	{
 | 
			
		||||
@ -441,9 +521,10 @@ HandleError HandleSystem::FreeHandle(Handle_t handle, IdentityToken_t *pOwner, I
 | 
			
		||||
		QHandle *pMaster;
 | 
			
		||||
		unsigned int master;
 | 
			
		||||
 | 
			
		||||
		/* This call should not return an error, it'd be a corruption sign */
 | 
			
		||||
		err = GetHandle(pHandle->clone, ident, &pMaster, &master, HandleAccess_IdentDelete, true);
 | 
			
		||||
		assert(err == HandleError_None);
 | 
			
		||||
		/* Note that if we ever have per-handle security, we would need to re-check
 | 
			
		||||
		 * the access on this Handle. */
 | 
			
		||||
		master = pHandle->clone;
 | 
			
		||||
		pMaster = &m_Handles[master];
 | 
			
		||||
 | 
			
		||||
		/* Release the clone now */
 | 
			
		||||
		ReleasePrimHandle(index);
 | 
			
		||||
@ -471,20 +552,23 @@ HandleError HandleSystem::FreeHandle(Handle_t handle, IdentityToken_t *pOwner, I
 | 
			
		||||
	return HandleError_None;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
HandleError HandleSystem::ReadHandle(Handle_t handle, 
 | 
			
		||||
									 HandleType_t type, 
 | 
			
		||||
									 IdentityToken_t *ident, 
 | 
			
		||||
									 void **object)
 | 
			
		||||
HandleError HandleSystem::ReadHandle(Handle_t handle, HandleType_t type, const HandleSecurity *pSecurity, void **object)
 | 
			
		||||
{
 | 
			
		||||
	unsigned int index;
 | 
			
		||||
	QHandle *pHandle;
 | 
			
		||||
	HandleError err;
 | 
			
		||||
	IdentityToken_t *ident = pSecurity ? pSecurity->pIdentity : NULL;
 | 
			
		||||
 | 
			
		||||
	if ((err=GetHandle(handle, ident, &pHandle, &index, HandleAccess_Read)) != HandleError_None)
 | 
			
		||||
	if ((err=GetHandle(handle, ident, &pHandle, &index)) != HandleError_None)
 | 
			
		||||
	{
 | 
			
		||||
		return err;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (!CheckAccess(pHandle, HandleAccess_Read, pSecurity))
 | 
			
		||||
	{
 | 
			
		||||
		return HandleError_Access;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* Check the type inheritance */
 | 
			
		||||
	if (pHandle->type & HANDLESYS_SUBTYPE_MASK)
 | 
			
		||||
	{
 | 
			
		||||
@ -505,8 +589,7 @@ HandleError HandleSystem::ReadHandle(Handle_t handle,
 | 
			
		||||
		/* if we're a clone, the rules change - object is ONLY in our reference */
 | 
			
		||||
		if (pHandle->clone)
 | 
			
		||||
		{
 | 
			
		||||
			/* :TODO: optimize this */
 | 
			
		||||
			return ReadHandle(pHandle->clone, pHandle->type, ident, object);
 | 
			
		||||
			pHandle = &m_Handles[pHandle->clone];
 | 
			
		||||
		}
 | 
			
		||||
		*object = pHandle->object;
 | 
			
		||||
	}
 | 
			
		||||
@ -579,7 +662,8 @@ bool HandleSystem::RemoveType(HandleType_t type, IdentityToken_t *ident)
 | 
			
		||||
 | 
			
		||||
	QHandleType *pType = &m_Types[type];
 | 
			
		||||
 | 
			
		||||
	if (pType->sec.owner && pType->sec.owner != ident)
 | 
			
		||||
	if (pType->typeSec.ident
 | 
			
		||||
		&& pType->typeSec.ident != ident)
 | 
			
		||||
	{
 | 
			
		||||
		return false;
 | 
			
		||||
	}
 | 
			
		||||
@ -598,7 +682,7 @@ bool HandleSystem::RemoveType(HandleType_t type, IdentityToken_t *ident)
 | 
			
		||||
			childType = &m_Types[type + i];
 | 
			
		||||
			if (childType->dispatch)
 | 
			
		||||
			{
 | 
			
		||||
				RemoveType(type + i, childType->sec.owner);
 | 
			
		||||
				RemoveType(type + i, childType->typeSec.ident);
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		/* Link us into the free chain */
 | 
			
		||||
@ -658,10 +742,38 @@ void HandleSystem::MarkHandleAsIdentity(Handle_t handle)
 | 
			
		||||
	QHandle *pHandle;
 | 
			
		||||
	unsigned int index;
 | 
			
		||||
 | 
			
		||||
	if (GetHandle(handle, g_ShareSys.GetIdentRoot(), &pHandle, &index, HandleAccess_Read) != HandleError_None)
 | 
			
		||||
	if (GetHandle(handle, g_ShareSys.GetIdentRoot(), &pHandle, &index) != HandleError_None)
 | 
			
		||||
	{
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	pHandle->set = HandleSet_Identity;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool HandleSystem::InitAccessDefaults(TypeAccess *pTypeAccess, HandleAccess *pHandleAccess)
 | 
			
		||||
{
 | 
			
		||||
	if (pTypeAccess)
 | 
			
		||||
	{
 | 
			
		||||
		if (pTypeAccess->hsVersion > SMINTERFACE_HANDLESYSTEM_VERSION)
 | 
			
		||||
		{
 | 
			
		||||
			return false;
 | 
			
		||||
		}
 | 
			
		||||
		pTypeAccess->access[HTypeAccess_Create] = false;
 | 
			
		||||
		pTypeAccess->access[HTypeAccess_Inherit] = false;
 | 
			
		||||
		pTypeAccess->ident = NULL;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (pHandleAccess)
 | 
			
		||||
	{
 | 
			
		||||
		if (pHandleAccess->hsVersion > SMINTERFACE_HANDLESYSTEM_VERSION)
 | 
			
		||||
		{
 | 
			
		||||
			return false;
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		pHandleAccess->access[HandleAccess_Clone] = 0;
 | 
			
		||||
		pHandleAccess->access[HandleAccess_Delete] = HANDLE_RESTRICT_OWNER;
 | 
			
		||||
		pHandleAccess->access[HandleAccess_Read] = HANDLE_RESTRICT_IDENTITY;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -48,7 +48,7 @@ struct QHandle
 | 
			
		||||
	IdentityToken_t *owner;		/* Identity of object which owns this */
 | 
			
		||||
	unsigned int serial;		/* Serial no. for sanity checking */
 | 
			
		||||
	unsigned int refcount;		/* Reference count for safe destruction */
 | 
			
		||||
	Handle_t clone;				/* If non-zero, this is our cloned parent */
 | 
			
		||||
	unsigned int clone;			/* If non-zero, this is our cloned parent index */
 | 
			
		||||
	HandleSet set;				/* Information about the handle's state */
 | 
			
		||||
	/* The following variables are unrelated to the Handle array, and used 
 | 
			
		||||
	 * as an inlined chain of information */
 | 
			
		||||
@ -64,7 +64,8 @@ struct QHandleType
 | 
			
		||||
	IHandleTypeDispatch *dispatch;
 | 
			
		||||
	unsigned int freeID;
 | 
			
		||||
	unsigned int children;
 | 
			
		||||
	HandleSecurity sec;
 | 
			
		||||
	TypeAccess typeSec;
 | 
			
		||||
	HandleAccess hndlSec;
 | 
			
		||||
	unsigned int opened;
 | 
			
		||||
	int nameIdx;
 | 
			
		||||
};
 | 
			
		||||
@ -78,23 +79,38 @@ public:
 | 
			
		||||
	HandleSystem();
 | 
			
		||||
	~HandleSystem();
 | 
			
		||||
public: //IHandleSystem
 | 
			
		||||
	HandleType_t CreateType(const char *name, IHandleTypeDispatch *dispatch);
 | 
			
		||||
	HandleType_t CreateTypeEx(const char *name,	
 | 
			
		||||
							  IHandleTypeDispatch *dispatch, 
 | 
			
		||||
							  HandleType_t parent, 
 | 
			
		||||
							  const HandleSecurity *security,
 | 
			
		||||
							  IdentityToken_t *ident);
 | 
			
		||||
	HandleType_t CreateChildType(const char *name, HandleType_t parent, IHandleTypeDispatch *dispatch);
 | 
			
		||||
 | 
			
		||||
	HandleType_t CreateType(const char *name,
 | 
			
		||||
		IHandleTypeDispatch *dispatch,
 | 
			
		||||
		HandleType_t parent,
 | 
			
		||||
		const TypeAccess *typeAccess,
 | 
			
		||||
		const HandleAccess *hndlAccess,
 | 
			
		||||
		IdentityToken_t *ident,
 | 
			
		||||
		HandleError *err);
 | 
			
		||||
 | 
			
		||||
	bool RemoveType(HandleType_t type, IdentityToken_t *ident);
 | 
			
		||||
 | 
			
		||||
	bool FindHandleType(const char *name, HandleType_t *type);
 | 
			
		||||
 | 
			
		||||
	Handle_t CreateHandle(HandleType_t type, 
 | 
			
		||||
							void *object, 
 | 
			
		||||
							IdentityToken_t *source, 
 | 
			
		||||
							IdentityToken_t *ident);
 | 
			
		||||
	Handle_t CreateScriptHandle(HandleType_t type, void *object, IPluginContext *pContext, IdentityToken_t *ident);
 | 
			
		||||
	HandleError FreeHandle(Handle_t handle, IdentityToken_t *owner, IdentityToken_t *ident);
 | 
			
		||||
	HandleError CloneHandle(Handle_t handle, Handle_t *newhandle, IdentityToken_t *source, IdentityToken_t *ident);
 | 
			
		||||
	HandleError ReadHandle(Handle_t handle, HandleType_t type, IdentityToken_t *ident, void **object);
 | 
			
		||||
		void *object,
 | 
			
		||||
		IdentityToken_t *owner,
 | 
			
		||||
		IdentityToken_t *ident,
 | 
			
		||||
		HandleError *err);
 | 
			
		||||
	HandleError FreeHandle(Handle_t handle, const HandleSecurity *pSecurity);
 | 
			
		||||
 | 
			
		||||
	HandleError CloneHandle(Handle_t handle, 
 | 
			
		||||
		Handle_t *newhandle, 
 | 
			
		||||
		IdentityToken_t *newOwner,
 | 
			
		||||
		const HandleSecurity *pSecurity);
 | 
			
		||||
 | 
			
		||||
	HandleError ReadHandle(Handle_t handle, 
 | 
			
		||||
		HandleType_t type, 
 | 
			
		||||
		const HandleSecurity *pSecurity,
 | 
			
		||||
		void **object);
 | 
			
		||||
 | 
			
		||||
	bool InitAccessDefaults(TypeAccess *pTypeAccess, HandleAccess *pHandleAccess);
 | 
			
		||||
 | 
			
		||||
	bool TypeCheck(HandleType_t intype, HandleType_t outtype);
 | 
			
		||||
protected:
 | 
			
		||||
	/**
 | 
			
		||||
@ -104,7 +120,6 @@ protected:
 | 
			
		||||
						  IdentityToken_t *ident, 
 | 
			
		||||
						  QHandle **pHandle, 
 | 
			
		||||
						  unsigned int *index,
 | 
			
		||||
						  HandleAccessRight access,
 | 
			
		||||
						  bool ignoreFree=false);
 | 
			
		||||
 | 
			
		||||
	/**
 | 
			
		||||
@ -133,6 +148,8 @@ protected:
 | 
			
		||||
	 * This prevents it from being tampered with by outside stuff
 | 
			
		||||
	 */
 | 
			
		||||
	void MarkHandleAsIdentity(Handle_t handle);
 | 
			
		||||
 | 
			
		||||
	bool CheckAccess(QHandle *pHandle, HandleAccessRight right, const HandleSecurity *pSecurity);
 | 
			
		||||
private:
 | 
			
		||||
	QHandle *m_Handles;
 | 
			
		||||
	QHandleType *m_Types;
 | 
			
		||||
 | 
			
		||||
@ -32,7 +32,7 @@ CPlugin::~CPlugin()
 | 
			
		||||
{
 | 
			
		||||
	if (m_ctx.base)
 | 
			
		||||
	{
 | 
			
		||||
		g_pSourcePawn->FreeBaseContext(m_ctx.base);
 | 
			
		||||
		delete m_ctx.base;
 | 
			
		||||
		m_ctx.base = NULL;
 | 
			
		||||
	}
 | 
			
		||||
	if (m_ctx.ctx)
 | 
			
		||||
@ -74,7 +74,11 @@ CPlugin::~CPlugin()
 | 
			
		||||
 | 
			
		||||
	if (m_handle)
 | 
			
		||||
	{
 | 
			
		||||
		g_HandleSys.FreeHandle(m_handle, g_PluginSys.GetIdentity(), g_PluginSys.GetIdentity());
 | 
			
		||||
		HandleSecurity sec;
 | 
			
		||||
		sec.pOwner = g_PluginSys.GetIdentity();
 | 
			
		||||
		sec.pIdentity = sec.pOwner;
 | 
			
		||||
 | 
			
		||||
		g_HandleSys.FreeHandle(m_handle, &sec);
 | 
			
		||||
		g_ShareSys.DestroyIdentity(m_ident);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
@ -84,7 +88,8 @@ void CPlugin::InitIdentity()
 | 
			
		||||
	if (!m_handle)
 | 
			
		||||
	{
 | 
			
		||||
		m_ident = g_ShareSys.CreateIdentity(g_PluginIdent);
 | 
			
		||||
		m_handle = g_HandleSys.CreateHandle(g_PluginType, this, g_PluginSys.GetIdentity(), g_PluginSys.GetIdentity());
 | 
			
		||||
		m_handle = g_HandleSys.CreateHandle(g_PluginType, this, g_PluginSys.GetIdentity(), g_PluginSys.GetIdentity(), NULL);
 | 
			
		||||
		m_ctx.base->SetIdentity(m_ident);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -188,7 +193,7 @@ bool CPlugin::FinishMyCompile(char *error, size_t maxlength)
 | 
			
		||||
		return false;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	m_ctx.base = g_pSourcePawn->CreateBaseContext(m_ctx.ctx);
 | 
			
		||||
	m_ctx.base = new BaseContext(m_ctx.ctx);
 | 
			
		||||
	m_ctx.ctx->user[SM_CONTEXTVAR_MYSELF] = (void *)this;
 | 
			
		||||
 | 
			
		||||
	m_funcsnum = m_ctx.vm->FunctionCount(m_ctx.ctx);
 | 
			
		||||
@ -1113,15 +1118,13 @@ void CPluginManager::OnSourceModAllInitialized()
 | 
			
		||||
{
 | 
			
		||||
	m_MyIdent = g_ShareSys.CreateCoreIdentity();
 | 
			
		||||
 | 
			
		||||
	HandleSecurity sec;
 | 
			
		||||
	HandleAccess sec;
 | 
			
		||||
	g_HandleSys.InitAccessDefaults(NULL, &sec);
 | 
			
		||||
 | 
			
		||||
	sec.owner = m_MyIdent;	/* :TODO: implement ShareSys */
 | 
			
		||||
	sec.access[HandleAccess_Create] = false;
 | 
			
		||||
	sec.access[HandleAccess_IdentDelete] = false;
 | 
			
		||||
	sec.access[HandleAccess_Inherit] = false;
 | 
			
		||||
	sec.access[HandleAccess_Clone] = false;
 | 
			
		||||
	
 | 
			
		||||
	g_PluginType = g_HandleSys.CreateTypeEx("IPlugin", this, 0, &sec, NULL);
 | 
			
		||||
	sec.access[HandleAccess_Delete] = HANDLE_RESTRICT_IDENTITY;
 | 
			
		||||
	sec.access[HandleAccess_Clone] = HANDLE_RESTRICT_IDENTITY;
 | 
			
		||||
 | 
			
		||||
	g_PluginType = g_HandleSys.CreateType("Plugin", this, 0, NULL, &sec, m_MyIdent, NULL);
 | 
			
		||||
	g_PluginIdent = g_ShareSys.CreateIdentType("PLUGIN");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -1147,7 +1150,12 @@ IPlugin *CPluginManager::PluginFromHandle(Handle_t handle, HandleError *err)
 | 
			
		||||
	IPlugin *pPlugin;
 | 
			
		||||
	HandleError _err;
 | 
			
		||||
 | 
			
		||||
	if ((_err=g_HandleSys.ReadHandle(handle, g_PluginType, m_MyIdent, (void **)&pPlugin)) != HandleError_None)
 | 
			
		||||
	HandleSecurity sec;
 | 
			
		||||
 | 
			
		||||
	sec.pOwner = NULL;
 | 
			
		||||
	sec.pIdentity = m_MyIdent;
 | 
			
		||||
 | 
			
		||||
	if ((_err=g_HandleSys.ReadHandle(handle, g_PluginType, &sec, (void **)&pPlugin)) != HandleError_None)
 | 
			
		||||
	{
 | 
			
		||||
		pPlugin = NULL;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
@ -7,6 +7,7 @@
 | 
			
		||||
#include <sh_list.h>
 | 
			
		||||
#include <sh_stack.h>
 | 
			
		||||
#include "sm_globals.h"
 | 
			
		||||
#include "vm/sp_vm_basecontext.h"
 | 
			
		||||
#include "CFunction.h"
 | 
			
		||||
#include "PluginInfoDatabase.h"
 | 
			
		||||
#include "sm_trie.h"
 | 
			
		||||
@ -67,7 +68,7 @@ struct ContextPair
 | 
			
		||||
	ContextPair() : base(NULL), ctx(NULL), co(NULL)
 | 
			
		||||
	{
 | 
			
		||||
	};
 | 
			
		||||
	IPluginContext *base;
 | 
			
		||||
	BaseContext *base;
 | 
			
		||||
	sp_context_t *ctx;
 | 
			
		||||
	ICompilation *co;
 | 
			
		||||
	IVirtualMachine *vm;
 | 
			
		||||
 | 
			
		||||
@ -23,17 +23,16 @@ IdentityToken_t *ShareSystem::CreateCoreIdentity()
 | 
			
		||||
 | 
			
		||||
void ShareSystem::OnSourceModStartup(bool late)
 | 
			
		||||
{
 | 
			
		||||
	HandleSecurity sec;
 | 
			
		||||
	TypeAccess sec;
 | 
			
		||||
 | 
			
		||||
	sec.owner = GetIdentRoot();
 | 
			
		||||
	sec.access[HandleAccess_Inherit] = false;
 | 
			
		||||
	sec.access[HandleAccess_IdentDelete] = false;
 | 
			
		||||
	
 | 
			
		||||
	m_TypeRoot = g_HandleSys.CreateTypeEx("Identity", this, 0, &sec, NULL);
 | 
			
		||||
	m_IfaceType = g_HandleSys.CreateTypeEx("Interface", this, 0, &sec, NULL);
 | 
			
		||||
	g_HandleSys.InitAccessDefaults(&sec, NULL);
 | 
			
		||||
	sec.ident = GetIdentRoot();
 | 
			
		||||
 | 
			
		||||
	m_TypeRoot = g_HandleSys.CreateType("Identity", this, 0, &sec, NULL, NULL, NULL);
 | 
			
		||||
	m_IfaceType = g_HandleSys.CreateType("Interface", this, 0, NULL, NULL, GetIdentRoot(), NULL);
 | 
			
		||||
 | 
			
		||||
	/* Initialize our static identity handle */
 | 
			
		||||
	m_IdentRoot.ident = g_HandleSys.CreateHandle(m_TypeRoot, NULL, NULL, NULL);
 | 
			
		||||
	m_IdentRoot.ident = g_HandleSys.CreateHandle(m_TypeRoot, NULL, NULL, GetIdentRoot(), NULL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ShareSystem::OnSourceModShutdown()
 | 
			
		||||
@ -69,7 +68,7 @@ IdentityType_t ShareSystem::CreateIdentType(const char *name)
 | 
			
		||||
		return 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	return g_HandleSys.CreateTypeEx(name, this, m_TypeRoot, NULL, GetIdentRoot());
 | 
			
		||||
	return g_HandleSys.CreateType(name, this, m_TypeRoot, NULL, NULL, GetIdentRoot(), NULL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void ShareSystem::OnHandleDestroy(HandleType_t type, void *object)
 | 
			
		||||
@ -86,7 +85,7 @@ IdentityToken_t *ShareSystem::CreateIdentity(IdentityType_t type)
 | 
			
		||||
 | 
			
		||||
	/* :TODO: Cache? */
 | 
			
		||||
	IdentityToken_t *pToken = new IdentityToken_t;
 | 
			
		||||
	pToken->ident = g_HandleSys.CreateHandle(type, NULL, NULL, GetIdentRoot());
 | 
			
		||||
	pToken->ident = g_HandleSys.CreateHandle(type, NULL, GetIdentRoot(), GetIdentRoot(), NULL);
 | 
			
		||||
 | 
			
		||||
	return pToken;
 | 
			
		||||
}
 | 
			
		||||
@ -106,7 +105,7 @@ bool ShareSystem::AddInterface(SMInterface *iface, IdentityToken_t *token)
 | 
			
		||||
	if (token)
 | 
			
		||||
	{
 | 
			
		||||
		/* If we're an external object, we have to do this */
 | 
			
		||||
		info.handle = g_HandleSys.CreateHandle(m_IfaceType, iface, token, GetIdentRoot());
 | 
			
		||||
		info.handle = g_HandleSys.CreateHandle(m_IfaceType, iface, token, GetIdentRoot(), NULL);
 | 
			
		||||
	} else {
 | 
			
		||||
		info.handle = 0;
 | 
			
		||||
	}
 | 
			
		||||
@ -125,7 +124,12 @@ bool ShareSystem::RequestInterface(const char *iface_name,
 | 
			
		||||
	 * HORRIBLE PERSON passed in a token that we don't recognize....
 | 
			
		||||
	 * <b>Punish them.</b>
 | 
			
		||||
	 */
 | 
			
		||||
	if (!g_HandleSys.ReadHandle(token->ident, m_TypeRoot, GetIdentRoot(), NULL))
 | 
			
		||||
	HandleSecurity sec;
 | 
			
		||||
 | 
			
		||||
	sec.pIdentity = GetIdentRoot();
 | 
			
		||||
	sec.pOwner = NULL;
 | 
			
		||||
 | 
			
		||||
	if (!g_HandleSys.ReadHandle(token->ident, m_TypeRoot, &sec, NULL))
 | 
			
		||||
	{
 | 
			
		||||
		return false;
 | 
			
		||||
	}
 | 
			
		||||
@ -162,7 +166,7 @@ bool ShareSystem::RequestInterface(const char *iface_name,
 | 
			
		||||
	if (iface_owner)
 | 
			
		||||
	{
 | 
			
		||||
		Handle_t newhandle;
 | 
			
		||||
		if (g_HandleSys.CloneHandle(iface_handle, &newhandle, token, GetIdentRoot())
 | 
			
		||||
		if (g_HandleSys.CloneHandle(iface_handle, &newhandle, token, &sec)
 | 
			
		||||
			!= HandleError_None)
 | 
			
		||||
		{
 | 
			
		||||
			return false;
 | 
			
		||||
@ -184,7 +188,12 @@ void ShareSystem::AddNatives(IdentityToken_t *token, const sp_nativeinfo_t *nati
 | 
			
		||||
 | 
			
		||||
void ShareSystem::DestroyIdentity(IdentityToken_t *identity)
 | 
			
		||||
{
 | 
			
		||||
	g_HandleSys.FreeHandle(identity->ident, NULL, GetIdentRoot());
 | 
			
		||||
	HandleSecurity sec;
 | 
			
		||||
 | 
			
		||||
	sec.pOwner = GetIdentRoot();
 | 
			
		||||
	sec.pIdentity = GetIdentRoot();
 | 
			
		||||
 | 
			
		||||
	g_HandleSys.FreeHandle(identity->ident, &sec);
 | 
			
		||||
	delete identity;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -252,11 +252,9 @@ int BaseContext::HeapRelease(cell_t local_addr)
 | 
			
		||||
 | 
			
		||||
int BaseContext::FindNativeByName(const char *name, uint32_t *index)
 | 
			
		||||
{
 | 
			
		||||
	int diff, high, low;
 | 
			
		||||
	uint32_t mid;
 | 
			
		||||
	int high;
 | 
			
		||||
 | 
			
		||||
	high = ctx->plugin->info.natives_num - 1;
 | 
			
		||||
	low = 0;
 | 
			
		||||
 | 
			
		||||
#if 0
 | 
			
		||||
	while (low <= high)
 | 
			
		||||
@ -786,3 +784,15 @@ int BaseContext::LookupLine(ucell_t addr, uint32_t *line)
 | 
			
		||||
 | 
			
		||||
	return SP_ERROR_NONE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#if defined SOURCEMOD_BUILD
 | 
			
		||||
SourceMod::IdentityToken_t *BaseContext::GetIdentity()
 | 
			
		||||
{
 | 
			
		||||
	return m_pToken;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void BaseContext::SetIdentity(SourceMod::IdentityToken_t *token)
 | 
			
		||||
{
 | 
			
		||||
	m_pToken = token;
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
@ -44,6 +44,10 @@ namespace SourcePawn
 | 
			
		||||
		virtual int Execute(funcid_t funcid, cell_t *result);
 | 
			
		||||
		virtual void ThrowNativeErrorEx(int error, const char *msg, ...);
 | 
			
		||||
		virtual cell_t ThrowNativeError(const char *msg, ...);
 | 
			
		||||
#if defined SOURCEMOD_BUILD
 | 
			
		||||
		virtual SourceMod::IdentityToken_t *GetIdentity();
 | 
			
		||||
		void SetIdentity(SourceMod::IdentityToken_t *token);
 | 
			
		||||
#endif
 | 
			
		||||
	public: //IPluginDebugInfo
 | 
			
		||||
		virtual int LookupFile(ucell_t addr, const char **filename);
 | 
			
		||||
		virtual int LookupFunction(ucell_t addr, const char **name);
 | 
			
		||||
@ -52,6 +56,9 @@ namespace SourcePawn
 | 
			
		||||
		void SetErrorMessage(const char *msg, va_list ap);
 | 
			
		||||
	private:
 | 
			
		||||
		sp_context_t *ctx;
 | 
			
		||||
#if defined SOURCEMOD_BUILD
 | 
			
		||||
		SourceMod::IdentityToken_t *m_pToken;
 | 
			
		||||
#endif
 | 
			
		||||
		char m_MsgCache[1024];
 | 
			
		||||
		bool m_CustomMsg;
 | 
			
		||||
		bool m_InExec;
 | 
			
		||||
 | 
			
		||||
@ -12,7 +12,7 @@ public Plugin:myinfo =
 | 
			
		||||
 | 
			
		||||
native PrintStuff(const String:buffer[]);
 | 
			
		||||
 | 
			
		||||
public bool:AskPluginLoad(Handle:myself, bool:late, String:error[], err_max)
 | 
			
		||||
DoItAll()
 | 
			
		||||
{
 | 
			
		||||
	new String:buffer[PLATFORM_MAX_PATH];
 | 
			
		||||
	new FileType:type;
 | 
			
		||||
@ -24,7 +24,14 @@ public bool:AskPluginLoad(Handle:myself, bool:late, String:error[], err_max)
 | 
			
		||||
		Format(stuff, sizeof(stuff), "Type: %d Dir: %s", _:type, buffer)
 | 
			
		||||
		PrintStuff(stuff);
 | 
			
		||||
	}
 | 
			
		||||
	new Handle:copy = CloneHandle(dir);
 | 
			
		||||
	CloseHandle(copy);
 | 
			
		||||
	CloseHandle(dir);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
public bool:AskPluginLoad(Handle:myself, bool:late, String:error[], err_max)
 | 
			
		||||
{
 | 
			
		||||
	DoItAll();
 | 
			
		||||
	
 | 
			
		||||
	return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -6,6 +6,13 @@
 | 
			
		||||
 | 
			
		||||
#define SOURCEPAWN_VM_API_VERSION		1
 | 
			
		||||
 | 
			
		||||
#if defined SOURCEMOD_BUILD
 | 
			
		||||
namespace SourceMod
 | 
			
		||||
{
 | 
			
		||||
	struct IdentityToken_t;
 | 
			
		||||
};
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
namespace SourcePawn
 | 
			
		||||
{
 | 
			
		||||
	class IVirtualMachine;
 | 
			
		||||
@ -331,6 +338,16 @@ namespace SourcePawn
 | 
			
		||||
		 * @return			0 for convenience.
 | 
			
		||||
		 */
 | 
			
		||||
		virtual cell_t ThrowNativeError(const char *msg, ...) =0;
 | 
			
		||||
 | 
			
		||||
#if defined SOURCEMOD_BUILD
 | 
			
		||||
		/**
 | 
			
		||||
		 * @brief Returns the identity token for this context.
 | 
			
		||||
		 * Note: This is a helper function for native calls and the Handle System.
 | 
			
		||||
		 *
 | 
			
		||||
		 * @return			Identity token.
 | 
			
		||||
		 */
 | 
			
		||||
		virtual SourceMod::IdentityToken_t *GetIdentity() =0;
 | 
			
		||||
#endif
 | 
			
		||||
	};
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -448,21 +465,6 @@ namespace SourcePawn
 | 
			
		||||
		 */
 | 
			
		||||
		virtual int FreeFromMemory(sp_plugin_t *plugin) =0;
 | 
			
		||||
 | 
			
		||||
		/**
 | 
			
		||||
		 * @brief Creates a new IContext from a context handle.
 | 
			
		||||
		 *
 | 
			
		||||
		 * @param ctx		Context to use as a basis for the IPluginContext.
 | 
			
		||||
		 * @return			New IPluginContext handle.
 | 
			
		||||
		 */
 | 
			
		||||
		virtual IPluginContext *CreateBaseContext(sp_context_t *ctx) =0;
 | 
			
		||||
 | 
			
		||||
		/** 
 | 
			
		||||
		 * @brief Frees a base context.  Does not free the sp_context_t it holds.
 | 
			
		||||
		 *
 | 
			
		||||
		 * @param ctx		Context pointer to free.
 | 
			
		||||
		 */
 | 
			
		||||
		virtual void FreeBaseContext(IPluginContext *ctx) =0;
 | 
			
		||||
 | 
			
		||||
		/**
 | 
			
		||||
		 * @brief Allocates large blocks of temporary memory.
 | 
			
		||||
		 * 
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user