core/systems/ShareSys.cpp
author David Anderson <dvander@alliedmods.net>
Thu Jan 11 07:29:09 2007 +0000 (2007-01-11)
changeset 283 c3d54680969a
parent 262 de0e374ffa47
child 304 fa485d2f25ed
permissions -rw-r--r--
Handle system can now unload identities safely. when an identity is removed, all handles owned by it are removed in a chain.
dvander@229
     1
#include "ShareSys.h"
dvander@229
     2
#include "HandleSys.h"
dvander@229
     3
dvander@229
     4
ShareSystem g_ShareSys;
dvander@229
     5
dvander@229
     6
ShareSystem::ShareSystem()
dvander@229
     7
{
dvander@229
     8
	m_IdentRoot.ident = 0;
dvander@229
     9
	m_TypeRoot = 0;
dvander@229
    10
	m_IfaceType = 0;
dvander@229
    11
	m_CoreType = 0;
dvander@229
    12
}
dvander@229
    13
dvander@229
    14
IdentityToken_t *ShareSystem::CreateCoreIdentity()
dvander@229
    15
{
dvander@229
    16
	if (!m_CoreType)
dvander@229
    17
	{
dvander@229
    18
		m_CoreType = CreateIdentType("CORE");
dvander@229
    19
	}
dvander@229
    20
dvander@229
    21
	return CreateIdentity(m_CoreType);
dvander@229
    22
}
dvander@229
    23
dvander@229
    24
void ShareSystem::OnSourceModStartup(bool late)
dvander@229
    25
{
dvander@262
    26
	TypeAccess sec;
dvander@229
    27
dvander@262
    28
	g_HandleSys.InitAccessDefaults(&sec, NULL);
dvander@262
    29
	sec.ident = GetIdentRoot();
dvander@262
    30
dvander@262
    31
	m_TypeRoot = g_HandleSys.CreateType("Identity", this, 0, &sec, NULL, NULL, NULL);
dvander@262
    32
	m_IfaceType = g_HandleSys.CreateType("Interface", this, 0, NULL, NULL, GetIdentRoot(), NULL);
dvander@229
    33
dvander@229
    34
	/* Initialize our static identity handle */
dvander@262
    35
	m_IdentRoot.ident = g_HandleSys.CreateHandle(m_TypeRoot, NULL, NULL, GetIdentRoot(), NULL);
dvander@229
    36
}
dvander@229
    37
dvander@229
    38
void ShareSystem::OnSourceModShutdown()
dvander@229
    39
{
dvander@229
    40
	if (m_CoreType)
dvander@229
    41
	{
dvander@229
    42
		g_HandleSys.RemoveType(m_CoreType, GetIdentRoot());
dvander@229
    43
	}
dvander@229
    44
dvander@229
    45
	g_HandleSys.RemoveType(m_IfaceType, GetIdentRoot());
dvander@229
    46
	g_HandleSys.RemoveType(m_TypeRoot, GetIdentRoot());
dvander@229
    47
}
dvander@229
    48
dvander@229
    49
IdentityType_t ShareSystem::FindIdentType(const char *name)
dvander@229
    50
{
dvander@229
    51
	HandleType_t type;
dvander@229
    52
dvander@229
    53
	if (g_HandleSys.FindHandleType(name, &type))
dvander@229
    54
	{
dvander@229
    55
		if (g_HandleSys.TypeCheck(type, m_TypeRoot))
dvander@229
    56
		{
dvander@229
    57
			return type;
dvander@229
    58
		}
dvander@229
    59
	}
dvander@229
    60
dvander@229
    61
	return 0;
dvander@229
    62
}
dvander@229
    63
dvander@229
    64
IdentityType_t ShareSystem::CreateIdentType(const char *name)
dvander@229
    65
{
dvander@229
    66
	if (!m_TypeRoot)
dvander@229
    67
	{
dvander@229
    68
		return 0;
dvander@229
    69
	}
dvander@229
    70
dvander@262
    71
	return g_HandleSys.CreateType(name, this, m_TypeRoot, NULL, NULL, GetIdentRoot(), NULL);
dvander@229
    72
}
dvander@229
    73
dvander@229
    74
void ShareSystem::OnHandleDestroy(HandleType_t type, void *object)
dvander@229
    75
{
dvander@283
    76
	/* THIS WILL NEVER BE CALLED FOR ANYTHING WITH THE IDENTITY TYPE */
dvander@229
    77
}
dvander@229
    78
dvander@229
    79
IdentityToken_t *ShareSystem::CreateIdentity(IdentityType_t type)
dvander@229
    80
{
dvander@229
    81
	if (!m_TypeRoot)
dvander@229
    82
	{
dvander@229
    83
		return 0;
dvander@229
    84
	}
dvander@229
    85
dvander@229
    86
	/* :TODO: Cache? */
dvander@229
    87
	IdentityToken_t *pToken = new IdentityToken_t;
dvander@283
    88
	pToken->ident = g_HandleSys.CreateHandleEx(type, NULL, GetIdentRoot(), GetIdentRoot(), NULL, true);
dvander@229
    89
dvander@229
    90
	return pToken;
dvander@229
    91
}
dvander@229
    92
dvander@229
    93
bool ShareSystem::AddInterface(SMInterface *iface, IdentityToken_t *token)
dvander@229
    94
{
dvander@229
    95
	if (!iface)
dvander@229
    96
	{
dvander@229
    97
		return false;
dvander@229
    98
	}
dvander@229
    99
dvander@229
   100
	IfaceInfo info;
dvander@229
   101
dvander@229
   102
	info.iface = iface;
dvander@229
   103
	info.token = token;
dvander@229
   104
	
dvander@229
   105
	if (token)
dvander@229
   106
	{
dvander@229
   107
		/* If we're an external object, we have to do this */
dvander@262
   108
		info.handle = g_HandleSys.CreateHandle(m_IfaceType, iface, token, GetIdentRoot(), NULL);
dvander@229
   109
	} else {
dvander@229
   110
		info.handle = 0;
dvander@229
   111
	}
dvander@229
   112
dvander@229
   113
	m_Interfaces.push_back(info);
dvander@229
   114
dvander@229
   115
	return true;
dvander@229
   116
}
dvander@229
   117
dvander@229
   118
bool ShareSystem::RequestInterface(const char *iface_name, 
dvander@229
   119
								   unsigned int iface_vers, 
dvander@229
   120
								   IdentityToken_t *token, 
dvander@229
   121
								   SMInterface **pIface)
dvander@229
   122
{
dvander@229
   123
	/* If Some yahoo.... SOME HOOLIGAN... some NO GOOD DIRTY 
dvander@229
   124
	 * HORRIBLE PERSON passed in a token that we don't recognize....
dvander@229
   125
	 * <b>Punish them.</b>
dvander@229
   126
	 */
dvander@262
   127
	HandleSecurity sec;
dvander@262
   128
dvander@262
   129
	sec.pIdentity = GetIdentRoot();
dvander@262
   130
	sec.pOwner = NULL;
dvander@262
   131
dvander@262
   132
	if (!g_HandleSys.ReadHandle(token->ident, m_TypeRoot, &sec, NULL))
dvander@229
   133
	{
dvander@229
   134
		return false;
dvander@229
   135
	}
dvander@229
   136
dvander@229
   137
	/* See if the interface exists */
dvander@229
   138
	List<IfaceInfo>::iterator iter;
dvander@229
   139
	SMInterface *iface;
dvander@229
   140
	IdentityToken_t *iface_owner;
dvander@229
   141
	Handle_t iface_handle;
dvander@229
   142
	bool found = false;
dvander@229
   143
	for (iter=m_Interfaces.begin(); iter!=m_Interfaces.end(); iter++)
dvander@229
   144
	{
dvander@229
   145
		IfaceInfo &info = (*iter);
dvander@229
   146
		iface = info.iface;
dvander@229
   147
		if (strcmp(iface->GetInterfaceName(), iface_name) == 0)
dvander@229
   148
		{
dvander@229
   149
			if (iface->GetInterfaceVersion() == iface_vers
dvander@229
   150
				|| iface->IsVersionCompatible(iface_vers))
dvander@229
   151
			{
dvander@229
   152
				iface_owner = info.token;
dvander@229
   153
				iface_handle = info.handle;
dvander@229
   154
				found = true;
dvander@229
   155
				break;
dvander@229
   156
			}
dvander@229
   157
		}
dvander@229
   158
	}
dvander@229
   159
dvander@229
   160
	if (!found)
dvander@229
   161
	{
dvander@229
   162
		return false;
dvander@229
   163
	}
dvander@229
   164
dvander@229
   165
	/* If something external owns this, we need to track it. */
dvander@229
   166
	if (iface_owner)
dvander@229
   167
	{
dvander@229
   168
		Handle_t newhandle;
dvander@262
   169
		if (g_HandleSys.CloneHandle(iface_handle, &newhandle, token, &sec)
dvander@229
   170
			!= HandleError_None)
dvander@229
   171
		{
dvander@229
   172
			return false;
dvander@229
   173
		}
dvander@229
   174
		/** 
dvander@229
   175
		 * Now we can deny module loads based on dependencies.
dvander@229
   176
		 */
dvander@229
   177
	}
dvander@229
   178
dvander@229
   179
	/* :TODO: finish */
dvander@229
   180
dvander@229
   181
	return NULL;
dvander@229
   182
}
dvander@229
   183
dvander@229
   184
void ShareSystem::AddNatives(IdentityToken_t *token, const sp_nativeinfo_t *natives[])
dvander@229
   185
{
dvander@229
   186
	/* :TODO: implement */
dvander@229
   187
}
dvander@229
   188
dvander@229
   189
void ShareSystem::DestroyIdentity(IdentityToken_t *identity)
dvander@229
   190
{
dvander@262
   191
	HandleSecurity sec;
dvander@262
   192
dvander@262
   193
	sec.pOwner = GetIdentRoot();
dvander@262
   194
	sec.pIdentity = GetIdentRoot();
dvander@262
   195
dvander@262
   196
	g_HandleSys.FreeHandle(identity->ident, &sec);
dvander@229
   197
	delete identity;
dvander@229
   198
}
dvander@229
   199
dvander@229
   200
void ShareSystem::DestroyIdentType(IdentityType_t type)
dvander@229
   201
{
dvander@229
   202
	g_HandleSys.RemoveType(type, GetIdentRoot());
dvander@229
   203
}
dvander@229
   204