/* * Process Hacker - * secured handle table * * Copyright (C) 2009 wj32 * * This file is part of Process Hacker. * * Process Hacker is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Process Hacker is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Process Hacker. If not, see . */ using System; namespace ProcessHacker.Common.Objects { public class SecuredHandleTableEntry : HandleTableEntry { private long _grantedAccess; public long GrantedAccess { get { return _grantedAccess; } set { _grantedAccess = value; } } public bool AreAllAccessesGranted(TAccess access) where TAccess : struct { long accessLong = Convert.ToInt64(access); if ((_grantedAccess & accessLong) == accessLong) return true; else return false; } public bool AreAnyAccessesGranted(TAccess access) where TAccess : struct { long accessLong = Convert.ToInt64(access); if ((_grantedAccess & accessLong) != 0) return true; else return false; } } /// /// Provides methods for managing handles to objects securely. /// public class SecuredHandleTable : SecuredHandleTable { } /// /// Provides methods for managing handles to objects securely. /// /// The type of each handle table entry. public class SecuredHandleTable : HandleTable where TEntry : SecuredHandleTableEntry, new() { /// /// Creates a handle to an object with the specified granted access. /// /// The type of access mask. /// The object to reference. /// The granted access to the object. /// The new handle. public int Allocate(IRefCounted obj, TAccess grantedAccess) where TAccess : struct { TEntry entry = new TEntry(); entry.GrantedAccess = Convert.ToInt64(grantedAccess); return base.Allocate(obj, entry); } /// /// References an object using a handle. /// /// The type of access mask. /// The handle to lookup. /// The desired access to the object. /// /// An object. This object has been referenced and must be /// dereferenced once it is no longer needed. /// public IRefCounted ReferenceByHandle(int handle, TAccess access) where TAccess : struct { return this.ReferenceByHandle(handle, access, false); } /// /// References an object using a handle. /// /// The type of access mask. /// The handle to lookup. /// The desired access to the object. /// /// Whether an exception will be thrown if access to the object is denied. /// /// /// An object. This object has been referenced and must be /// dereferenced once it is no longer needed. /// public IRefCounted ReferenceByHandle(int handle, TAccess access, bool throwOnAccessDenied) where TAccess : struct { TEntry entry; IRefCounted obj; // Reference the object. obj = this.ReferenceByHandle(handle, out entry); if (obj == null) return null; // Check the access. if (entry.AreAllAccessesGranted(access)) { // OK, return the object. return obj; } else { // Access denied. Dereference the object and return. obj.Dereference(); if (throwOnAccessDenied) throw new UnauthorizedAccessException("Access denied."); else return null; } } /// /// References an object using a handle. /// /// The type of the object to reference. /// The type of access mask. /// The handle to lookup. /// The desired access to the object. /// /// An object. This object has been referenced and must be /// dereferenced once it is no longer needed. /// public T ReferenceByHandle(int handle, TAccess access) where T : class, IRefCounted where TAccess : struct { return this.ReferenceByHandle(handle, access, false); } /// /// References an object using a handle. /// /// The type of the object to reference. /// The type of access mask. /// The handle to lookup. /// The desired access to the object. /// /// Whether an exception will be thrown if access to the object is denied. /// /// /// An object. This object has been referenced and must be /// dereferenced once it is no longer needed. /// public T ReferenceByHandle(int handle, TAccess access, bool throwOnAccessDenied) where T : class, IRefCounted where TAccess : struct { IRefCounted obj = this.ReferenceByHandle(handle, access, throwOnAccessDenied); if (obj == null) return null; // Check the type. if (obj is T) { return (T)obj; } else { obj.Dereference(); return null; } } } }