Root menu handles in callbacks (bug 4353, r=fyren).
authorDavid Anderson <dvander@alliedmods.net>
Tue Apr 27 21:03:20 2010 -0700 (2010-04-27)
changeset 29591a7109501676
parent 2957 485d1c752340
child 2960 95f5f8a4b7dc
Root menu handles in callbacks (bug 4353, r=fyren).
core/HandleSys.cpp
core/HandleSys.h
core/MenuStyle_Base.cpp
     1.1 --- a/core/HandleSys.cpp	Sat Apr 24 21:10:23 2010 -0400
     1.2 +++ b/core/HandleSys.cpp	Tue Apr 27 21:03:20 2010 -0700
     1.3 @@ -620,6 +620,43 @@
     1.4  	return CloneHandle(pHandle, index, newhandle, newOwner);
     1.5  }
     1.6  
     1.7 +Handle_t HandleSystem::FastCloneHandle(QHandle *pHandle, unsigned int index)
     1.8 +{
     1.9 +	if (pHandle->clone)
    1.10 +		return FastCloneHandle(&m_Handles[pHandle->clone], pHandle->clone);
    1.11 +
    1.12 +	Handle_t hndl;
    1.13 +	if (CloneHandle(pHandle, index, &hndl, g_pCoreIdent) != HandleError_None)
    1.14 +		return BAD_HANDLE;
    1.15 +
    1.16 +	return hndl;
    1.17 +}
    1.18 +
    1.19 +Handle_t HandleSystem::FastCloneHandle(Handle_t hndl)
    1.20 +{
    1.21 +	QHandle *pHandle;
    1.22 +	unsigned int index;
    1.23 +
    1.24 +	GetHandleUnchecked(hndl, pHandle, index);
    1.25 +
    1.26 +	return FastCloneHandle(pHandle, index);
    1.27 +}
    1.28 +
    1.29 +void HandleSystem::GetHandleUnchecked(Handle_t hndl, QHandle *& pHandle, unsigned int &index)
    1.30 +{
    1.31 +#ifndef NDEBUG
    1.32 +	unsigned int serial = (hndl >> 16);
    1.33 +#endif
    1.34 +	index = (hndl & HANDLESYS_HANDLE_MASK);
    1.35 +
    1.36 +	assert(index != 0 && index <= m_HandleTail && index < HANDLESYS_MAX_HANDLES);
    1.37 +
    1.38 +	pHandle = &m_Handles[index];
    1.39 +
    1.40 +	assert(pHandle->set && pHandle->set != HandleSet_Freed);
    1.41 +	assert(pHandle->serial == serial);
    1.42 +}
    1.43 +
    1.44  HandleError HandleSystem::FreeHandle(QHandle *pHandle, unsigned int index)
    1.45  {
    1.46  	QHandleType *pType = &m_Types[pHandle->type];
     2.1 --- a/core/HandleSys.h	Sat Apr 24 21:10:23 2010 -0400
     2.2 +++ b/core/HandleSys.h	Tue Apr 27 21:03:20 2010 -0700
     2.3 @@ -160,6 +160,9 @@
     2.4  		HandleError *err);
     2.5  
     2.6  	void Dump(HANDLE_REPORTER rep);
     2.7 +
     2.8 +	/* Bypasses security checks. */
     2.9 +	Handle_t FastCloneHandle(Handle_t hndl);
    2.10  protected:
    2.11  	/**
    2.12  	 * Decodes a handle with sanity and security checking.
    2.13 @@ -170,6 +173,9 @@
    2.14  						  unsigned int *index,
    2.15  						  bool ignoreFree=false);
    2.16  
    2.17 +	Handle_t FastCloneHandle(QHandle *pHandle, unsigned int index);
    2.18 +	void GetHandleUnchecked(Handle_t hndl, QHandle *& pHandle, unsigned int &index);
    2.19 +
    2.20  	/**
    2.21  	 * Creates a basic handle and sets its reference count to 1.
    2.22  	 * Does not do any type or security checking.
    2.23 @@ -222,4 +228,27 @@
    2.24  
    2.25  extern HandleSystem g_HandleSys;
    2.26  
    2.27 +struct AutoHandleRooter
    2.28 +{
    2.29 +public:
    2.30 +	AutoHandleRooter(Handle_t hndl)
    2.31 +	{
    2.32 +		if (hndl != BAD_HANDLE)
    2.33 +			this->hndl = g_HandleSys.FastCloneHandle(hndl);
    2.34 +		else
    2.35 +			this->hndl = BAD_HANDLE;
    2.36 +	}
    2.37 +
    2.38 +	~AutoHandleRooter()
    2.39 +	{
    2.40 +		if (hndl != BAD_HANDLE)
    2.41 +		{
    2.42 +			HandleSecurity sec(g_pCoreIdent, g_pCoreIdent);
    2.43 +			g_HandleSys.FreeHandle(hndl, &sec);
    2.44 +		}
    2.45 +	}
    2.46 +private:
    2.47 +	Handle_t hndl;
    2.48 +};
    2.49 +
    2.50  #endif //_INCLUDE_SOURCEMOD_HANDLESYSTEM_H_
     3.1 --- a/core/MenuStyle_Base.cpp	Sat Apr 24 21:10:23 2010 -0400
     3.2 +++ b/core/MenuStyle_Base.cpp	Tue Apr 27 21:03:20 2010 -0700
     3.3 @@ -377,6 +377,9 @@
     3.4  		RemoveClientFromWatch(client);
     3.5  	}
     3.6  
     3.7 +	Handle_t hndl = menu->GetHandle();
     3.8 +	AutoHandleRooter ahr(hndl);
     3.9 +
    3.10  	if (cancel)
    3.11  	{
    3.12  		mh->OnMenuCancel(menu, client, reason);