core/smn_handles.cpp
author David Anderson <dvander@alliedmods.net>
Fri Feb 16 04:16:31 2007 +0000 (2007-02-16)
changeset 502 4530ea065a8b
parent 370 d3a484f98f6d
child 536 164f7d3482ef
permissions -rw-r--r--
fixed a serious potential bug with swapping plugins to debug mode, leaving stale function pointers without plugin removal
     1 /**
     2  * ===============================================================
     3  * SourceMod (C)2004-2007 AlliedModders LLC.  All rights reserved.
     4  * ===============================================================
     5  *
     6  * This file is not open source and may not be copied without explicit
     7  * written permission of AlliedModders LLC.  This file may not be redistributed 
     8  * in whole or significant part.
     9  * For information, see LICENSE.txt or http://www.sourcemod.net/license.php
    10  *
    11  * Version: $Id$
    12  */
    13 
    14 #include "sm_globals.h"
    15 #include "HandleSys.h"
    16 #include "PluginSys.h"
    17 
    18 static cell_t sm_IsValidHandle(IPluginContext *pContext, const cell_t *params)
    19 {
    20 	Handle_t hndl = static_cast<Handle_t>(params[1]);
    21 
    22 	HandleError err = g_HandleSys.ReadHandle(hndl, 0, NULL, NULL);
    23 
    24 	if (err != HandleError_Access
    25 		&& err != HandleError_None)
    26 	{
    27 		return 0;
    28 	}
    29 
    30 	return 1;
    31 }
    32 
    33 static cell_t sm_CloseHandle(IPluginContext *pContext, const cell_t *params)
    34 {
    35 	Handle_t hndl = static_cast<Handle_t>(params[1]);
    36 	HandleSecurity sec;
    37 
    38 	sec.pIdentity = NULL;
    39 	sec.pOwner = pContext->GetIdentity();
    40 
    41 	HandleError err = g_HandleSys.FreeHandle(hndl, &sec);
    42   
    43 	if (err == HandleError_None)
    44 	{
    45 		return 1;
    46 	} else if (err == HandleError_Access) {
    47 		return 0;
    48 	} else {
    49 		return pContext->ThrowNativeError("Handle %x is invalid (error %d)", hndl, err);
    50 	}
    51 }
    52 
    53 static cell_t sm_CloneHandle(IPluginContext *pContext, const cell_t *params)
    54 {
    55 	Handle_t new_hndl;
    56 	Handle_t hndl = static_cast<Handle_t>(params[1]);
    57 	HandleError err;
    58 	IdentityToken_t *pNewOwner;
    59 	
    60 	if (params[2] == 0)
    61 	{
    62 		pNewOwner = pContext->GetIdentity();
    63 	} else {
    64 		Handle_t hPlugin = static_cast<Handle_t>(params[2]);
    65 		IPlugin *pPlugin = g_PluginSys.PluginFromHandle(hPlugin, &err);
    66 		if (!pPlugin)
    67 		{
    68 			return pContext->ThrowNativeError("Plugin handle %x is invalid (error %d)", hndl, err);
    69 		}
    70 		pNewOwner = pPlugin->GetIdentity();
    71 	}
    72 
    73 	err = g_HandleSys.CloneHandle(hndl, &new_hndl, pNewOwner, NULL);
    74 
    75 	if (err == HandleError_Access)
    76 	{
    77 		return 0;
    78 	} else if (err == HandleError_None) {
    79 		return new_hndl;
    80 	} else {
    81 		return pContext->ThrowNativeError("Handle %x cannot be cloned because it is invalid (error %d)", hndl, err);
    82 	}
    83 }
    84 
    85 REGISTER_NATIVES(handles)
    86 {
    87 	{"IsValidHandle",			sm_IsValidHandle},
    88 	{"CloseHandle",				sm_CloseHandle},
    89 	{"CloneHandle",				sm_CloneHandle},
    90 	{NULL,						NULL},
    91 };