/*
* 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;
}
}
}
}