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:
parent
5b331ca858
commit
f068587ecc
@ -7,6 +7,8 @@
|
|||||||
#define SMINTERFACE_HANDLESYSTEM_NAME "IHandleSys"
|
#define SMINTERFACE_HANDLESYSTEM_NAME "IHandleSys"
|
||||||
#define SMINTERFACE_HANDLESYSTEM_VERSION 1
|
#define SMINTERFACE_HANDLESYSTEM_VERSION 1
|
||||||
|
|
||||||
|
#define DEFAULT_IDENTITY NULL
|
||||||
|
|
||||||
namespace SourceMod
|
namespace SourceMod
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
@ -37,6 +39,7 @@ namespace SourceMod
|
|||||||
HandleError_Index, /* generic internal indexing error */
|
HandleError_Index, /* generic internal indexing error */
|
||||||
HandleError_Access, /* No access permitted to free this handle */
|
HandleError_Access, /* No access permitted to free this handle */
|
||||||
HandleError_Limit, /* The limited number of handles has been reached */
|
HandleError_Limit, /* The limited number of handles has been reached */
|
||||||
|
HandleError_Identity, /* The identity token was not usable */
|
||||||
};
|
};
|
||||||
|
|
||||||
enum HandleAccessRight
|
enum HandleAccessRight
|
||||||
@ -54,14 +57,14 @@ namespace SourceMod
|
|||||||
{
|
{
|
||||||
HandleSecurity()
|
HandleSecurity()
|
||||||
{
|
{
|
||||||
owner = 0;
|
owner = NULL;
|
||||||
access[HandleAccess_Create] = true;
|
access[HandleAccess_Create] = true;
|
||||||
access[HandleAccess_Read] = true;
|
access[HandleAccess_Read] = true;
|
||||||
access[HandleAccess_Delete] = true;
|
access[HandleAccess_Delete] = true;
|
||||||
access[HandleAccess_Inherit] = true;
|
access[HandleAccess_Inherit] = true;
|
||||||
access[HandleAccess_Clone] = true;
|
access[HandleAccess_Clone] = true;
|
||||||
}
|
}
|
||||||
IdentityToken_t owner; /* Owner of the handle */
|
IdentityToken_t *owner; /* Owner of the handle */
|
||||||
bool access[HandleAccess_TOTAL]; /* World access rights */
|
bool access[HandleAccess_TOTAL]; /* World access rights */
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -112,12 +115,14 @@ namespace SourceMod
|
|||||||
* @param parent Parent handle to inherit from, 0 for none.
|
* @param parent Parent handle to inherit from, 0 for none.
|
||||||
* @param security Pointer to a temporary HandleSecurity object, NULL to use default
|
* @param security Pointer to a temporary HandleSecurity object, NULL to use default
|
||||||
* or inherited permissions.
|
* or inherited permissions.
|
||||||
|
* @param ident Security token for any permissions.
|
||||||
* @return A new HandleType_t unique ID.
|
* @return A new HandleType_t unique ID.
|
||||||
*/
|
*/
|
||||||
virtual HandleType_t CreateTypeEx(const char *name,
|
virtual HandleType_t CreateTypeEx(const char *name,
|
||||||
IHandleTypeDispatch *dispatch,
|
IHandleTypeDispatch *dispatch,
|
||||||
HandleType_t parent,
|
HandleType_t parent,
|
||||||
const HandleSecurity *security) =0;
|
const HandleSecurity *security,
|
||||||
|
IdentityToken_t *ident) =0;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -143,7 +148,7 @@ namespace SourceMod
|
|||||||
* @param type Type chain to remove.
|
* @param type Type chain to remove.
|
||||||
* @return True on success, false on failure.
|
* @return True on success, false on failure.
|
||||||
*/
|
*/
|
||||||
virtual bool RemoveType(HandleType_t type, IdentityToken_t ident) =0;
|
virtual bool RemoveType(HandleType_t type, IdentityToken_t *ident) =0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Finds a handle type by name.
|
* @brief Finds a handle type by name.
|
||||||
@ -159,14 +164,14 @@ namespace SourceMod
|
|||||||
*
|
*
|
||||||
* @param type Type to use on the handle.
|
* @param type Type to use on the handle.
|
||||||
* @param object Object to bind to the handle.
|
* @param object Object to bind to the handle.
|
||||||
* @param source Identity token for object using this handle (for example, a script).
|
* @param owner Owner for the handle.
|
||||||
* @param ident Identity token if any security rights are needed.
|
* @param ident Identity token if any security rights are needed.
|
||||||
* @return A new Handle_t, or 0 on failure.
|
* @return A new Handle_t, or 0 on failure.
|
||||||
*/
|
*/
|
||||||
virtual Handle_t CreateHandle(HandleType_t type,
|
virtual Handle_t CreateHandle(HandleType_t type,
|
||||||
void *object,
|
void *object,
|
||||||
IdentityToken_t source,
|
IdentityToken_t *owner,
|
||||||
IdentityToken_t ident) =0;
|
IdentityToken_t *ident) =0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Creates a new handle.
|
* @brief Creates a new handle.
|
||||||
@ -181,7 +186,7 @@ namespace SourceMod
|
|||||||
virtual Handle_t CreateScriptHandle(HandleType_t type,
|
virtual Handle_t CreateScriptHandle(HandleType_t type,
|
||||||
void *object,
|
void *object,
|
||||||
sp_context_t *ctx,
|
sp_context_t *ctx,
|
||||||
IdentityToken_t ident) =0;
|
IdentityToken_t *ident) =0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Frees the memory associated with a handle and calls any destructors.
|
* @brief Frees the memory associated with a handle and calls any destructors.
|
||||||
@ -192,7 +197,7 @@ namespace SourceMod
|
|||||||
* @param ident Identity token, for destroying secure handles (0 for none).
|
* @param ident Identity token, for destroying secure handles (0 for none).
|
||||||
* @return A HandleError error code.
|
* @return A HandleError error code.
|
||||||
*/
|
*/
|
||||||
virtual HandleError FreeHandle(Handle_t handle, IdentityToken_t ident) =0;
|
virtual HandleError FreeHandle(Handle_t handle, IdentityToken_t *ident) =0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Clones a handle by adding to its internal reference count. Its data,
|
* @brief Clones a handle by adding to its internal reference count. Its data,
|
||||||
@ -200,11 +205,11 @@ namespace SourceMod
|
|||||||
*
|
*
|
||||||
* @param handle Handle to duplicate. Any non-free handle target is valid.
|
* @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 newhandle If non-NULL, stores the duplicated handle in the pointer.
|
||||||
* @param source New source of cloned handle.
|
* @param owner New owner of cloned handle.
|
||||||
* @param ident Security token, if needed.
|
* @param ident Security token, if needed.
|
||||||
* @return A HandleError error code.
|
* @return A HandleError error code.
|
||||||
*/
|
*/
|
||||||
virtual HandleError CloneHandle(Handle_t handle, Handle_t *newhandle, IdentityToken_t source, IdentityToken_t ident) =0;
|
virtual HandleError CloneHandle(Handle_t handle, Handle_t *newhandle, IdentityToken_t *owner, IdentityToken_t *ident) =0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Retrieves the contents of a handle.
|
* @brief Retrieves the contents of a handle.
|
||||||
@ -215,7 +220,7 @@ namespace SourceMod
|
|||||||
* @param object Address to store object in.
|
* @param object Address to store object in.
|
||||||
* @return HandleError error code.
|
* @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, IdentityToken_t *ident, void **object) =0;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -147,7 +147,7 @@ namespace SourceMod
|
|||||||
/**
|
/**
|
||||||
* @brief Returns a plugin's identity token.
|
* @brief Returns a plugin's identity token.
|
||||||
*/
|
*/
|
||||||
virtual IdentityToken_t GetIdentity() =0;
|
virtual IdentityToken_t *GetIdentity() =0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -3,11 +3,13 @@
|
|||||||
|
|
||||||
#include <sp_vm_types.h>
|
#include <sp_vm_types.h>
|
||||||
|
|
||||||
#define DEFAULT_IDENTITY 0
|
#define NO_IDENTITY 0
|
||||||
|
|
||||||
namespace SourceMod
|
namespace SourceMod
|
||||||
{
|
{
|
||||||
typedef unsigned int IdentityToken_t;
|
struct IdentityToken_t;
|
||||||
|
typedef unsigned int HandleType_t;
|
||||||
|
typedef HandleType_t IdentityType_t;
|
||||||
/**
|
/**
|
||||||
* @brief Defines the base functionality required by a shared interface.
|
* @brief Defines the base functionality required by a shared interface.
|
||||||
*/
|
*/
|
||||||
@ -49,12 +51,13 @@ namespace SourceMod
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
* @brief Adds an interface to the global interface system
|
* @brief Adds an interface to the global interface system.
|
||||||
*
|
*
|
||||||
* @param iface Interface pointer (must be unique).
|
* @param iface Interface pointer (must be unique).
|
||||||
* @param token Parent token of the module/interface.
|
* @param token Parent token of the module/interface.
|
||||||
|
* @return True on success, false otherwise.
|
||||||
*/
|
*/
|
||||||
virtual bool AddInterface(SMInterface *iface, IdentityToken_t token) =0;
|
virtual bool AddInterface(SMInterface *iface, IdentityToken_t *token) =0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Requests an interface from the global interface system.
|
* @brief Requests an interface from the global interface system.
|
||||||
@ -67,8 +70,8 @@ namespace SourceMod
|
|||||||
*/
|
*/
|
||||||
virtual bool RequestInterface(const char *iface_name,
|
virtual bool RequestInterface(const char *iface_name,
|
||||||
unsigned int iface_vers,
|
unsigned int iface_vers,
|
||||||
IdentityToken_t token,
|
IdentityToken_t *token,
|
||||||
void **pIface) =0;
|
SMInterface **pIface) =0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Adds a list of natives to the global native pool.
|
* @brief Adds a list of natives to the global native pool.
|
||||||
@ -76,7 +79,54 @@ namespace SourceMod
|
|||||||
* @param token Identity token of parent object.
|
* @param token Identity token of parent object.
|
||||||
* @param natives Array of natives to add, NULL terminated.
|
* @param natives Array of natives to add, NULL terminated.
|
||||||
*/
|
*/
|
||||||
virtual void AddNatives(IdentityToken_t token, const sp_nativeinfo_t *natives[]) =0;
|
virtual void AddNatives(IdentityToken_t *token, const sp_nativeinfo_t *natives[]) =0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Creates a new identity type.
|
||||||
|
* NOTE: Module authors should never need to use this. Due to the current implementation,
|
||||||
|
* there is a hardcoded limit of 15 types. Core uses up a few, so think carefully!
|
||||||
|
*
|
||||||
|
* @param name String containing type name. Must not be empty or NULL.
|
||||||
|
* @return A new HandleType_t identifier, or 0 on failure.
|
||||||
|
*/
|
||||||
|
virtual IdentityType_t CreateIdentType(const char *name) =0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Finds an identity type by name.
|
||||||
|
* DEFAULT IDENTITY TYPES:
|
||||||
|
* "PLUGIN" - An IPlugin object.
|
||||||
|
* "MODULE" - An IModule object.
|
||||||
|
* "CORE" - An SMGlobalClass or other singleton.
|
||||||
|
*
|
||||||
|
* @param name String containing type name to search for.
|
||||||
|
* @return A HandleType_t identifier if found, 0 otherwise.
|
||||||
|
*/
|
||||||
|
virtual IdentityType_t FindIdentType(const char *name) =0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Creates a new identity token. This token is guaranteed to be unique
|
||||||
|
* amongst all other open identities.
|
||||||
|
*
|
||||||
|
* @param type Identity type.
|
||||||
|
* @return A new IdentityToken_t identifier.
|
||||||
|
*/
|
||||||
|
virtual IdentityToken_t *CreateIdentity(IdentityType_t type) =0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Destroys an identity type. Note that this will delete any identities
|
||||||
|
* that are under this type.
|
||||||
|
*
|
||||||
|
* @param type Identity type.
|
||||||
|
*/
|
||||||
|
virtual void DestroyIdentType(IdentityType_t type) =0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Destroys an identity token. Any handles being owned by this token, or
|
||||||
|
* any handles being
|
||||||
|
*
|
||||||
|
* @param identity Identity to remove.
|
||||||
|
*/
|
||||||
|
virtual void DestroyIdentity(IdentityToken_t *identity) =0;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -13,6 +13,40 @@
|
|||||||
using namespace SourcePawn;
|
using namespace SourcePawn;
|
||||||
using namespace SourceMod;
|
using namespace SourceMod;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Any class deriving from this will be automatically initiated/shutdown by SourceMod
|
||||||
|
*/
|
||||||
|
class SMGlobalClass
|
||||||
|
{
|
||||||
|
friend class SourceModBase;
|
||||||
|
public:
|
||||||
|
SMGlobalClass();
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* @brief Called when SourceMod is initially loading
|
||||||
|
*/
|
||||||
|
virtual void OnSourceModStartup(bool late)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Called after all global classes have initialized
|
||||||
|
*/
|
||||||
|
virtual void OnSourceModAllInitialized()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Called when SourceMod is shutting down
|
||||||
|
*/
|
||||||
|
virtual void OnSourceModShutdown()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
SMGlobalClass *m_pGlobalClassNext;
|
||||||
|
static SMGlobalClass *head;
|
||||||
|
};
|
||||||
|
|
||||||
extern ISourcePawnEngine *g_pSourcePawn;
|
extern ISourcePawnEngine *g_pSourcePawn;
|
||||||
extern IVirtualMachine *g_pVM;
|
extern IVirtualMachine *g_pVM;
|
||||||
|
|
||||||
|
@ -52,40 +52,6 @@ private:
|
|||||||
bool m_IsLateLoadInMap;
|
bool m_IsLateLoadInMap;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Any class deriving from this will be automatically initiated/shutdown by SourceMod
|
|
||||||
*/
|
|
||||||
class SMGlobalClass
|
|
||||||
{
|
|
||||||
friend class SourceModBase;
|
|
||||||
public:
|
|
||||||
SMGlobalClass();
|
|
||||||
public:
|
|
||||||
/**
|
|
||||||
* @brief Called when SourceMod is initially loading
|
|
||||||
*/
|
|
||||||
virtual void OnSourceModStartup(bool late)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Called after all global classes have initialized
|
|
||||||
*/
|
|
||||||
virtual void OnSourceModAllInitialized()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief Called when SourceMod is shutting down
|
|
||||||
*/
|
|
||||||
virtual void OnSourceModShutdown()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
private:
|
|
||||||
SMGlobalClass *m_pGlobalClassNext;
|
|
||||||
static SMGlobalClass *head;
|
|
||||||
};
|
|
||||||
|
|
||||||
extern SourceModBase g_SourceMod;
|
extern SourceModBase g_SourceMod;
|
||||||
|
|
||||||
#endif //_INCLUDE_SOURCEMOD_GLOBALHEADER_H_
|
#endif //_INCLUDE_SOURCEMOD_GLOBALHEADER_H_
|
||||||
|
@ -1,9 +1,22 @@
|
|||||||
#include "HandleSys.h"
|
#include "HandleSys.h"
|
||||||
|
#include "ShareSys.h"
|
||||||
#include "PluginSys.h"
|
#include "PluginSys.h"
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
|
||||||
HandleSystem g_HandleSys;
|
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()
|
HandleSystem::HandleSystem()
|
||||||
{
|
{
|
||||||
m_Handles = new QHandle[HANDLESYS_MAX_HANDLES + 1];
|
m_Handles = new QHandle[HANDLESYS_MAX_HANDLES + 1];
|
||||||
@ -28,18 +41,19 @@ HandleSystem::~HandleSystem()
|
|||||||
|
|
||||||
HandleType_t HandleSystem::CreateType(const char *name, IHandleTypeDispatch *dispatch)
|
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)
|
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,
|
HandleType_t HandleSystem::CreateTypeEx(const char *name,
|
||||||
IHandleTypeDispatch *dispatch,
|
IHandleTypeDispatch *dispatch,
|
||||||
HandleType_t parent,
|
HandleType_t parent,
|
||||||
const HandleSecurity *security)
|
const HandleSecurity *security,
|
||||||
|
IdentityToken_t *ident)
|
||||||
{
|
{
|
||||||
if (!dispatch)
|
if (!dispatch)
|
||||||
{
|
{
|
||||||
@ -56,8 +70,9 @@ HandleType_t HandleSystem::CreateTypeEx(const char *name,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (parent >= HANDLESYS_TYPEARRAY_SIZE
|
if (parent >= HANDLESYS_TYPEARRAY_SIZE
|
||||||
|| m_Types[parent].dispatch != NULL
|
|| m_Types[parent].dispatch == NULL
|
||||||
|| m_Types[parent].sec.access[HandleAccess_Inherit] == false)
|
|| (m_Types[parent].sec.access[HandleAccess_Inherit] == false
|
||||||
|
&& m_Types[parent].sec.owner != ident))
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -163,8 +178,16 @@ bool HandleSystem::FindHandleType(const char *name, HandleType_t *type)
|
|||||||
HandleError HandleSystem::MakePrimHandle(HandleType_t type,
|
HandleError HandleSystem::MakePrimHandle(HandleType_t type,
|
||||||
QHandle **in_pHandle,
|
QHandle **in_pHandle,
|
||||||
unsigned int *in_index,
|
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;
|
unsigned int handle;
|
||||||
if (m_FreeHandles == 0)
|
if (m_FreeHandles == 0)
|
||||||
{
|
{
|
||||||
@ -187,10 +210,12 @@ HandleError HandleSystem::MakePrimHandle(HandleType_t type,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Set essential information */
|
/* Set essential information */
|
||||||
pHandle->set = true;
|
pHandle->set = HandleSet_Used;;
|
||||||
pHandle->refcount = 1;
|
pHandle->refcount = 1;
|
||||||
pHandle->type = type;
|
pHandle->type = type;
|
||||||
pHandle->serial = m_HSerial;
|
pHandle->serial = m_HSerial;
|
||||||
|
pHandle->owner = owner;
|
||||||
|
pHandle->ch_next = 0;
|
||||||
|
|
||||||
/* Create the hash value */
|
/* Create the hash value */
|
||||||
Handle_t hash = pHandle->serial;
|
Handle_t hash = pHandle->serial;
|
||||||
@ -205,10 +230,44 @@ HandleError HandleSystem::MakePrimHandle(HandleType_t type,
|
|||||||
*in_index = handle;
|
*in_index = handle;
|
||||||
*in_handle = hash;
|
*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;
|
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
|
if (!type
|
||||||
|| type >= HANDLESYS_TYPEARRAY_SIZE
|
|| type >= HANDLESYS_TYPEARRAY_SIZE
|
||||||
@ -230,12 +289,11 @@ Handle_t HandleSystem::CreateHandle(HandleType_t type, void *object, IdentityTok
|
|||||||
QHandle *pHandle;
|
QHandle *pHandle;
|
||||||
HandleError err;
|
HandleError err;
|
||||||
|
|
||||||
if ((err=MakePrimHandle(type, &pHandle, &index, &handle)) != HandleError_None)
|
if ((err=MakePrimHandle(type, &pHandle, &index, &handle, source)) != HandleError_None)
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
pHandle->source = source;
|
|
||||||
pHandle->object = object;
|
pHandle->object = object;
|
||||||
pHandle->clone = 0;
|
pHandle->clone = 0;
|
||||||
|
|
||||||
@ -245,15 +303,35 @@ Handle_t HandleSystem::CreateHandle(HandleType_t type, void *object, IdentityTok
|
|||||||
Handle_t HandleSystem::CreateScriptHandle(HandleType_t type,
|
Handle_t HandleSystem::CreateScriptHandle(HandleType_t type,
|
||||||
void *object,
|
void *object,
|
||||||
sp_context_t *ctx,
|
sp_context_t *ctx,
|
||||||
IdentityToken_t ident)
|
IdentityToken_t *ident)
|
||||||
{
|
{
|
||||||
IPlugin *pPlugin = g_PluginSys.FindPluginByContext(ctx);
|
IPlugin *pPlugin = g_PluginSys.FindPluginByContext(ctx);
|
||||||
|
|
||||||
return CreateHandle(type, object, pPlugin->GetIdentity(), ident);
|
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,
|
HandleError HandleSystem::GetHandle(Handle_t handle,
|
||||||
IdentityToken_t ident,
|
IdentityToken_t *ident,
|
||||||
QHandle **in_pHandle,
|
QHandle **in_pHandle,
|
||||||
unsigned int *in_index,
|
unsigned int *in_index,
|
||||||
HandleAccessRight access)
|
HandleAccessRight access)
|
||||||
@ -277,6 +355,11 @@ HandleError HandleSystem::GetHandle(Handle_t handle,
|
|||||||
if (!pHandle->set)
|
if (!pHandle->set)
|
||||||
{
|
{
|
||||||
return HandleError_Freed;
|
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)
|
if (pHandle->serial != serial)
|
||||||
{
|
{
|
||||||
@ -289,7 +372,7 @@ HandleError HandleSystem::GetHandle(Handle_t handle,
|
|||||||
return HandleError_None;
|
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;
|
HandleError err;
|
||||||
QHandle *pHandle;
|
QHandle *pHandle;
|
||||||
@ -307,13 +390,12 @@ HandleError HandleSystem::CloneHandle(Handle_t handle, Handle_t *out_newhandle,
|
|||||||
QHandle *pNewHandle;
|
QHandle *pNewHandle;
|
||||||
Handle_t new_handle;
|
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;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
pNewHandle->clone = index;
|
pNewHandle->clone = index;
|
||||||
pNewHandle->source = source;
|
|
||||||
|
|
||||||
if (out_newhandle)
|
if (out_newhandle)
|
||||||
{
|
{
|
||||||
@ -323,7 +405,7 @@ HandleError HandleSystem::CloneHandle(Handle_t handle, Handle_t *out_newhandle,
|
|||||||
return HandleError_None;
|
return HandleError_None;
|
||||||
}
|
}
|
||||||
|
|
||||||
HandleError HandleSystem::FreeHandle(Handle_t handle, IdentityToken_t ident)
|
HandleError HandleSystem::FreeHandle(Handle_t handle, IdentityToken_t *ident)
|
||||||
{
|
{
|
||||||
unsigned int index;
|
unsigned int index;
|
||||||
QHandle *pHandle;
|
QHandle *pHandle;
|
||||||
@ -361,14 +443,9 @@ HandleError HandleSystem::FreeHandle(Handle_t handle, IdentityToken_t ident)
|
|||||||
return HandleError_None;
|
return HandleError_None;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline HandleType_t TypeParent(HandleType_t type)
|
|
||||||
{
|
|
||||||
return (type & ~HANDLESYS_SUBTYPE_MASK);
|
|
||||||
}
|
|
||||||
|
|
||||||
HandleError HandleSystem::ReadHandle(Handle_t handle,
|
HandleError HandleSystem::ReadHandle(Handle_t handle,
|
||||||
HandleType_t type,
|
HandleType_t type,
|
||||||
IdentityToken_t ident,
|
IdentityToken_t *ident,
|
||||||
void **object)
|
void **object)
|
||||||
{
|
{
|
||||||
unsigned int index;
|
unsigned int index;
|
||||||
@ -412,12 +489,59 @@ void HandleSystem::ReleasePrimHandle(unsigned int index)
|
|||||||
{
|
{
|
||||||
QHandle *pHandle = &m_Handles[index];
|
QHandle *pHandle = &m_Handles[index];
|
||||||
|
|
||||||
pHandle->set = false;
|
pHandle->set = HandleSet_None;
|
||||||
m_Types[pHandle->type].opened--;
|
m_Types[pHandle->type].opened--;
|
||||||
m_Handles[++m_FreeHandles].freeID = index;
|
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)
|
if (type == 0 || type >= HANDLESYS_TYPEARRAY_SIZE)
|
||||||
{
|
{
|
||||||
@ -499,3 +623,16 @@ bool HandleSystem::RemoveType(HandleType_t type, IdentityToken_t ident)
|
|||||||
|
|
||||||
return true;
|
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;
|
||||||
|
}
|
||||||
|
@ -16,16 +16,46 @@
|
|||||||
#define HANDLESYS_SERIAL_MASK 0xFFFF0000
|
#define HANDLESYS_SERIAL_MASK 0xFFFF0000
|
||||||
#define HANDLESYS_HANDLE_MASK 0x0000FFFF
|
#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
|
struct QHandle
|
||||||
{
|
{
|
||||||
HandleType_t type; /* Handle type */
|
HandleType_t type; /* Handle type */
|
||||||
void *object; /* Unmaintained object pointer */
|
void *object; /* Unmaintained object pointer */
|
||||||
unsigned int freeID; /* ID of a free handle in the free handle chain */
|
IdentityToken_t *owner; /* Identity of object which owns this */
|
||||||
IdentityToken_t source; /* Identity of object which owns this */
|
|
||||||
unsigned int serial; /* Serial no. for sanity checking */
|
unsigned int serial; /* Serial no. for sanity checking */
|
||||||
unsigned int refcount; /* Reference count for safe destruction */
|
unsigned int refcount; /* Reference count for safe destruction */
|
||||||
Handle_t clone; /* If non-zero, this is our cloned parent */
|
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
|
struct QHandleType
|
||||||
@ -41,6 +71,8 @@ struct QHandleType
|
|||||||
class HandleSystem :
|
class HandleSystem :
|
||||||
public IHandleSys
|
public IHandleSys
|
||||||
{
|
{
|
||||||
|
friend HandleError IdentityHandle(IdentityToken_t *token, unsigned int *index);
|
||||||
|
friend class ShareSystem;
|
||||||
public:
|
public:
|
||||||
HandleSystem();
|
HandleSystem();
|
||||||
~HandleSystem();
|
~HandleSystem();
|
||||||
@ -49,24 +81,26 @@ public: //IHandleSystem
|
|||||||
HandleType_t CreateTypeEx(const char *name,
|
HandleType_t CreateTypeEx(const char *name,
|
||||||
IHandleTypeDispatch *dispatch,
|
IHandleTypeDispatch *dispatch,
|
||||||
HandleType_t parent,
|
HandleType_t parent,
|
||||||
const HandleSecurity *security);
|
const HandleSecurity *security,
|
||||||
|
IdentityToken_t *ident);
|
||||||
HandleType_t CreateChildType(const char *name, HandleType_t parent, IHandleTypeDispatch *dispatch);
|
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);
|
bool FindHandleType(const char *name, HandleType_t *type);
|
||||||
Handle_t CreateHandle(HandleType_t type,
|
Handle_t CreateHandle(HandleType_t type,
|
||||||
void *object,
|
void *object,
|
||||||
IdentityToken_t source,
|
IdentityToken_t *source,
|
||||||
IdentityToken_t ident);
|
IdentityToken_t *ident);
|
||||||
Handle_t CreateScriptHandle(HandleType_t type, void *object, sp_context_t *ctx, 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 FreeHandle(Handle_t handle, IdentityToken_t *ident);
|
||||||
HandleError CloneHandle(Handle_t handle, Handle_t *newhandle, IdentityToken_t source, 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);
|
HandleError ReadHandle(Handle_t handle, HandleType_t type, IdentityToken_t *ident, void **object);
|
||||||
private:
|
bool TypeCheck(HandleType_t intype, HandleType_t outtype);
|
||||||
|
protected:
|
||||||
/**
|
/**
|
||||||
* Decodes a handle with sanity and security checking.
|
* Decodes a handle with sanity and security checking.
|
||||||
*/
|
*/
|
||||||
HandleError GetHandle(Handle_t handle,
|
HandleError GetHandle(Handle_t handle,
|
||||||
IdentityToken_t ident,
|
IdentityToken_t *ident,
|
||||||
QHandle **pHandle,
|
QHandle **pHandle,
|
||||||
unsigned int *index,
|
unsigned int *index,
|
||||||
HandleAccessRight access);
|
HandleAccessRight access);
|
||||||
@ -75,12 +109,28 @@ private:
|
|||||||
* Creates a basic handle and sets its reference count to 1.
|
* Creates a basic handle and sets its reference count to 1.
|
||||||
* Does not do any type or security checking.
|
* 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);
|
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:
|
private:
|
||||||
QHandle *m_Handles;
|
QHandle *m_Handles;
|
||||||
QHandleType *m_Types;
|
QHandleType *m_Types;
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include "PluginSys.h"
|
#include "PluginSys.h"
|
||||||
|
#include "ShareSys.h"
|
||||||
#include "LibrarySys.h"
|
#include "LibrarySys.h"
|
||||||
#include "HandleSys.h"
|
#include "HandleSys.h"
|
||||||
#include "sourcemm_api.h"
|
#include "sourcemm_api.h"
|
||||||
@ -8,6 +9,7 @@
|
|||||||
|
|
||||||
CPluginManager g_PluginSys;
|
CPluginManager g_PluginSys;
|
||||||
HandleType_t g_PluginType = 0;
|
HandleType_t g_PluginType = 0;
|
||||||
|
IdentityType_t g_PluginIdent = 0;
|
||||||
|
|
||||||
CPlugin::CPlugin(const char *file)
|
CPlugin::CPlugin(const char *file)
|
||||||
{
|
{
|
||||||
@ -22,8 +24,8 @@ CPlugin::CPlugin(const char *file)
|
|||||||
m_pub_funcs = NULL;
|
m_pub_funcs = NULL;
|
||||||
m_errormsg[256] = '\0';
|
m_errormsg[256] = '\0';
|
||||||
snprintf(m_filename, sizeof(m_filename), "%s", file);
|
snprintf(m_filename, sizeof(m_filename), "%s", file);
|
||||||
/* :TODO: ShareSys token */
|
m_handle = 0;
|
||||||
m_handle = g_HandleSys.CreateHandle(g_PluginType, this, DEFAULT_IDENTITY, 1);
|
m_ident = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
CPlugin::~CPlugin()
|
CPlugin::~CPlugin()
|
||||||
@ -70,7 +72,20 @@ CPlugin::~CPlugin()
|
|||||||
m_plugin = NULL;
|
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)
|
CPlugin *CPlugin::CreatePlugin(const char *file, char *error, size_t maxlength)
|
||||||
@ -447,9 +462,9 @@ bool CPlugin::SetPauseState(bool paused)
|
|||||||
return true;
|
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_LoadLookup = sm_trie_create();
|
||||||
m_AllPluginsLoaded = false;
|
m_AllPluginsLoaded = false;
|
||||||
|
m_MyIdent = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
CPluginManager::~CPluginManager()
|
CPluginManager::~CPluginManager()
|
||||||
@ -661,6 +677,7 @@ void CPluginManager::LoadAutoPlugin(const char *file)
|
|||||||
if (pPlugin->GetStatus() == Plugin_Created)
|
if (pPlugin->GetStatus() == Plugin_Created)
|
||||||
{
|
{
|
||||||
AddCoreNativesToPlugin(pPlugin);
|
AddCoreNativesToPlugin(pPlugin);
|
||||||
|
pPlugin->InitIdentity();
|
||||||
pPlugin->Call_AskPluginLoad(NULL, 0);
|
pPlugin->Call_AskPluginLoad(NULL, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -712,6 +729,8 @@ IPlugin *CPluginManager::LoadPlugin(const char *path, bool debug, PluginType typ
|
|||||||
|
|
||||||
AddCoreNativesToPlugin(pPlugin);
|
AddCoreNativesToPlugin(pPlugin);
|
||||||
|
|
||||||
|
pPlugin->InitIdentity();
|
||||||
|
|
||||||
/* Finally, ask the plugin if it wants to be loaded */
|
/* Finally, ask the plugin if it wants to be loaded */
|
||||||
if (!pPlugin->Call_AskPluginLoad(error, err_max))
|
if (!pPlugin->Call_AskPluginLoad(error, err_max))
|
||||||
{
|
{
|
||||||
@ -1092,20 +1111,25 @@ bool CPluginManager::IsLateLoadTime()
|
|||||||
|
|
||||||
void CPluginManager::OnSourceModAllInitialized()
|
void CPluginManager::OnSourceModAllInitialized()
|
||||||
{
|
{
|
||||||
|
m_MyIdent = g_ShareSys.CreateCoreIdentity();
|
||||||
|
|
||||||
HandleSecurity sec;
|
HandleSecurity sec;
|
||||||
|
|
||||||
sec.owner = 1; /* :TODO: implement ShareSys */
|
sec.owner = m_MyIdent; /* :TODO: implement ShareSys */
|
||||||
sec.access[HandleAccess_Create] = false;
|
sec.access[HandleAccess_Create] = false;
|
||||||
sec.access[HandleAccess_Delete] = false;
|
sec.access[HandleAccess_Delete] = false;
|
||||||
sec.access[HandleAccess_Inherit] = false;
|
sec.access[HandleAccess_Inherit] = false;
|
||||||
sec.access[HandleAccess_Clone] = 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()
|
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)
|
void CPluginManager::OnHandleDestroy(HandleType_t type, void *object)
|
||||||
|
@ -93,7 +93,7 @@ public:
|
|||||||
virtual const sp_plugin_t *GetPluginStructure() const;
|
virtual const sp_plugin_t *GetPluginStructure() const;
|
||||||
virtual IPluginFunction *GetFunctionByName(const char *public_name);
|
virtual IPluginFunction *GetFunctionByName(const char *public_name);
|
||||||
virtual IPluginFunction *GetFunctionById(funcid_t func_id);
|
virtual IPluginFunction *GetFunctionById(funcid_t func_id);
|
||||||
virtual IdentityToken_t GetIdentity();
|
virtual IdentityToken_t *GetIdentity();
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
* Creates a plugin object with default values.
|
* Creates a plugin object with default values.
|
||||||
@ -114,11 +114,17 @@ public:
|
|||||||
*/
|
*/
|
||||||
bool FinishMyCompile(char *error, size_t maxlength);
|
bool FinishMyCompile(char *error, size_t maxlength);
|
||||||
void CancelMyCompile();
|
void CancelMyCompile();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets an error state on the plugin
|
* Sets an error state on the plugin
|
||||||
*/
|
*/
|
||||||
void SetErrorState(PluginStatus status, const char *error_fmt, ...);
|
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.
|
* Calls the OnPluginLoad function, and sets any failed states if necessary.
|
||||||
* NOTE: Valid pre-states are: Plugin_Created
|
* NOTE: Valid pre-states are: Plugin_Created
|
||||||
@ -151,6 +157,7 @@ private:
|
|||||||
CFunction **m_pub_funcs;
|
CFunction **m_pub_funcs;
|
||||||
char m_errormsg[256];
|
char m_errormsg[256];
|
||||||
time_t m_LastAccess;
|
time_t m_LastAccess;
|
||||||
|
IdentityToken_t *m_ident;
|
||||||
Handle_t m_handle;
|
Handle_t m_handle;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -262,6 +269,10 @@ protected:
|
|||||||
void ReleaseIterator(CPluginIterator *iter);
|
void ReleaseIterator(CPluginIterator *iter);
|
||||||
CFunction *GetFunctionFromPool(funcid_t f, CPlugin *plugin);
|
CFunction *GetFunctionFromPool(funcid_t f, CPlugin *plugin);
|
||||||
void ReleaseFunctionToPool(CFunction *func);
|
void ReleaseFunctionToPool(CFunction *func);
|
||||||
|
inline IdentityToken_t *GetIdentity()
|
||||||
|
{
|
||||||
|
return m_MyIdent;
|
||||||
|
}
|
||||||
private:
|
private:
|
||||||
List<IPluginsListener *> m_listeners;
|
List<IPluginsListener *> m_listeners;
|
||||||
List<CPlugin *> m_plugins;
|
List<CPlugin *> m_plugins;
|
||||||
@ -271,6 +282,7 @@ private:
|
|||||||
CPluginInfoDatabase m_PluginInfo;
|
CPluginInfoDatabase m_PluginInfo;
|
||||||
Trie *m_LoadLookup;
|
Trie *m_LoadLookup;
|
||||||
bool m_AllPluginsLoaded;
|
bool m_AllPluginsLoaded;
|
||||||
|
IdentityToken_t *m_MyIdent;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern CPluginManager g_PluginSys;
|
extern CPluginManager g_PluginSys;
|
||||||
|
195
core/systems/ShareSys.cpp
Normal file
195
core/systems/ShareSys.cpp
Normal file
@ -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());
|
||||||
|
}
|
||||||
|
|
69
core/systems/ShareSys.h
Normal file
69
core/systems/ShareSys.h
Normal file
@ -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_
|
Loading…
Reference in New Issue
Block a user