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:
+195
-83
@@ -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;
|
||||
}
|
||||
|
||||
+34
-17
@@ -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;
|
||||
|
||||
+21
-13
@@ -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
-14
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user