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