148 lines
4.0 KiB
C
148 lines
4.0 KiB
C
#ifndef _PH_HANDLEP_H
|
|
#define _PH_HANDLEP_H
|
|
|
|
#define PH_HANDLE_TABLE_ENTRY_TYPE 0x1
|
|
#define PH_HANDLE_TABLE_ENTRY_IN_USE 0x0
|
|
#define PH_HANDLE_TABLE_ENTRY_FREE 0x1
|
|
|
|
// Locked actually means Not Locked. This means that an in use, locked handle table entry can be
|
|
// used as-is.
|
|
#define PH_HANDLE_TABLE_ENTRY_LOCKED 0x2
|
|
#define PH_HANDLE_TABLE_ENTRY_LOCKED_SHIFT 1
|
|
|
|
// There is initially one handle table level, with 256 entries. When the handle table is expanded,
|
|
// the table is replaced with a level 1 table, which contains 256 pointers to level 0 tables (the
|
|
// first entry already points to the initial level 0 table). Similarly, when the handle table is
|
|
// expanded a second time, the table is replaced with a level 2 table, which contains 256 pointers
|
|
// to level 1 tables.
|
|
//
|
|
// This provides a maximum of 16,777,216 handles.
|
|
|
|
#define PH_HANDLE_TABLE_LEVEL_ENTRIES 256
|
|
#define PH_HANDLE_TABLE_LEVEL_MASK 0x3
|
|
|
|
#define PH_HANDLE_TABLE_LOCKS 8
|
|
#define PH_HANDLE_TABLE_LOCK_INDEX(HandleValue) ((HandleValue) % PH_HANDLE_TABLE_LOCKS)
|
|
|
|
typedef struct _PH_HANDLE_TABLE
|
|
{
|
|
PH_QUEUED_LOCK Lock;
|
|
PH_WAKE_EVENT HandleWakeEvent;
|
|
|
|
ULONG Count;
|
|
ULONG_PTR TableValue;
|
|
ULONG FreeValue;
|
|
ULONG NextValue;
|
|
ULONG FreeValueAlt;
|
|
|
|
ULONG Flags;
|
|
|
|
PH_QUEUED_LOCK Locks[PH_HANDLE_TABLE_LOCKS];
|
|
} PH_HANDLE_TABLE, *PPH_HANDLE_TABLE;
|
|
|
|
FORCEINLINE VOID PhpLockHandleTableShared(
|
|
_Inout_ PPH_HANDLE_TABLE HandleTable,
|
|
_In_ ULONG Index
|
|
)
|
|
{
|
|
PhAcquireQueuedLockShared(&HandleTable->Locks[Index]);
|
|
}
|
|
|
|
FORCEINLINE VOID PhpUnlockHandleTableShared(
|
|
_Inout_ PPH_HANDLE_TABLE HandleTable,
|
|
_In_ ULONG Index
|
|
)
|
|
{
|
|
PhReleaseQueuedLockShared(&HandleTable->Locks[Index]);
|
|
}
|
|
|
|
// Handle values work by specifying indicies into each
|
|
// level.
|
|
//
|
|
// Bits 0-7: level 0
|
|
// Bits 8-15: level 1
|
|
// Bits 16-23: level 2
|
|
// Bits 24-31: reserved
|
|
|
|
#define PH_HANDLE_VALUE_INVALID ((ULONG)-1)
|
|
#define PH_HANDLE_VALUE_SHIFT 2
|
|
#define PH_HANDLE_VALUE_BIAS 4
|
|
|
|
#define PH_HANDLE_VALUE_LEVEL0(HandleValue) ((HandleValue) & 0xff)
|
|
#define PH_HANDLE_VALUE_LEVEL1_U(HandleValue) ((HandleValue) >> 8)
|
|
#define PH_HANDLE_VALUE_LEVEL1(HandleValue) (PH_HANDLE_VALUE_LEVEL1_U(HandleValue) & 0xff)
|
|
#define PH_HANDLE_VALUE_LEVEL2_U(HandleValue) ((HandleValue) >> 16)
|
|
#define PH_HANDLE_VALUE_LEVEL2(HandleValue) (PH_HANDLE_VALUE_LEVEL2_U(HandleValue) & 0xff)
|
|
#define PH_HANDLE_VALUE_IS_INVALID(HandleValue) (((HandleValue) >> 24) != 0)
|
|
|
|
FORCEINLINE HANDLE PhpEncodeHandle(
|
|
_In_ ULONG HandleValue
|
|
)
|
|
{
|
|
return UlongToHandle(((HandleValue << PH_HANDLE_VALUE_SHIFT) + PH_HANDLE_VALUE_BIAS));
|
|
}
|
|
|
|
FORCEINLINE ULONG PhpDecodeHandle(
|
|
_In_ HANDLE Handle
|
|
)
|
|
{
|
|
return (HandleToUlong(Handle) - PH_HANDLE_VALUE_BIAS) >> PH_HANDLE_VALUE_SHIFT;
|
|
}
|
|
|
|
VOID PhpBlockOnLockedHandleTableEntry(
|
|
_Inout_ PPH_HANDLE_TABLE HandleTable,
|
|
_In_ PPH_HANDLE_TABLE_ENTRY HandleTableEntry
|
|
);
|
|
|
|
PPH_HANDLE_TABLE_ENTRY PhpAllocateHandleTableEntry(
|
|
_Inout_ PPH_HANDLE_TABLE HandleTable,
|
|
_Out_ PULONG HandleValue
|
|
);
|
|
|
|
VOID PhpFreeHandleTableEntry(
|
|
_Inout_ PPH_HANDLE_TABLE HandleTable,
|
|
_In_ ULONG HandleValue,
|
|
_Inout_ PPH_HANDLE_TABLE_ENTRY HandleTableEntry
|
|
);
|
|
|
|
BOOLEAN PhpAllocateMoreHandleTableEntries(
|
|
_In_ PPH_HANDLE_TABLE HandleTable,
|
|
_In_ BOOLEAN Initialize
|
|
);
|
|
|
|
PPH_HANDLE_TABLE_ENTRY PhpLookupHandleTableEntry(
|
|
_In_ PPH_HANDLE_TABLE HandleTable,
|
|
_In_ ULONG HandleValue
|
|
);
|
|
|
|
ULONG PhpMoveFreeHandleTableEntries(
|
|
_Inout_ PPH_HANDLE_TABLE HandleTable
|
|
);
|
|
|
|
PPH_HANDLE_TABLE_ENTRY PhpCreateHandleTableLevel0(
|
|
_In_ PPH_HANDLE_TABLE HandleTable,
|
|
_In_ BOOLEAN Initialize
|
|
);
|
|
|
|
VOID PhpFreeHandleTableLevel0(
|
|
_In_ PPH_HANDLE_TABLE_ENTRY Table
|
|
);
|
|
|
|
PPH_HANDLE_TABLE_ENTRY *PhpCreateHandleTableLevel1(
|
|
_In_ PPH_HANDLE_TABLE HandleTable
|
|
);
|
|
|
|
VOID PhpFreeHandleTableLevel1(
|
|
_In_ PPH_HANDLE_TABLE_ENTRY *Table
|
|
);
|
|
|
|
PPH_HANDLE_TABLE_ENTRY **PhpCreateHandleTableLevel2(
|
|
_In_ PPH_HANDLE_TABLE HandleTable
|
|
);
|
|
|
|
VOID PhpFreeHandleTableLevel2(
|
|
_In_ PPH_HANDLE_TABLE_ENTRY **Table
|
|
);
|
|
|
|
#endif
|