Root menu handles in callbacks (bug 4353, r=fyren).
This commit is contained in:
parent
b8d512f5e1
commit
a36fa76d21
@ -620,6 +620,43 @@ HandleError HandleSystem::CloneHandle(Handle_t handle, Handle_t *newhandle, Iden
|
||||
return CloneHandle(pHandle, index, newhandle, newOwner);
|
||||
}
|
||||
|
||||
Handle_t HandleSystem::FastCloneHandle(QHandle *pHandle, unsigned int index)
|
||||
{
|
||||
if (pHandle->clone)
|
||||
return FastCloneHandle(&m_Handles[pHandle->clone], pHandle->clone);
|
||||
|
||||
Handle_t hndl;
|
||||
if (CloneHandle(pHandle, index, &hndl, g_pCoreIdent) != HandleError_None)
|
||||
return BAD_HANDLE;
|
||||
|
||||
return hndl;
|
||||
}
|
||||
|
||||
Handle_t HandleSystem::FastCloneHandle(Handle_t hndl)
|
||||
{
|
||||
QHandle *pHandle;
|
||||
unsigned int index;
|
||||
|
||||
GetHandleUnchecked(hndl, pHandle, index);
|
||||
|
||||
return FastCloneHandle(pHandle, index);
|
||||
}
|
||||
|
||||
void HandleSystem::GetHandleUnchecked(Handle_t hndl, QHandle *& pHandle, unsigned int &index)
|
||||
{
|
||||
#ifndef NDEBUG
|
||||
unsigned int serial = (hndl >> 16);
|
||||
#endif
|
||||
index = (hndl & HANDLESYS_HANDLE_MASK);
|
||||
|
||||
assert(index != 0 && index <= m_HandleTail && index < HANDLESYS_MAX_HANDLES);
|
||||
|
||||
pHandle = &m_Handles[index];
|
||||
|
||||
assert(pHandle->set && pHandle->set != HandleSet_Freed);
|
||||
assert(pHandle->serial == serial);
|
||||
}
|
||||
|
||||
HandleError HandleSystem::FreeHandle(QHandle *pHandle, unsigned int index)
|
||||
{
|
||||
QHandleType *pType = &m_Types[pHandle->type];
|
||||
|
@ -160,6 +160,9 @@ public: //IHandleSystem
|
||||
HandleError *err);
|
||||
|
||||
void Dump(HANDLE_REPORTER rep);
|
||||
|
||||
/* Bypasses security checks. */
|
||||
Handle_t FastCloneHandle(Handle_t hndl);
|
||||
protected:
|
||||
/**
|
||||
* Decodes a handle with sanity and security checking.
|
||||
@ -170,6 +173,9 @@ protected:
|
||||
unsigned int *index,
|
||||
bool ignoreFree=false);
|
||||
|
||||
Handle_t FastCloneHandle(QHandle *pHandle, unsigned int index);
|
||||
void GetHandleUnchecked(Handle_t hndl, QHandle *& pHandle, unsigned int &index);
|
||||
|
||||
/**
|
||||
* Creates a basic handle and sets its reference count to 1.
|
||||
* Does not do any type or security checking.
|
||||
@ -222,4 +228,27 @@ private:
|
||||
|
||||
extern HandleSystem g_HandleSys;
|
||||
|
||||
struct AutoHandleRooter
|
||||
{
|
||||
public:
|
||||
AutoHandleRooter(Handle_t hndl)
|
||||
{
|
||||
if (hndl != BAD_HANDLE)
|
||||
this->hndl = g_HandleSys.FastCloneHandle(hndl);
|
||||
else
|
||||
this->hndl = BAD_HANDLE;
|
||||
}
|
||||
|
||||
~AutoHandleRooter()
|
||||
{
|
||||
if (hndl != BAD_HANDLE)
|
||||
{
|
||||
HandleSecurity sec(g_pCoreIdent, g_pCoreIdent);
|
||||
g_HandleSys.FreeHandle(hndl, &sec);
|
||||
}
|
||||
}
|
||||
private:
|
||||
Handle_t hndl;
|
||||
};
|
||||
|
||||
#endif //_INCLUDE_SOURCEMOD_HANDLESYSTEM_H_
|
||||
|
@ -377,6 +377,9 @@ void BaseMenuStyle::ClientPressedKey(int client, unsigned int key_press)
|
||||
RemoveClientFromWatch(client);
|
||||
}
|
||||
|
||||
Handle_t hndl = menu->GetHandle();
|
||||
AutoHandleRooter ahr(hndl);
|
||||
|
||||
if (cancel)
|
||||
{
|
||||
mh->OnMenuCancel(menu, client, reason);
|
||||
|
Loading…
Reference in New Issue
Block a user