initial import of sharesystem (unfinished)
final revision of handle system (I hope!) initial import of plugin handles --HG-- extra : convert_revision : svn%3A39bc706e-5318-0410-9160-8a85361fbb7c/trunk%40234
This commit is contained in:
+161
-24
@@ -1,9 +1,22 @@
|
||||
#include "HandleSys.h"
|
||||
#include "ShareSys.h"
|
||||
#include "PluginSys.h"
|
||||
#include <assert.h>
|
||||
|
||||
HandleSystem g_HandleSys;
|
||||
|
||||
QHandle *ignore_handle;
|
||||
|
||||
inline HandleType_t TypeParent(HandleType_t type)
|
||||
{
|
||||
return (type & ~HANDLESYS_SUBTYPE_MASK);
|
||||
}
|
||||
|
||||
inline HandleError IdentityHandle(IdentityToken_t *token, unsigned int *index)
|
||||
{
|
||||
return g_HandleSys.GetHandle(token->ident, g_ShareSys.GetIdentRoot(), &ignore_handle, index, HandleAccess_Read);
|
||||
}
|
||||
|
||||
HandleSystem::HandleSystem()
|
||||
{
|
||||
m_Handles = new QHandle[HANDLESYS_MAX_HANDLES + 1];
|
||||
@@ -28,18 +41,19 @@ HandleSystem::~HandleSystem()
|
||||
|
||||
HandleType_t HandleSystem::CreateType(const char *name, IHandleTypeDispatch *dispatch)
|
||||
{
|
||||
return CreateTypeEx(name, dispatch, 0, NULL);
|
||||
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);
|
||||
return CreateTypeEx(name, dispatch, parent, NULL, NULL);
|
||||
}
|
||||
|
||||
HandleType_t HandleSystem::CreateTypeEx(const char *name,
|
||||
IHandleTypeDispatch *dispatch,
|
||||
HandleType_t parent,
|
||||
const HandleSecurity *security)
|
||||
const HandleSecurity *security,
|
||||
IdentityToken_t *ident)
|
||||
{
|
||||
if (!dispatch)
|
||||
{
|
||||
@@ -56,8 +70,9 @@ HandleType_t HandleSystem::CreateTypeEx(const char *name,
|
||||
return 0;
|
||||
}
|
||||
if (parent >= HANDLESYS_TYPEARRAY_SIZE
|
||||
|| m_Types[parent].dispatch != NULL
|
||||
|| m_Types[parent].sec.access[HandleAccess_Inherit] == false)
|
||||
|| m_Types[parent].dispatch == NULL
|
||||
|| (m_Types[parent].sec.access[HandleAccess_Inherit] == false
|
||||
&& m_Types[parent].sec.owner != ident))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
@@ -163,8 +178,16 @@ bool HandleSystem::FindHandleType(const char *name, HandleType_t *type)
|
||||
HandleError HandleSystem::MakePrimHandle(HandleType_t type,
|
||||
QHandle **in_pHandle,
|
||||
unsigned int *in_index,
|
||||
Handle_t *in_handle)
|
||||
Handle_t *in_handle,
|
||||
IdentityToken_t *owner)
|
||||
{
|
||||
unsigned int owner_index = 0;
|
||||
|
||||
if (owner && (IdentityHandle(owner, &owner_index) != HandleError_None))
|
||||
{
|
||||
return HandleError_Identity;
|
||||
}
|
||||
|
||||
unsigned int handle;
|
||||
if (m_FreeHandles == 0)
|
||||
{
|
||||
@@ -187,10 +210,12 @@ HandleError HandleSystem::MakePrimHandle(HandleType_t type,
|
||||
}
|
||||
|
||||
/* Set essential information */
|
||||
pHandle->set = true;
|
||||
pHandle->set = HandleSet_Used;;
|
||||
pHandle->refcount = 1;
|
||||
pHandle->type = type;
|
||||
pHandle->serial = m_HSerial;
|
||||
pHandle->owner = owner;
|
||||
pHandle->ch_next = 0;
|
||||
|
||||
/* Create the hash value */
|
||||
Handle_t hash = pHandle->serial;
|
||||
@@ -205,10 +230,44 @@ HandleError HandleSystem::MakePrimHandle(HandleType_t type,
|
||||
*in_index = handle;
|
||||
*in_handle = hash;
|
||||
|
||||
/* Decode the identity token */
|
||||
if (owner)
|
||||
{
|
||||
QHandle *pIdentity = &m_Handles[owner_index];
|
||||
if (pIdentity->ch_prev == 0)
|
||||
{
|
||||
pIdentity->ch_prev = handle;
|
||||
pIdentity->ch_next = handle;
|
||||
pHandle->ch_prev = 0;
|
||||
} else {
|
||||
/* Link previous node to us (forward) */
|
||||
m_Handles[pIdentity->ch_next].ch_next = handle;
|
||||
/* Link us to previous node (backwards) */
|
||||
pHandle->ch_prev = pIdentity->ch_next;
|
||||
/* Set new tail */
|
||||
pIdentity->ch_next = handle;
|
||||
}
|
||||
pIdentity->refcount++;
|
||||
} else {
|
||||
pHandle->ch_prev = 0;
|
||||
}
|
||||
|
||||
return HandleError_None;
|
||||
}
|
||||
|
||||
Handle_t HandleSystem::CreateHandle(HandleType_t type, void *object, IdentityToken_t source, IdentityToken_t ident)
|
||||
void HandleSystem::SetTypeSecurityOwner(HandleType_t type, IdentityToken_t *pToken)
|
||||
{
|
||||
if (!type
|
||||
|| type >= HANDLESYS_TYPEARRAY_SIZE
|
||||
|| m_Types[type].dispatch == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
m_Types[type].sec.owner = pToken;
|
||||
}
|
||||
|
||||
Handle_t HandleSystem::CreateHandle(HandleType_t type, void *object, IdentityToken_t *source, IdentityToken_t *ident)
|
||||
{
|
||||
if (!type
|
||||
|| type >= HANDLESYS_TYPEARRAY_SIZE
|
||||
@@ -230,12 +289,11 @@ Handle_t HandleSystem::CreateHandle(HandleType_t type, void *object, IdentityTok
|
||||
QHandle *pHandle;
|
||||
HandleError err;
|
||||
|
||||
if ((err=MakePrimHandle(type, &pHandle, &index, &handle)) != HandleError_None)
|
||||
if ((err=MakePrimHandle(type, &pHandle, &index, &handle, source)) != HandleError_None)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
pHandle->source = source;
|
||||
pHandle->object = object;
|
||||
pHandle->clone = 0;
|
||||
|
||||
@@ -245,15 +303,35 @@ Handle_t HandleSystem::CreateHandle(HandleType_t type, void *object, IdentityTok
|
||||
Handle_t HandleSystem::CreateScriptHandle(HandleType_t type,
|
||||
void *object,
|
||||
sp_context_t *ctx,
|
||||
IdentityToken_t ident)
|
||||
IdentityToken_t *ident)
|
||||
{
|
||||
IPlugin *pPlugin = g_PluginSys.FindPluginByContext(ctx);
|
||||
|
||||
return CreateHandle(type, object, pPlugin->GetIdentity(), ident);
|
||||
}
|
||||
|
||||
bool HandleSystem::TypeCheck(HandleType_t intype, HandleType_t outtype)
|
||||
{
|
||||
/* Check the type inheritance */
|
||||
if (intype & HANDLESYS_SUBTYPE_MASK)
|
||||
{
|
||||
if (intype != outtype
|
||||
&& (TypeParent(intype) != TypeParent(outtype)))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
if (intype != outtype)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
HandleError HandleSystem::GetHandle(Handle_t handle,
|
||||
IdentityToken_t ident,
|
||||
IdentityToken_t *ident,
|
||||
QHandle **in_pHandle,
|
||||
unsigned int *in_index,
|
||||
HandleAccessRight access)
|
||||
@@ -277,6 +355,11 @@ HandleError HandleSystem::GetHandle(Handle_t handle,
|
||||
if (!pHandle->set)
|
||||
{
|
||||
return HandleError_Freed;
|
||||
} else if (pHandle->set == HandleSet_Identity
|
||||
&& ident != g_ShareSys.GetIdentRoot())
|
||||
{
|
||||
/* Only IdentityHandle() can read this! */
|
||||
return HandleError_Identity;
|
||||
}
|
||||
if (pHandle->serial != serial)
|
||||
{
|
||||
@@ -289,7 +372,7 @@ 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)
|
||||
HandleError HandleSystem::CloneHandle(Handle_t handle, Handle_t *out_newhandle, IdentityToken_t *source, IdentityToken_t *ident)
|
||||
{
|
||||
HandleError err;
|
||||
QHandle *pHandle;
|
||||
@@ -307,13 +390,12 @@ HandleError HandleSystem::CloneHandle(Handle_t handle, Handle_t *out_newhandle,
|
||||
QHandle *pNewHandle;
|
||||
Handle_t new_handle;
|
||||
|
||||
if ((err=MakePrimHandle(pHandle->type, &pNewHandle, &new_index, &new_handle)) != HandleError_None)
|
||||
if ((err=MakePrimHandle(pHandle->type, &pNewHandle, &new_index, &new_handle, source)) != HandleError_None)
|
||||
{
|
||||
return err;
|
||||
}
|
||||
|
||||
pNewHandle->clone = index;
|
||||
pNewHandle->source = source;
|
||||
|
||||
if (out_newhandle)
|
||||
{
|
||||
@@ -323,7 +405,7 @@ HandleError HandleSystem::CloneHandle(Handle_t handle, Handle_t *out_newhandle,
|
||||
return HandleError_None;
|
||||
}
|
||||
|
||||
HandleError HandleSystem::FreeHandle(Handle_t handle, IdentityToken_t ident)
|
||||
HandleError HandleSystem::FreeHandle(Handle_t handle, IdentityToken_t *ident)
|
||||
{
|
||||
unsigned int index;
|
||||
QHandle *pHandle;
|
||||
@@ -361,14 +443,9 @@ HandleError HandleSystem::FreeHandle(Handle_t handle, IdentityToken_t ident)
|
||||
return HandleError_None;
|
||||
}
|
||||
|
||||
inline HandleType_t TypeParent(HandleType_t type)
|
||||
{
|
||||
return (type & ~HANDLESYS_SUBTYPE_MASK);
|
||||
}
|
||||
|
||||
HandleError HandleSystem::ReadHandle(Handle_t handle,
|
||||
HandleType_t type,
|
||||
IdentityToken_t ident,
|
||||
IdentityToken_t *ident,
|
||||
void **object)
|
||||
{
|
||||
unsigned int index;
|
||||
@@ -412,12 +489,59 @@ void HandleSystem::ReleasePrimHandle(unsigned int index)
|
||||
{
|
||||
QHandle *pHandle = &m_Handles[index];
|
||||
|
||||
pHandle->set = false;
|
||||
pHandle->set = HandleSet_None;
|
||||
m_Types[pHandle->type].opened--;
|
||||
m_Handles[++m_FreeHandles].freeID = index;
|
||||
|
||||
/* Unlink us if necessary */
|
||||
if (pHandle->owner)
|
||||
{
|
||||
unsigned int ident_index;
|
||||
if (IdentityHandle(pHandle->owner, &ident_index) != HandleError_None)
|
||||
{
|
||||
/* Uh-oh! */
|
||||
assert(pHandle->owner == 0);
|
||||
return;
|
||||
}
|
||||
/* Note that since 0 is an invalid handle, if any of these links are 0,
|
||||
* the data can still be set.
|
||||
*/
|
||||
QHandle *pIdentity = &m_Handles[ident_index];
|
||||
|
||||
/* Unlink case: We're the head AND tail node */
|
||||
if (index == pIdentity->ch_prev && index == pIdentity->ch_next)
|
||||
{
|
||||
pIdentity->ch_prev = 0;
|
||||
pIdentity->ch_next = 0;
|
||||
}
|
||||
/* Unlink case: We're the head node */
|
||||
else if (index == pIdentity->ch_prev) {
|
||||
/* Link us to the next in the chain */
|
||||
pIdentity->ch_prev = pHandle->ch_next;
|
||||
/* Patch up the previous link */
|
||||
m_Handles[pHandle->ch_next].ch_prev = 0;
|
||||
}
|
||||
/* Unlink case: We're the tail node */
|
||||
else if (index == pIdentity->ch_next) {
|
||||
/* Link us to the previous in the chain */
|
||||
pIdentity->ch_next = pHandle->ch_prev;
|
||||
/* Patch up the next link */
|
||||
m_Handles[pHandle->ch_prev].ch_next = 0;
|
||||
}
|
||||
/* Unlink case: We're in the middle! */
|
||||
else {
|
||||
/* Patch the forward reference */
|
||||
m_Handles[pHandle->ch_next].ch_prev = pHandle->ch_prev;
|
||||
/* Patch the backward reference */
|
||||
m_Handles[pHandle->ch_prev].ch_next = pHandle->ch_next;
|
||||
}
|
||||
|
||||
/* Lastly, decrease the reference count */
|
||||
pIdentity->refcount--;
|
||||
}
|
||||
}
|
||||
|
||||
bool HandleSystem::RemoveType(HandleType_t type, IdentityToken_t ident)
|
||||
bool HandleSystem::RemoveType(HandleType_t type, IdentityToken_t *ident)
|
||||
{
|
||||
if (type == 0 || type >= HANDLESYS_TYPEARRAY_SIZE)
|
||||
{
|
||||
@@ -499,3 +623,16 @@ bool HandleSystem::RemoveType(HandleType_t type, IdentityToken_t ident)
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void HandleSystem::MarkHandleAsIdentity(Handle_t handle)
|
||||
{
|
||||
QHandle *pHandle;
|
||||
unsigned int index;
|
||||
|
||||
if (GetHandle(handle, g_ShareSys.GetIdentRoot(), &pHandle, &index, HandleAccess_Read) != HandleError_None)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
pHandle->set = HandleSet_Identity;
|
||||
}
|
||||
|
||||
+65
-15
@@ -16,16 +16,46 @@
|
||||
#define HANDLESYS_SERIAL_MASK 0xFFFF0000
|
||||
#define HANDLESYS_HANDLE_MASK 0x0000FFFF
|
||||
|
||||
/**
|
||||
* The QHandle is a nasty structure that compacts the handle system into a big vector.
|
||||
* The members of the vector each encapsulate one Handle, however, they also act as nodes
|
||||
* in an inlined linked list and an inlined vector.
|
||||
*
|
||||
* The first of these lists is the 'freeID' list. Each node from 1 to N (where N
|
||||
* is the number of free nodes) has a 'freeID' that specifies a free Handle ID. This
|
||||
* is a quick hack to get around allocating a second base vector.
|
||||
*
|
||||
* The second vector is the identity linked list. An identity has its own handle, so
|
||||
* these handles are used as sentinel nodes for index linking. They point to the first and last
|
||||
* index into the handle array. Each subsequent Handle who is owned by that indentity is mapped into
|
||||
* that list. This lets owning identities be unloaded in O(n) time.
|
||||
*
|
||||
* Eventually, there may be a third list for type chains.
|
||||
*/
|
||||
|
||||
enum HandleSet
|
||||
{
|
||||
HandleSet_None = 0,
|
||||
HandleSet_Used,
|
||||
HandleSet_Identity
|
||||
};
|
||||
|
||||
struct QHandle
|
||||
{
|
||||
HandleType_t type; /* Handle type */
|
||||
void *object; /* Unmaintained object pointer */
|
||||
unsigned int freeID; /* ID of a free handle in the free handle chain */
|
||||
IdentityToken_t source; /* Identity of object which owns this */
|
||||
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 */
|
||||
bool set; /* Whether or not this handle is set */
|
||||
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 */
|
||||
unsigned int freeID; /* ID of a free handle in the free handle chain */
|
||||
/* Indexes into the handle array for owner membership.
|
||||
* For identity roots, these are treated as the head/tail. */
|
||||
unsigned int ch_prev; /* chained previous handle or HEAD */
|
||||
unsigned int ch_next; /* chained next handle or TAIL */
|
||||
};
|
||||
|
||||
struct QHandleType
|
||||
@@ -41,6 +71,8 @@ struct QHandleType
|
||||
class HandleSystem :
|
||||
public IHandleSys
|
||||
{
|
||||
friend HandleError IdentityHandle(IdentityToken_t *token, unsigned int *index);
|
||||
friend class ShareSystem;
|
||||
public:
|
||||
HandleSystem();
|
||||
~HandleSystem();
|
||||
@@ -49,24 +81,26 @@ public: //IHandleSystem
|
||||
HandleType_t CreateTypeEx(const char *name,
|
||||
IHandleTypeDispatch *dispatch,
|
||||
HandleType_t parent,
|
||||
const HandleSecurity *security);
|
||||
const HandleSecurity *security,
|
||||
IdentityToken_t *ident);
|
||||
HandleType_t CreateChildType(const char *name, HandleType_t parent, IHandleTypeDispatch *dispatch);
|
||||
bool RemoveType(HandleType_t type, IdentityToken_t ident);
|
||||
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, sp_context_t *ctx, IdentityToken_t ident);
|
||||
HandleError FreeHandle(Handle_t handle, 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);
|
||||
private:
|
||||
IdentityToken_t *source,
|
||||
IdentityToken_t *ident);
|
||||
Handle_t CreateScriptHandle(HandleType_t type, void *object, sp_context_t *ctx, IdentityToken_t *ident);
|
||||
HandleError FreeHandle(Handle_t handle, 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);
|
||||
bool TypeCheck(HandleType_t intype, HandleType_t outtype);
|
||||
protected:
|
||||
/**
|
||||
* Decodes a handle with sanity and security checking.
|
||||
*/
|
||||
HandleError GetHandle(Handle_t handle,
|
||||
IdentityToken_t ident,
|
||||
IdentityToken_t *ident,
|
||||
QHandle **pHandle,
|
||||
unsigned int *index,
|
||||
HandleAccessRight access);
|
||||
@@ -75,12 +109,28 @@ private:
|
||||
* Creates a basic handle and sets its reference count to 1.
|
||||
* Does not do any type or security checking.
|
||||
*/
|
||||
HandleError MakePrimHandle(HandleType_t type, QHandle **pHandle, unsigned int *index, HandleType_t *handle);
|
||||
HandleError MakePrimHandle(HandleType_t type,
|
||||
QHandle **pHandle,
|
||||
unsigned int *index,
|
||||
HandleType_t *handle,
|
||||
IdentityToken_t *owner);
|
||||
|
||||
/**
|
||||
* Frees a primitive handle. Does no object freeing, only reference count and bookkeepping.
|
||||
* Frees a primitive handle. Does no object freeing, only reference count, bookkeepping,
|
||||
* and linked list maintenance.
|
||||
*/
|
||||
void ReleasePrimHandle(unsigned int index);
|
||||
|
||||
/**
|
||||
* Sets the security owner of a type
|
||||
*/
|
||||
void SetTypeSecurityOwner(HandleType_t type, IdentityToken_t *pToken);
|
||||
|
||||
/**
|
||||
* Marks a handle as an identity.
|
||||
* This prevents it from being tampered with by outside stuff
|
||||
*/
|
||||
void MarkHandleAsIdentity(Handle_t handle);
|
||||
private:
|
||||
QHandle *m_Handles;
|
||||
QHandleType *m_Types;
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#include <stdio.h>
|
||||
#include "PluginSys.h"
|
||||
#include "ShareSys.h"
|
||||
#include "LibrarySys.h"
|
||||
#include "HandleSys.h"
|
||||
#include "sourcemm_api.h"
|
||||
@@ -8,6 +9,7 @@
|
||||
|
||||
CPluginManager g_PluginSys;
|
||||
HandleType_t g_PluginType = 0;
|
||||
IdentityType_t g_PluginIdent = 0;
|
||||
|
||||
CPlugin::CPlugin(const char *file)
|
||||
{
|
||||
@@ -22,8 +24,8 @@ CPlugin::CPlugin(const char *file)
|
||||
m_pub_funcs = NULL;
|
||||
m_errormsg[256] = '\0';
|
||||
snprintf(m_filename, sizeof(m_filename), "%s", file);
|
||||
/* :TODO: ShareSys token */
|
||||
m_handle = g_HandleSys.CreateHandle(g_PluginType, this, DEFAULT_IDENTITY, 1);
|
||||
m_handle = 0;
|
||||
m_ident = NULL;
|
||||
}
|
||||
|
||||
CPlugin::~CPlugin()
|
||||
@@ -70,7 +72,20 @@ CPlugin::~CPlugin()
|
||||
m_plugin = NULL;
|
||||
}
|
||||
|
||||
g_HandleSys.FreeHandle(m_handle, g_PluginType);
|
||||
if (m_handle)
|
||||
{
|
||||
g_HandleSys.FreeHandle(m_handle, g_PluginSys.GetIdentity());
|
||||
g_ShareSys.DestroyIdentity(m_ident);
|
||||
}
|
||||
}
|
||||
|
||||
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());
|
||||
}
|
||||
}
|
||||
|
||||
CPlugin *CPlugin::CreatePlugin(const char *file, char *error, size_t maxlength)
|
||||
@@ -447,9 +462,9 @@ bool CPlugin::SetPauseState(bool paused)
|
||||
return true;
|
||||
}
|
||||
|
||||
IdentityToken_t CPlugin::GetIdentity()
|
||||
IdentityToken_t *CPlugin::GetIdentity()
|
||||
{
|
||||
return 0;
|
||||
return m_ident;
|
||||
}
|
||||
|
||||
/*******************
|
||||
@@ -499,6 +514,7 @@ CPluginManager::CPluginManager()
|
||||
{
|
||||
m_LoadLookup = sm_trie_create();
|
||||
m_AllPluginsLoaded = false;
|
||||
m_MyIdent = NULL;
|
||||
}
|
||||
|
||||
CPluginManager::~CPluginManager()
|
||||
@@ -661,6 +677,7 @@ void CPluginManager::LoadAutoPlugin(const char *file)
|
||||
if (pPlugin->GetStatus() == Plugin_Created)
|
||||
{
|
||||
AddCoreNativesToPlugin(pPlugin);
|
||||
pPlugin->InitIdentity();
|
||||
pPlugin->Call_AskPluginLoad(NULL, 0);
|
||||
}
|
||||
|
||||
@@ -712,6 +729,8 @@ IPlugin *CPluginManager::LoadPlugin(const char *path, bool debug, PluginType typ
|
||||
|
||||
AddCoreNativesToPlugin(pPlugin);
|
||||
|
||||
pPlugin->InitIdentity();
|
||||
|
||||
/* Finally, ask the plugin if it wants to be loaded */
|
||||
if (!pPlugin->Call_AskPluginLoad(error, err_max))
|
||||
{
|
||||
@@ -1092,20 +1111,25 @@ bool CPluginManager::IsLateLoadTime()
|
||||
|
||||
void CPluginManager::OnSourceModAllInitialized()
|
||||
{
|
||||
m_MyIdent = g_ShareSys.CreateCoreIdentity();
|
||||
|
||||
HandleSecurity sec;
|
||||
|
||||
sec.owner = 1; /* :TODO: implement ShareSys */
|
||||
sec.owner = m_MyIdent; /* :TODO: implement ShareSys */
|
||||
sec.access[HandleAccess_Create] = false;
|
||||
sec.access[HandleAccess_Delete] = false;
|
||||
sec.access[HandleAccess_Inherit] = false;
|
||||
sec.access[HandleAccess_Clone] = false;
|
||||
|
||||
g_PluginType = g_HandleSys.CreateTypeEx("IPlugin", this, 0, &sec);
|
||||
g_PluginType = g_HandleSys.CreateTypeEx("IPlugin", this, 0, &sec, NULL);
|
||||
g_PluginIdent = g_ShareSys.CreateIdentType("PLUGIN");
|
||||
}
|
||||
|
||||
void CPluginManager::OnSourceModShutdown()
|
||||
{
|
||||
g_HandleSys.RemoveType(g_PluginType, 1);
|
||||
g_HandleSys.RemoveType(g_PluginType, m_MyIdent);
|
||||
g_ShareSys.DestroyIdentType(g_PluginIdent);
|
||||
g_ShareSys.DestroyIdentity(m_MyIdent);
|
||||
}
|
||||
|
||||
void CPluginManager::OnHandleDestroy(HandleType_t type, void *object)
|
||||
|
||||
@@ -93,7 +93,7 @@ public:
|
||||
virtual const sp_plugin_t *GetPluginStructure() const;
|
||||
virtual IPluginFunction *GetFunctionByName(const char *public_name);
|
||||
virtual IPluginFunction *GetFunctionById(funcid_t func_id);
|
||||
virtual IdentityToken_t GetIdentity();
|
||||
virtual IdentityToken_t *GetIdentity();
|
||||
public:
|
||||
/**
|
||||
* Creates a plugin object with default values.
|
||||
@@ -114,11 +114,17 @@ public:
|
||||
*/
|
||||
bool FinishMyCompile(char *error, size_t maxlength);
|
||||
void CancelMyCompile();
|
||||
|
||||
/**
|
||||
* Sets an error state on the plugin
|
||||
*/
|
||||
void SetErrorState(PluginStatus status, const char *error_fmt, ...);
|
||||
|
||||
/**
|
||||
* Initializes the plugin's identity information
|
||||
*/
|
||||
void InitIdentity();
|
||||
|
||||
/**
|
||||
* Calls the OnPluginLoad function, and sets any failed states if necessary.
|
||||
* NOTE: Valid pre-states are: Plugin_Created
|
||||
@@ -151,6 +157,7 @@ private:
|
||||
CFunction **m_pub_funcs;
|
||||
char m_errormsg[256];
|
||||
time_t m_LastAccess;
|
||||
IdentityToken_t *m_ident;
|
||||
Handle_t m_handle;
|
||||
};
|
||||
|
||||
@@ -262,6 +269,10 @@ protected:
|
||||
void ReleaseIterator(CPluginIterator *iter);
|
||||
CFunction *GetFunctionFromPool(funcid_t f, CPlugin *plugin);
|
||||
void ReleaseFunctionToPool(CFunction *func);
|
||||
inline IdentityToken_t *GetIdentity()
|
||||
{
|
||||
return m_MyIdent;
|
||||
}
|
||||
private:
|
||||
List<IPluginsListener *> m_listeners;
|
||||
List<CPlugin *> m_plugins;
|
||||
@@ -271,6 +282,7 @@ private:
|
||||
CPluginInfoDatabase m_PluginInfo;
|
||||
Trie *m_LoadLookup;
|
||||
bool m_AllPluginsLoaded;
|
||||
IdentityToken_t *m_MyIdent;
|
||||
};
|
||||
|
||||
extern CPluginManager g_PluginSys;
|
||||
|
||||
@@ -0,0 +1,195 @@
|
||||
#include "ShareSys.h"
|
||||
#include "HandleSys.h"
|
||||
|
||||
ShareSystem g_ShareSys;
|
||||
|
||||
ShareSystem::ShareSystem()
|
||||
{
|
||||
m_IdentRoot.ident = 0;
|
||||
m_TypeRoot = 0;
|
||||
m_IfaceType = 0;
|
||||
m_CoreType = 0;
|
||||
}
|
||||
|
||||
IdentityToken_t *ShareSystem::CreateCoreIdentity()
|
||||
{
|
||||
if (!m_CoreType)
|
||||
{
|
||||
m_CoreType = CreateIdentType("CORE");
|
||||
}
|
||||
|
||||
return CreateIdentity(m_CoreType);
|
||||
}
|
||||
|
||||
void ShareSystem::OnSourceModStartup(bool late)
|
||||
{
|
||||
HandleSecurity sec;
|
||||
|
||||
sec.owner = GetIdentRoot();
|
||||
sec.access[HandleAccess_Inherit] = false;
|
||||
sec.access[HandleAccess_Delete] = false;
|
||||
|
||||
m_TypeRoot = g_HandleSys.CreateTypeEx("Identity", this, 0, &sec, NULL);
|
||||
m_IfaceType = g_HandleSys.CreateTypeEx("Interface", this, 0, &sec, NULL);
|
||||
|
||||
/* Initialize our static identity handle */
|
||||
m_IdentRoot.ident = g_HandleSys.CreateHandle(m_TypeRoot, NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
void ShareSystem::OnSourceModShutdown()
|
||||
{
|
||||
if (m_CoreType)
|
||||
{
|
||||
g_HandleSys.RemoveType(m_CoreType, GetIdentRoot());
|
||||
}
|
||||
|
||||
g_HandleSys.RemoveType(m_IfaceType, GetIdentRoot());
|
||||
g_HandleSys.RemoveType(m_TypeRoot, GetIdentRoot());
|
||||
}
|
||||
|
||||
IdentityType_t ShareSystem::FindIdentType(const char *name)
|
||||
{
|
||||
HandleType_t type;
|
||||
|
||||
if (g_HandleSys.FindHandleType(name, &type))
|
||||
{
|
||||
if (g_HandleSys.TypeCheck(type, m_TypeRoot))
|
||||
{
|
||||
return type;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
IdentityType_t ShareSystem::CreateIdentType(const char *name)
|
||||
{
|
||||
if (!m_TypeRoot)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
return g_HandleSys.CreateTypeEx(name, this, m_TypeRoot, NULL, GetIdentRoot());
|
||||
}
|
||||
|
||||
void ShareSystem::OnHandleDestroy(HandleType_t type, void *object)
|
||||
{
|
||||
/* We don't care here */
|
||||
}
|
||||
|
||||
IdentityToken_t *ShareSystem::CreateIdentity(IdentityType_t type)
|
||||
{
|
||||
if (!m_TypeRoot)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* :TODO: Cache? */
|
||||
IdentityToken_t *pToken = new IdentityToken_t;
|
||||
pToken->ident = g_HandleSys.CreateHandle(type, NULL, NULL, GetIdentRoot());
|
||||
|
||||
return pToken;
|
||||
}
|
||||
|
||||
bool ShareSystem::AddInterface(SMInterface *iface, IdentityToken_t *token)
|
||||
{
|
||||
if (!iface)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
IfaceInfo info;
|
||||
|
||||
info.iface = iface;
|
||||
info.token = token;
|
||||
|
||||
if (token)
|
||||
{
|
||||
/* If we're an external object, we have to do this */
|
||||
info.handle = g_HandleSys.CreateHandle(m_IfaceType, iface, token, GetIdentRoot());
|
||||
} else {
|
||||
info.handle = 0;
|
||||
}
|
||||
|
||||
m_Interfaces.push_back(info);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool ShareSystem::RequestInterface(const char *iface_name,
|
||||
unsigned int iface_vers,
|
||||
IdentityToken_t *token,
|
||||
SMInterface **pIface)
|
||||
{
|
||||
/* If Some yahoo.... SOME HOOLIGAN... some NO GOOD DIRTY
|
||||
* 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))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/* See if the interface exists */
|
||||
List<IfaceInfo>::iterator iter;
|
||||
SMInterface *iface;
|
||||
IdentityToken_t *iface_owner;
|
||||
Handle_t iface_handle;
|
||||
bool found = false;
|
||||
for (iter=m_Interfaces.begin(); iter!=m_Interfaces.end(); iter++)
|
||||
{
|
||||
IfaceInfo &info = (*iter);
|
||||
iface = info.iface;
|
||||
if (strcmp(iface->GetInterfaceName(), iface_name) == 0)
|
||||
{
|
||||
if (iface->GetInterfaceVersion() == iface_vers
|
||||
|| iface->IsVersionCompatible(iface_vers))
|
||||
{
|
||||
iface_owner = info.token;
|
||||
iface_handle = info.handle;
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!found)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
/* If something external owns this, we need to track it. */
|
||||
if (iface_owner)
|
||||
{
|
||||
Handle_t newhandle;
|
||||
if (g_HandleSys.CloneHandle(iface_handle, &newhandle, token, GetIdentRoot())
|
||||
!= HandleError_None)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
/**
|
||||
* Now we can deny module loads based on dependencies.
|
||||
*/
|
||||
}
|
||||
|
||||
/* :TODO: finish */
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void ShareSystem::AddNatives(IdentityToken_t *token, const sp_nativeinfo_t *natives[])
|
||||
{
|
||||
/* :TODO: implement */
|
||||
}
|
||||
|
||||
void ShareSystem::DestroyIdentity(IdentityToken_t *identity)
|
||||
{
|
||||
g_HandleSys.FreeHandle(identity->ident, GetIdentRoot());
|
||||
delete identity;
|
||||
}
|
||||
|
||||
void ShareSystem::DestroyIdentType(IdentityType_t type)
|
||||
{
|
||||
g_HandleSys.RemoveType(type, GetIdentRoot());
|
||||
}
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
#ifndef _INCLUDE_SOURCEMOD_SHARESYSTEM_H_
|
||||
#define _INCLUDE_SOURCEMOD_SHARESYSTEM_H_
|
||||
|
||||
#include <IShareSys.h>
|
||||
#include <IHandleSys.h>
|
||||
#include <sh_list.h>
|
||||
#include "sm_globals.h"
|
||||
#include "sourcemod.h"
|
||||
|
||||
using namespace SourceHook;
|
||||
|
||||
namespace SourceMod
|
||||
{
|
||||
struct IdentityToken_t
|
||||
{
|
||||
Handle_t ident;
|
||||
};
|
||||
};
|
||||
|
||||
struct IfaceInfo
|
||||
{
|
||||
SMInterface *iface;
|
||||
IdentityToken_t *token;
|
||||
Handle_t handle;
|
||||
};
|
||||
|
||||
class ShareSystem :
|
||||
public IShareSys,
|
||||
public SMGlobalClass,
|
||||
public IHandleTypeDispatch
|
||||
{
|
||||
public:
|
||||
ShareSystem();
|
||||
public: //IShareSys
|
||||
bool AddInterface(SMInterface *iface, IdentityToken_t *token);
|
||||
bool RequestInterface(const char *iface_name,
|
||||
unsigned int iface_vers,
|
||||
IdentityToken_t *token,
|
||||
SMInterface **pIface);
|
||||
void AddNatives(IdentityToken_t *token, const sp_nativeinfo_t *natives[]);
|
||||
IdentityType_t CreateIdentType(const char *name);
|
||||
IdentityType_t FindIdentType(const char *name);
|
||||
IdentityToken_t *CreateIdentity(IdentityType_t type);
|
||||
void DestroyIdentType(IdentityType_t type);
|
||||
void DestroyIdentity(IdentityToken_t *identity);
|
||||
public: //SMGlobalClass
|
||||
/* Pre-empt in case anything tries to register idents early */
|
||||
void OnSourceModStartup(bool late);
|
||||
void OnSourceModShutdown();
|
||||
public: //IHandleTypeDispatch
|
||||
void OnHandleDestroy(HandleType_t type, void *object);
|
||||
public:
|
||||
IdentityToken_t *CreateCoreIdentity();
|
||||
public:
|
||||
inline IdentityToken_t *GetIdentRoot()
|
||||
{
|
||||
return &m_IdentRoot;
|
||||
}
|
||||
private:
|
||||
List<IfaceInfo> m_Interfaces;
|
||||
HandleType_t m_TypeRoot;
|
||||
IdentityToken_t m_IdentRoot;
|
||||
HandleType_t m_IfaceType;
|
||||
IdentityType_t m_CoreType;
|
||||
};
|
||||
|
||||
extern ShareSystem g_ShareSys;
|
||||
|
||||
#endif //_INCLUDE_SOURCEMOD_SHARESYSTEM_H_
|
||||
Reference in New Issue
Block a user