310 lines
5.7 KiB
C
310 lines
5.7 KiB
C
/*
|
|
* Process Hacker -
|
|
* internal object manager
|
|
*
|
|
* Copyright (C) 2009-2016 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 <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#ifndef _PH_REF_H
|
|
#define _PH_REF_H
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
// Configuration
|
|
|
|
#define PH_OBJECT_SMALL_OBJECT_SIZE 48
|
|
#define PH_OBJECT_SMALL_OBJECT_COUNT 512
|
|
|
|
// Object type flags
|
|
#define PH_OBJECT_TYPE_USE_FREE_LIST 0x00000001
|
|
#define PH_OBJECT_TYPE_VALID_FLAGS 0x00000001
|
|
|
|
// Object type callbacks
|
|
|
|
/**
|
|
* The delete procedure for an object type, called when an object of the type is being freed.
|
|
*
|
|
* \param Object A pointer to the object being freed.
|
|
* \param Flags Reserved.
|
|
*/
|
|
typedef VOID (NTAPI *PPH_TYPE_DELETE_PROCEDURE)(
|
|
_In_ PVOID Object,
|
|
_In_ ULONG Flags
|
|
);
|
|
|
|
struct _PH_OBJECT_TYPE;
|
|
typedef struct _PH_OBJECT_TYPE *PPH_OBJECT_TYPE;
|
|
|
|
struct _PH_QUEUED_LOCK;
|
|
typedef struct _PH_QUEUED_LOCK PH_QUEUED_LOCK, *PPH_QUEUED_LOCK;
|
|
|
|
#ifdef DEBUG
|
|
typedef VOID (NTAPI *PPH_CREATE_OBJECT_HOOK)(
|
|
_In_ PVOID Object,
|
|
_In_ SIZE_T Size,
|
|
_In_ ULONG Flags,
|
|
_In_ PPH_OBJECT_TYPE ObjectType
|
|
);
|
|
#endif
|
|
|
|
typedef struct _PH_OBJECT_TYPE_PARAMETERS
|
|
{
|
|
SIZE_T FreeListSize;
|
|
ULONG FreeListCount;
|
|
} PH_OBJECT_TYPE_PARAMETERS, *PPH_OBJECT_TYPE_PARAMETERS;
|
|
|
|
typedef struct _PH_OBJECT_TYPE_INFORMATION
|
|
{
|
|
PWSTR Name;
|
|
ULONG NumberOfObjects;
|
|
USHORT Flags;
|
|
UCHAR TypeIndex;
|
|
UCHAR Reserved;
|
|
} PH_OBJECT_TYPE_INFORMATION, *PPH_OBJECT_TYPE_INFORMATION;
|
|
|
|
extern PPH_OBJECT_TYPE PhObjectTypeObject;
|
|
extern PPH_OBJECT_TYPE PhAllocType;
|
|
|
|
#ifdef DEBUG
|
|
extern LIST_ENTRY PhDbgObjectListHead;
|
|
extern PH_QUEUED_LOCK PhDbgObjectListLock;
|
|
extern PPH_CREATE_OBJECT_HOOK PhDbgCreateObjectHook;
|
|
#endif
|
|
|
|
NTSTATUS PhRefInitialization(
|
|
VOID
|
|
);
|
|
|
|
_May_raise_
|
|
PHLIBAPI
|
|
PVOID
|
|
NTAPI
|
|
PhCreateObject(
|
|
_In_ SIZE_T ObjectSize,
|
|
_In_ PPH_OBJECT_TYPE ObjectType
|
|
);
|
|
|
|
PHLIBAPI
|
|
PVOID
|
|
NTAPI
|
|
PhReferenceObject(
|
|
_In_ PVOID Object
|
|
);
|
|
|
|
_May_raise_
|
|
PHLIBAPI
|
|
PVOID
|
|
NTAPI
|
|
PhReferenceObjectEx(
|
|
_In_ PVOID Object,
|
|
_In_ LONG RefCount
|
|
);
|
|
|
|
PHLIBAPI
|
|
PVOID
|
|
NTAPI
|
|
PhReferenceObjectSafe(
|
|
_In_ PVOID Object
|
|
);
|
|
|
|
PHLIBAPI
|
|
VOID
|
|
NTAPI
|
|
PhDereferenceObject(
|
|
_In_ PVOID Object
|
|
);
|
|
|
|
PHLIBAPI
|
|
VOID
|
|
NTAPI
|
|
PhDereferenceObjectDeferDelete(
|
|
_In_ PVOID Object
|
|
);
|
|
|
|
_May_raise_
|
|
PHLIBAPI
|
|
VOID
|
|
NTAPI
|
|
PhDereferenceObjectEx(
|
|
_In_ PVOID Object,
|
|
_In_ LONG RefCount,
|
|
_In_ BOOLEAN DeferDelete
|
|
);
|
|
|
|
PHLIBAPI
|
|
PPH_OBJECT_TYPE
|
|
NTAPI
|
|
PhGetObjectType(
|
|
_In_ PVOID Object
|
|
);
|
|
|
|
PHLIBAPI
|
|
PPH_OBJECT_TYPE
|
|
NTAPI
|
|
PhCreateObjectType(
|
|
_In_ PWSTR Name,
|
|
_In_ ULONG Flags,
|
|
_In_opt_ PPH_TYPE_DELETE_PROCEDURE DeleteProcedure
|
|
);
|
|
|
|
PHLIBAPI
|
|
PPH_OBJECT_TYPE
|
|
NTAPI
|
|
PhCreateObjectTypeEx(
|
|
_In_ PWSTR Name,
|
|
_In_ ULONG Flags,
|
|
_In_opt_ PPH_TYPE_DELETE_PROCEDURE DeleteProcedure,
|
|
_In_opt_ PPH_OBJECT_TYPE_PARAMETERS Parameters
|
|
);
|
|
|
|
PHLIBAPI
|
|
VOID
|
|
NTAPI
|
|
PhGetObjectTypeInformation(
|
|
_In_ PPH_OBJECT_TYPE ObjectType,
|
|
_Out_ PPH_OBJECT_TYPE_INFORMATION Information
|
|
);
|
|
|
|
PHLIBAPI
|
|
PVOID
|
|
NTAPI
|
|
PhCreateAlloc(
|
|
_In_ SIZE_T Size
|
|
);
|
|
|
|
// Object reference functions
|
|
|
|
FORCEINLINE
|
|
VOID
|
|
PhSwapReference(
|
|
_Inout_ PVOID *ObjectReference,
|
|
_In_opt_ PVOID NewObject
|
|
)
|
|
{
|
|
PVOID oldObject;
|
|
|
|
oldObject = *ObjectReference;
|
|
*ObjectReference = NewObject;
|
|
|
|
if (NewObject) PhReferenceObject(NewObject);
|
|
if (oldObject) PhDereferenceObject(oldObject);
|
|
}
|
|
|
|
FORCEINLINE
|
|
VOID
|
|
PhMoveReference(
|
|
_Inout_ PVOID *ObjectReference,
|
|
_In_opt_ _Assume_refs_(1) PVOID NewObject
|
|
)
|
|
{
|
|
PVOID oldObject;
|
|
|
|
oldObject = *ObjectReference;
|
|
*ObjectReference = NewObject;
|
|
|
|
if (oldObject) PhDereferenceObject(oldObject);
|
|
}
|
|
|
|
FORCEINLINE
|
|
VOID
|
|
PhSetReference(
|
|
_Out_ PVOID *ObjectReference,
|
|
_In_opt_ PVOID NewObject
|
|
)
|
|
{
|
|
*ObjectReference = NewObject;
|
|
|
|
if (NewObject) PhReferenceObject(NewObject);
|
|
}
|
|
|
|
FORCEINLINE
|
|
VOID
|
|
PhClearReference(
|
|
_Inout_ PVOID *ObjectReference
|
|
)
|
|
{
|
|
PhMoveReference(ObjectReference, NULL);
|
|
}
|
|
|
|
// Auto-dereference pool
|
|
|
|
/** The size of the static array in an auto-release pool. */
|
|
#define PH_AUTO_POOL_STATIC_SIZE 64
|
|
/** The maximum size of the dynamic array for it to be kept after the auto-release pool is drained. */
|
|
#define PH_AUTO_POOL_DYNAMIC_BIG_SIZE 256
|
|
|
|
/**
|
|
* An auto-dereference pool can be used for semi-automatic reference counting. Batches of objects
|
|
* are dereferenced at a certain time.
|
|
*
|
|
* This object is not thread-safe and cannot be used across thread boundaries. Always store them as
|
|
* local variables.
|
|
*/
|
|
typedef struct _PH_AUTO_POOL
|
|
{
|
|
ULONG StaticCount;
|
|
PVOID StaticObjects[PH_AUTO_POOL_STATIC_SIZE];
|
|
|
|
ULONG DynamicCount;
|
|
ULONG DynamicAllocated;
|
|
PVOID *DynamicObjects;
|
|
|
|
struct _PH_AUTO_POOL *NextPool;
|
|
} PH_AUTO_POOL, *PPH_AUTO_POOL;
|
|
|
|
PHLIBAPI
|
|
VOID
|
|
NTAPI
|
|
PhInitializeAutoPool(
|
|
_Out_ PPH_AUTO_POOL AutoPool
|
|
);
|
|
|
|
_May_raise_
|
|
PHLIBAPI
|
|
VOID
|
|
NTAPI
|
|
PhDeleteAutoPool(
|
|
_Inout_ PPH_AUTO_POOL AutoPool
|
|
);
|
|
|
|
PHLIBAPI
|
|
VOID
|
|
NTAPI
|
|
PhDrainAutoPool(
|
|
_In_ PPH_AUTO_POOL AutoPool
|
|
);
|
|
|
|
_May_raise_
|
|
PHLIBAPI
|
|
PVOID
|
|
NTAPI
|
|
PhAutoDereferenceObject(
|
|
_In_opt_ PVOID Object
|
|
);
|
|
|
|
#define PH_AUTO PhAutoDereferenceObject
|
|
#define PH_AUTO_T(Type, Object) ((Type *)PH_AUTO(Object))
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
|
|
#endif
|