go my file uploader

This commit is contained in:
AirDog46
2025-05-13 19:45:22 +03:00
commit c5fab8aa94
708 changed files with 343216 additions and 0 deletions

86
phlib/include/apiimport.h Normal file
View File

@@ -0,0 +1,86 @@
#ifndef _PH_APIIMPORT_H
#define _PH_APIIMPORT_H
// comctl32
typedef HRESULT (WINAPI *_TaskDialogIndirect)(
_In_ const struct _TASKDIALOGCONFIG *pTaskConfig,
_In_ int *pnButton,
_In_ int *pnRadioButton,
_In_ BOOL *pfVerificationFlagChecked
);
// ntdll
typedef NTSTATUS (NTAPI *_NtQueryInformationEnlistment)(
_In_ HANDLE EnlistmentHandle,
_In_ ENLISTMENT_INFORMATION_CLASS EnlistmentInformationClass,
_Out_writes_bytes_(EnlistmentInformationLength) PVOID EnlistmentInformation,
_In_ ULONG EnlistmentInformationLength,
_Out_opt_ PULONG ReturnLength
);
typedef NTSTATUS (NTAPI *_NtQueryInformationResourceManager)(
_In_ HANDLE ResourceManagerHandle,
_In_ RESOURCEMANAGER_INFORMATION_CLASS ResourceManagerInformationClass,
_Out_writes_bytes_(ResourceManagerInformationLength) PVOID ResourceManagerInformation,
_In_ ULONG ResourceManagerInformationLength,
_Out_opt_ PULONG ReturnLength
);
typedef NTSTATUS (NTAPI *_NtQueryInformationTransaction)(
_In_ HANDLE TransactionHandle,
_In_ TRANSACTION_INFORMATION_CLASS TransactionInformationClass,
_Out_writes_bytes_(TransactionInformationLength) PVOID TransactionInformation,
_In_ ULONG TransactionInformationLength,
_Out_opt_ PULONG ReturnLength
);
typedef NTSTATUS (NTAPI *_NtQueryInformationTransactionManager)(
_In_ HANDLE TransactionManagerHandle,
_In_ TRANSACTIONMANAGER_INFORMATION_CLASS TransactionManagerInformationClass,
_Out_writes_bytes_(TransactionManagerInformationLength) PVOID TransactionManagerInformation,
_In_ ULONG TransactionManagerInformationLength,
_Out_opt_ PULONG ReturnLength
);
// shell32
#if defined(_M_IX86)
#define __unaligned
#endif
typedef HRESULT (WINAPI *_SHCreateShellItem)(
_In_opt_ const struct _ITEMIDLIST __unaligned *pidlParent,
_In_opt_ struct IShellFolder *psfParent,
_In_ const struct _ITEMIDLIST __unaligned *pidl,
_Out_ struct IShellItem **ppsi
);
typedef HRESULT (WINAPI *_SHOpenFolderAndSelectItems)(
_In_ const struct _ITEMIDLIST __unaligned *pidlFolder,
_In_ UINT cidl,
_In_reads_opt_(cidl) const struct _ITEMIDLIST __unaligned **apidl,
_In_ DWORD dwFlags
);
typedef HRESULT (WINAPI *_SHParseDisplayName)(
_In_ LPCWSTR pszName,
_In_opt_ struct IBindCtx *pbc,
_Out_ const struct _ITEMIDLIST __unaligned **ppidl,
_In_ ULONG sfgaoIn,
_Out_ ULONG *psfgaoOut
);
#define PH_DECLARE_IMPORT(Name) _##Name Name##_Import(VOID)
PH_DECLARE_IMPORT(TaskDialogIndirect);
PH_DECLARE_IMPORT(NtQueryInformationEnlistment);
PH_DECLARE_IMPORT(NtQueryInformationResourceManager);
PH_DECLARE_IMPORT(NtQueryInformationTransaction);
PH_DECLARE_IMPORT(NtQueryInformationTransactionManager);
PH_DECLARE_IMPORT(SHCreateShellItem);
PH_DECLARE_IMPORT(SHOpenFolderAndSelectItems);
PH_DECLARE_IMPORT(SHParseDisplayName);
#endif

26
phlib/include/circbuf.h Normal file
View File

@@ -0,0 +1,26 @@
#ifndef _PH_CIRCBUF_H
#define _PH_CIRCBUF_H
#define PH_CIRCULAR_BUFFER_POWER_OF_TWO_SIZE
#undef T
#define T ULONG
#include "circbuf_h.h"
#undef T
#define T ULONG64
#include "circbuf_h.h"
#undef T
#define T PVOID
#include "circbuf_h.h"
#undef T
#define T SIZE_T
#include "circbuf_h.h"
#undef T
#define T FLOAT
#include "circbuf_h.h"
#endif

140
phlib/include/circbuf_h.h Normal file
View File

@@ -0,0 +1,140 @@
#ifdef T
#include <templ.h>
#ifdef __cplusplus
extern "C" {
#endif
typedef struct T___(_PH_CIRCULAR_BUFFER, T)
{
ULONG Size;
#ifdef PH_CIRCULAR_BUFFER_POWER_OF_TWO_SIZE
ULONG SizeMinusOne;
#endif
ULONG Count;
LONG Index;
T *Data;
} T___(PH_CIRCULAR_BUFFER, T), *T___(PPH_CIRCULAR_BUFFER, T);
PHLIBAPI
VOID
NTAPI
T___(PhInitializeCircularBuffer, T)(
_Out_ T___(PPH_CIRCULAR_BUFFER, T) Buffer,
_In_ ULONG Size
);
PHLIBAPI
VOID
NTAPI
T___(PhDeleteCircularBuffer, T)(
_Inout_ T___(PPH_CIRCULAR_BUFFER, T) Buffer
);
PHLIBAPI
VOID
NTAPI
T___(PhResizeCircularBuffer, T)(
_Inout_ T___(PPH_CIRCULAR_BUFFER, T) Buffer,
_In_ ULONG NewSize
);
PHLIBAPI
VOID
NTAPI
T___(PhClearCircularBuffer, T)(
_Inout_ T___(PPH_CIRCULAR_BUFFER, T) Buffer
);
PHLIBAPI
VOID
NTAPI
T___(PhCopyCircularBuffer, T)(
_Inout_ T___(PPH_CIRCULAR_BUFFER, T) Buffer,
_Out_writes_(Count) T *Destination,
_In_ ULONG Count
);
FORCEINLINE T T___(PhGetItemCircularBuffer, T)(
_In_ T___(PPH_CIRCULAR_BUFFER, T) Buffer,
_In_ LONG Index
)
{
#ifdef PH_CIRCULAR_BUFFER_POWER_OF_TWO_SIZE
return Buffer->Data[(Buffer->Index + Index) & Buffer->SizeMinusOne];
#else
ULONG size;
size = Buffer->Size;
// Modulo is dividend-based.
return Buffer->Data[(((Buffer->Index + Index) % size) + size) % size];
#endif
}
FORCEINLINE VOID T___(PhSetItemCircularBuffer, T)(
_Inout_ T___(PPH_CIRCULAR_BUFFER, T) Buffer,
_In_ LONG Index,
_In_ T Value
)
{
#ifdef PH_CIRCULAR_BUFFER_POWER_OF_TWO_SIZE
Buffer->Data[(Buffer->Index + Index) & Buffer->SizeMinusOne] = Value;
#else
ULONG size;
size = Buffer->Size;
Buffer->Data[(((Buffer->Index + Index) % size) + size) % size] = Value;
#endif
}
FORCEINLINE VOID T___(PhAddItemCircularBuffer, T)(
_Inout_ T___(PPH_CIRCULAR_BUFFER, T) Buffer,
_In_ T Value
)
{
#ifdef PH_CIRCULAR_BUFFER_POWER_OF_TWO_SIZE
Buffer->Data[Buffer->Index = ((Buffer->Index - 1) & Buffer->SizeMinusOne)] = Value;
#else
ULONG size;
size = Buffer->Size;
Buffer->Data[Buffer->Index = (((Buffer->Index - 1) % size) + size) % size] = Value;
#endif
if (Buffer->Count < Buffer->Size)
Buffer->Count++;
}
FORCEINLINE T T___(PhAddItemCircularBuffer2, T)(
_Inout_ T___(PPH_CIRCULAR_BUFFER, T) Buffer,
_In_ T Value
)
{
LONG index;
T oldValue;
#ifdef PH_CIRCULAR_BUFFER_POWER_OF_TWO_SIZE
index = ((Buffer->Index - 1) & Buffer->SizeMinusOne);
#else
ULONG size;
size = Buffer->Size;
index = (((Buffer->Index - 1) % size) + size) % size;
#endif
Buffer->Index = index;
oldValue = Buffer->Data[index];
Buffer->Data[index] = Value;
if (Buffer->Count < Buffer->Size)
Buffer->Count++;
return oldValue;
}
#ifdef __cplusplus
}
#endif
#endif

30
phlib/include/colorbox.h Normal file
View File

@@ -0,0 +1,30 @@
#ifndef _PH_COLORBOX_H
#define _PH_COLORBOX_H
#ifdef __cplusplus
extern "C" {
#endif
#define PH_COLORBOX_CLASSNAME L"PhColorBox"
PHLIBAPI
BOOLEAN
NTAPI
PhColorBoxInitialization(
VOID
);
#define CBCM_SETCOLOR (WM_APP + 1501)
#define CBCM_GETCOLOR (WM_APP + 1502)
#define ColorBox_SetColor(hWnd, Color) \
SendMessage((hWnd), CBCM_SETCOLOR, (WPARAM)(Color), 0)
#define ColorBox_GetColor(hWnd) \
((COLORREF)SendMessage((hWnd), CBCM_GETCOLOR, 0, 0))
#ifdef __cplusplus
}
#endif
#endif

78
phlib/include/cpysave.h Normal file
View File

@@ -0,0 +1,78 @@
#ifndef _PH_CPYSAVE_H
#define _PH_CPYSAVE_H
#ifdef __cplusplus
extern "C" {
#endif
#define PH_EXPORT_MODE_TABS 0
#define PH_EXPORT_MODE_SPACES 1
#define PH_EXPORT_MODE_CSV 2
PHLIBAPI
VOID PhaCreateTextTable(
_Out_ PPH_STRING ***Table,
_In_ ULONG Rows,
_In_ ULONG Columns
);
PHLIBAPI
PPH_LIST PhaFormatTextTable(
_In_ PPH_STRING **Table,
_In_ ULONG Rows,
_In_ ULONG Columns,
_In_ ULONG Mode
);
PHLIBAPI
VOID PhMapDisplayIndexTreeNew(
_In_ HWND TreeNewHandle,
_Out_opt_ PULONG *DisplayToId,
_Out_opt_ PWSTR **DisplayToText,
_Out_ PULONG NumberOfColumns
);
PHLIBAPI
PPH_STRING PhGetTreeNewText(
_In_ HWND TreeNewHandle,
_Reserved_ ULONG Reserved
);
PHLIBAPI
PPH_LIST PhGetGenericTreeNewLines(
_In_ HWND TreeNewHandle,
_In_ ULONG Mode
);
PHLIBAPI
VOID PhaMapDisplayIndexListView(
_In_ HWND ListViewHandle,
_Out_writes_(Count) PULONG DisplayToId,
_Out_writes_opt_(Count) PPH_STRING *DisplayToText,
_In_ ULONG Count,
_Out_ PULONG NumberOfColumns
);
PHLIBAPI
PPH_STRING PhaGetListViewItemText(
_In_ HWND ListViewHandle,
_In_ INT Index,
_In_ INT SubItemIndex
);
PHLIBAPI
PPH_STRING PhGetListViewText(
_In_ HWND ListViewHandle
);
PHLIBAPI
PPH_LIST PhGetListViewLines(
_In_ HWND ListViewHandle,
_In_ ULONG Mode
);
#ifdef __cplusplus
}
#endif
#endif

35
phlib/include/dltmgr.h Normal file
View File

@@ -0,0 +1,35 @@
#ifndef _PH_DLTMGR_H
#define _PH_DLTMGR_H
typedef struct _PH_SINGLE_DELTA
{
FLOAT Value;
FLOAT Delta;
} PH_SINGLE_DELTA, *PPH_SINGLE_DELTA;
typedef struct _PH_UINT32_DELTA
{
ULONG Value;
ULONG Delta;
} PH_UINT32_DELTA, *PPH_UINT32_DELTA;
typedef struct _PH_UINT64_DELTA
{
ULONG64 Value;
ULONG64 Delta;
} PH_UINT64_DELTA, *PPH_UINT64_DELTA;
typedef struct _PH_UINTPTR_DELTA
{
ULONG_PTR Value;
ULONG_PTR Delta;
} PH_UINTPTR_DELTA, *PPH_UINTPTR_DELTA;
#define PhInitializeDelta(DltMgr) \
((DltMgr)->Value = 0, (DltMgr)->Delta = 0)
#define PhUpdateDelta(DltMgr, NewValue) \
((DltMgr)->Delta = (NewValue) - (DltMgr)->Value, \
(DltMgr)->Value = (NewValue), (DltMgr)->Delta)
#endif

48
phlib/include/dspick.h Normal file
View File

@@ -0,0 +1,48 @@
#ifndef _PH_DSPICK_H
#define _PH_DSPICK_H
#ifdef __cplusplus
extern "C" {
#endif
#define PH_DSPICK_MULTISELECT 0x1
typedef struct _PH_DSPICK_OBJECT
{
PPH_STRING Name;
PSID Sid;
} PH_DSPICK_OBJECT, *PPH_DSPICK_OBJECT;
typedef struct _PH_DSPICK_OBJECTS
{
ULONG NumberOfObjects;
PH_DSPICK_OBJECT Objects[1];
} PH_DSPICK_OBJECTS, *PPH_DSPICK_OBJECTS;
PHLIBAPI
VOID PhFreeDsObjectPickerDialog(
_In_ PVOID PickerDialog
);
PHLIBAPI
PVOID PhCreateDsObjectPickerDialog(
_In_ ULONG Flags
);
PHLIBAPI
BOOLEAN PhShowDsObjectPickerDialog(
_In_ HWND hWnd,
_In_ PVOID PickerDialog,
_Out_ PPH_DSPICK_OBJECTS *Objects
);
PHLIBAPI
VOID PhFreeDsObjectPickerObjects(
_In_ PPH_DSPICK_OBJECTS Objects
);
#ifdef __cplusplus
}
#endif
#endif

219
phlib/include/emenu.h Normal file
View File

@@ -0,0 +1,219 @@
#ifndef _PH_EMENU_H
#define _PH_EMENU_H
#ifdef __cplusplus
extern "C" {
#endif
#define PH_EMENU_DISABLED 0x1
#define PH_EMENU_CHECKED 0x2
#define PH_EMENU_HIGHLIGHT 0x4
#define PH_EMENU_MENUBARBREAK 0x8
#define PH_EMENU_MENUBREAK 0x10
#define PH_EMENU_DEFAULT 0x20
#define PH_EMENU_MOUSESELECT 0x40
#define PH_EMENU_RADIOCHECK 0x80
#define PH_EMENU_SEPARATECHECKSPACE 0x100000
#define PH_EMENU_SEPARATOR 0x200000
#define PH_EMENU_TEXT_OWNED 0x80000000
#define PH_EMENU_BITMAP_OWNED 0x40000000
struct _PH_EMENU_ITEM;
typedef VOID (NTAPI *PPH_EMENU_ITEM_DELETE_FUNCTION)(
_In_ struct _PH_EMENU_ITEM *Item
);
typedef struct _PH_EMENU_ITEM
{
ULONG Flags;
ULONG Id;
PWSTR Text;
HBITMAP Bitmap;
PVOID Parameter;
PVOID Context;
PPH_EMENU_ITEM_DELETE_FUNCTION DeleteFunction;
PVOID Reserved;
struct _PH_EMENU_ITEM *Parent;
PPH_LIST Items;
} PH_EMENU_ITEM, *PPH_EMENU_ITEM;
typedef struct _PH_EMENU_ITEM PH_EMENU, *PPH_EMENU;
PHLIBAPI
PPH_EMENU_ITEM PhCreateEMenuItem(
_In_ ULONG Flags,
_In_ ULONG Id,
_In_ PWSTR Text,
_In_opt_ HBITMAP Bitmap,
_In_opt_ PVOID Context
);
PHLIBAPI
VOID PhDestroyEMenuItem(
_In_ PPH_EMENU_ITEM Item
);
#define PH_EMENU_FIND_DESCEND 0x1
#define PH_EMENU_FIND_STARTSWITH 0x2
#define PH_EMENU_FIND_LITERAL 0x4
PHLIBAPI
PPH_EMENU_ITEM PhFindEMenuItem(
_In_ PPH_EMENU_ITEM Item,
_In_ ULONG Flags,
_In_opt_ PWSTR Text,
_In_opt_ ULONG Id
);
PHLIBAPI
PPH_EMENU_ITEM PhFindEMenuItemEx(
_In_ PPH_EMENU_ITEM Item,
_In_ ULONG Flags,
_In_opt_ PWSTR Text,
_In_opt_ ULONG Id,
_Out_opt_ PPH_EMENU_ITEM *FoundParent,
_Out_opt_ PULONG FoundIndex
);
PHLIBAPI
ULONG PhIndexOfEMenuItem(
_In_ PPH_EMENU_ITEM Parent,
_In_ PPH_EMENU_ITEM Item
);
PHLIBAPI
VOID PhInsertEMenuItem(
_Inout_ PPH_EMENU_ITEM Parent,
_Inout_ PPH_EMENU_ITEM Item,
_In_ ULONG Index
);
PHLIBAPI
BOOLEAN PhRemoveEMenuItem(
_Inout_opt_ PPH_EMENU_ITEM Parent,
_In_opt_ PPH_EMENU_ITEM Item,
_In_opt_ ULONG Index
);
PHLIBAPI
VOID PhRemoveAllEMenuItems(
_Inout_ PPH_EMENU_ITEM Parent
);
PHLIBAPI
PPH_EMENU PhCreateEMenu(
VOID
);
PHLIBAPI
VOID PhDestroyEMenu(
_In_ PPH_EMENU Menu
);
#define PH_EMENU_CONVERT_ID 0x1
typedef struct _PH_EMENU_DATA
{
PPH_LIST IdToItem;
} PH_EMENU_DATA, *PPH_EMENU_DATA;
PHLIBAPI
VOID PhInitializeEMenuData(
_Out_ PPH_EMENU_DATA Data
);
PHLIBAPI
VOID PhDeleteEMenuData(
_Inout_ PPH_EMENU_DATA Data
);
PHLIBAPI
HMENU PhEMenuToHMenu(
_In_ PPH_EMENU_ITEM Menu,
_In_ ULONG Flags,
_Inout_opt_ PPH_EMENU_DATA Data
);
PHLIBAPI
VOID PhEMenuToHMenu2(
_In_ HMENU MenuHandle,
_In_ PPH_EMENU_ITEM Menu,
_In_ ULONG Flags,
_Inout_opt_ PPH_EMENU_DATA Data
);
PHLIBAPI
VOID PhHMenuToEMenuItem(
_Inout_ PPH_EMENU_ITEM MenuItem,
_In_ HMENU MenuHandle
);
PHLIBAPI
VOID PhLoadResourceEMenuItem(
_Inout_ PPH_EMENU_ITEM MenuItem,
_In_ HINSTANCE InstanceHandle,
_In_ PWSTR Resource,
_In_ ULONG SubMenuIndex
);
#define PH_EMENU_SHOW_SEND_COMMAND 0x1
#define PH_EMENU_SHOW_LEFTRIGHT 0x2
PHLIBAPI
PPH_EMENU_ITEM PhShowEMenu(
_In_ PPH_EMENU Menu,
_In_ HWND WindowHandle,
_In_ ULONG Flags,
_In_ ULONG Align,
_In_ ULONG X,
_In_ ULONG Y
);
// Convenience functions
PHLIBAPI
BOOLEAN PhSetFlagsEMenuItem(
_Inout_ PPH_EMENU_ITEM Item,
_In_ ULONG Id,
_In_ ULONG Mask,
_In_ ULONG Value
);
FORCEINLINE BOOLEAN PhEnableEMenuItem(
_Inout_ PPH_EMENU_ITEM Item,
_In_ ULONG Id,
_In_ BOOLEAN Enable
)
{
return PhSetFlagsEMenuItem(Item, Id, PH_EMENU_DISABLED, Enable ? 0 : PH_EMENU_DISABLED);
}
PHLIBAPI
VOID PhSetFlagsAllEMenuItems(
_In_ PPH_EMENU_ITEM Item,
_In_ ULONG Mask,
_In_ ULONG Value
);
#define PH_EMENU_MODIFY_TEXT 0x1
#define PH_EMENU_MODIFY_BITMAP 0x2
PHLIBAPI
VOID PhModifyEMenuItem(
_Inout_ PPH_EMENU_ITEM Item,
_In_ ULONG ModifyFlags,
_In_ ULONG OwnedFlags,
_In_opt_ PWSTR Text,
_In_opt_ HBITMAP Bitmap
);
#ifdef __cplusplus
}
#endif
#endif

93
phlib/include/fastlock.h Normal file
View File

@@ -0,0 +1,93 @@
#ifndef _PH_FASTLOCK_H
#define _PH_FASTLOCK_H
// FastLock is a port of FastResourceLock from PH 1.x.
#ifdef __cplusplus
extern "C" {
#endif
typedef struct _PH_FAST_LOCK
{
ULONG Value;
HANDLE ExclusiveWakeEvent;
HANDLE SharedWakeEvent;
} PH_FAST_LOCK, *PPH_FAST_LOCK;
#define PH_FAST_LOCK_INIT { 0, NULL, NULL }
PHLIBAPI
VOID
NTAPI
PhInitializeFastLock(
_Out_ PPH_FAST_LOCK FastLock
);
PHLIBAPI
VOID
NTAPI
PhDeleteFastLock(
_Inout_ PPH_FAST_LOCK FastLock
);
#define PhAcquireFastLockExclusive PhfAcquireFastLockExclusive
_May_raise_
_Acquires_exclusive_lock_(*FastLock)
PHLIBAPI
VOID
FASTCALL
PhfAcquireFastLockExclusive(
_Inout_ PPH_FAST_LOCK FastLock
);
#define PhAcquireFastLockShared PhfAcquireFastLockShared
_May_raise_
_Acquires_shared_lock_(*FastLock)
PHLIBAPI
VOID
FASTCALL
PhfAcquireFastLockShared(
_Inout_ PPH_FAST_LOCK FastLock
);
#define PhReleaseFastLockExclusive PhfReleaseFastLockExclusive
_Releases_exclusive_lock_(*FastLock)
PHLIBAPI
VOID
FASTCALL
PhfReleaseFastLockExclusive(
_Inout_ PPH_FAST_LOCK FastLock
);
#define PhReleaseFastLockShared PhfReleaseFastLockShared
_Releases_shared_lock_(*FastLock)
PHLIBAPI
VOID
FASTCALL
PhfReleaseFastLockShared(
_Inout_ PPH_FAST_LOCK FastLock
);
#define PhTryAcquireFastLockExclusive PhfTryAcquireFastLockExclusive
_When_(return != 0, _Acquires_exclusive_lock_(*FastLock))
PHLIBAPI
BOOLEAN
FASTCALL
PhfTryAcquireFastLockExclusive(
_Inout_ PPH_FAST_LOCK FastLock
);
#define PhTryAcquireFastLockShared PhfTryAcquireFastLockShared
_When_(return != 0, _Acquires_shared_lock_(*FastLock))
PHLIBAPI
BOOLEAN
FASTCALL
PhfTryAcquireFastLockShared(
_Inout_ PPH_FAST_LOCK FastLock
);
#ifdef __cplusplus
}
#endif
#endif

196
phlib/include/filepool.h Normal file
View File

@@ -0,0 +1,196 @@
#ifndef _PH_FILEPOOL_H
#define _PH_FILEPOOL_H
#ifdef __cplusplus
extern "C" {
#endif
// On-disk structures
// Each file has at least one segment. Each segment has a number of blocks, which are allocated from
// a bitmap. The segment header is always in the first block of each segment, except for the first
// segment. In the first segment, the file header is in the first few blocks, followed by the
// segment header.
//
// The segments are placed in a particular free list depending on how many blocks they have free;
// this allows allocators to simply skip the segments which don't have enough segments free, and
// allocate new segments if necessary. The free list does not however guarantee that a particular
// segment has a particular number of contiguous blocks free; low performance can still occur when
// there is fragmentation.
/** The number of 32-bit integers used for each allocation bitmap. */
#define PH_FP_BITMAP_SIZE 64
/** The power-of-two index of the bitmap size. */
#define PH_FP_BITMAP_SIZE_SHIFT 6
/** The number of blocks that are available in each segment. */
#define PH_FP_BLOCK_COUNT (PH_FP_BITMAP_SIZE * 32)
/** The power-of-two index of the block count. */
#define PH_FP_BLOCK_COUNT_SHIFT (PH_FP_BITMAP_SIZE_SHIFT + 5)
/** The number of free lists for segments. */
#define PH_FP_FREE_LIST_COUNT 8
// Block flags
/** The block is the beginning of a large allocation (one that spans several segments). */
#define PH_FP_BLOCK_LARGE_ALLOCATION 0x1
typedef struct _PH_FP_BLOCK_HEADER
{
ULONG Flags; // PH_FP_BLOCK_*
/** The number of blocks in the entire logical block, or the number
* of segments in a large allocation. */
ULONG Span;
ULONGLONG Body;
} PH_FP_BLOCK_HEADER, *PPH_FP_BLOCK_HEADER;
typedef struct _PH_FP_SEGMENT_HEADER
{
ULONG Bitmap[PH_FP_BITMAP_SIZE];
ULONG FreeBlocks;
ULONG FreeFlink;
ULONG FreeBlink;
ULONG Reserved[13];
} PH_FP_SEGMENT_HEADER, *PPH_FP_SEGMENT_HEADER;
#define PH_FP_MAGIC ('loPF')
typedef struct _PH_FP_FILE_HEADER
{
ULONG Magic;
ULONG SegmentShift;
ULONG SegmentCount;
ULONGLONG UserContext;
ULONG FreeLists[PH_FP_FREE_LIST_COUNT];
} PH_FP_FILE_HEADER, *PPH_FP_FILE_HEADER;
// Runtime
typedef struct _PH_FILE_POOL_PARAMETERS
{
// File options
/**
* The base-2 logarithm of the size of each segment. This value must be between 16 and 28,
* inclusive.
*/
ULONG SegmentShift;
// Runtime options
/** The maximum number of inactive segments to keep mapped. */
ULONG MaximumInactiveViews;
} PH_FILE_POOL_PARAMETERS, *PPH_FILE_POOL_PARAMETERS;
typedef struct _PH_FILE_POOL
{
HANDLE FileHandle;
HANDLE SectionHandle;
BOOLEAN ReadOnly;
PH_FREE_LIST ViewFreeList;
PLIST_ENTRY *ByIndexBuckets;
ULONG ByIndexSize;
PH_AVL_TREE ByBaseSet;
ULONG MaximumInactiveViews;
ULONG NumberOfInactiveViews;
LIST_ENTRY InactiveViewsListHead;
PPH_FP_BLOCK_HEADER FirstBlockOfFirstSegment;
PPH_FP_FILE_HEADER Header;
ULONG SegmentShift; // The power-of-two size of each segment
ULONG SegmentSize; // The size of each segment
ULONG BlockShift; // The power-of-two size of each block in each segment
ULONG BlockSize; // The size of each block in each segment
ULONG FileHeaderBlockSpan; // The number of blocks needed to store a file header
ULONG SegmentHeaderBlockSpan; // The number of blocks needed to store a segment header
} PH_FILE_POOL, *PPH_FILE_POOL;
PHLIBAPI
NTSTATUS PhCreateFilePool(
_Out_ PPH_FILE_POOL *Pool,
_In_ HANDLE FileHandle,
_In_ BOOLEAN ReadOnly,
_In_opt_ PPH_FILE_POOL_PARAMETERS Parameters
);
PHLIBAPI
NTSTATUS PhCreateFilePool2(
_Out_ PPH_FILE_POOL *Pool,
_In_ PWSTR FileName,
_In_ BOOLEAN ReadOnly,
_In_ ULONG ShareAccess,
_In_ ULONG CreateDisposition,
_In_opt_ PPH_FILE_POOL_PARAMETERS Parameters
);
PHLIBAPI
VOID PhDestroyFilePool(
_In_ _Post_invalid_ PPH_FILE_POOL Pool
);
PHLIBAPI
PVOID PhAllocateFilePool(
_Inout_ PPH_FILE_POOL Pool,
_In_ ULONG Size,
_Out_opt_ PULONG Rva
);
PHLIBAPI
VOID PhFreeFilePool(
_Inout_ PPH_FILE_POOL Pool,
_In_ PVOID Block
);
PHLIBAPI
BOOLEAN PhFreeFilePoolByRva(
_Inout_ PPH_FILE_POOL Pool,
_In_ ULONG Rva
);
PHLIBAPI
VOID PhReferenceFilePool(
_Inout_ PPH_FILE_POOL Pool,
_In_ PVOID Address
);
PHLIBAPI
VOID PhDereferenceFilePool(
_Inout_ PPH_FILE_POOL Pool,
_In_ PVOID Address
);
PHLIBAPI
PVOID PhReferenceFilePoolByRva(
_Inout_ PPH_FILE_POOL Pool,
_In_ ULONG Rva
);
PHLIBAPI
BOOLEAN PhDereferenceFilePoolByRva(
_Inout_ PPH_FILE_POOL Pool,
_In_ ULONG Rva
);
PHLIBAPI
ULONG PhEncodeRvaFilePool(
_In_ PPH_FILE_POOL Pool,
_In_ PVOID Address
);
PHLIBAPI
VOID PhGetUserContextFilePool(
_In_ PPH_FILE_POOL Pool,
_Out_ PULONGLONG Context
);
PHLIBAPI
VOID PhSetUserContextFilePool(
_Inout_ PPH_FILE_POOL Pool,
_In_ PULONGLONG Context
);
#ifdef __cplusplus
}
#endif
#endif

204
phlib/include/filepoolp.h Normal file
View File

@@ -0,0 +1,204 @@
#ifndef _PH_FILEPOOLP_H
#define _PH_FILEPOOLP_H
typedef struct _PH_FILE_POOL_VIEW
{
LIST_ENTRY ByIndexListEntry;
PH_AVL_LINKS ByBaseLinks;
LIST_ENTRY InactiveViewsListEntry;
ULONG RefCount;
ULONG SegmentIndex;
PVOID Base;
} PH_FILE_POOL_VIEW, *PPH_FILE_POOL_VIEW;
NTSTATUS PhpValidateFilePoolParameters(
_Inout_ PPH_FILE_POOL_PARAMETERS Parameters
);
VOID PhpSetDefaultFilePoolParameters(
_Out_ PPH_FILE_POOL_PARAMETERS Parameters
);
// Range mapping
NTSTATUS PhFppExtendRange(
_Inout_ PPH_FILE_POOL Pool,
_In_ ULONG NewSize
);
NTSTATUS PhFppMapRange(
_Inout_ PPH_FILE_POOL Pool,
_In_ ULONG Offset,
_In_ ULONG Size,
_Out_ PVOID *Base
);
NTSTATUS PhFppUnmapRange(
_Inout_ PPH_FILE_POOL Pool,
_In_ PVOID Base
);
// Segments
VOID PhFppInitializeSegment(
_Inout_ PPH_FILE_POOL Pool,
_Out_ PPH_FP_BLOCK_HEADER BlockOfSegmentHeader,
_In_ ULONG AdditionalBlocksUsed
);
PPH_FP_BLOCK_HEADER PhFppAllocateSegment(
_Inout_ PPH_FILE_POOL Pool,
_Out_ PULONG NewSegmentIndex
);
PPH_FP_SEGMENT_HEADER PhFppGetHeaderSegment(
_Inout_ PPH_FILE_POOL Pool,
_In_ PPH_FP_BLOCK_HEADER FirstBlock
);
// Views
VOID PhFppAddViewByIndex(
_Inout_ PPH_FILE_POOL Pool,
_Inout_ PPH_FILE_POOL_VIEW View
);
VOID PhFppRemoveViewByIndex(
_Inout_ PPH_FILE_POOL Pool,
_Inout_ PPH_FILE_POOL_VIEW View
);
PPH_FILE_POOL_VIEW PhFppFindViewByIndex(
_Inout_ PPH_FILE_POOL Pool,
_In_ ULONG SegmentIndex
);
LONG NTAPI PhpFilePoolViewByBaseCompareFunction(
_In_ PPH_AVL_LINKS Links1,
_In_ PPH_AVL_LINKS Links2
);
VOID PhFppAddViewByBase(
_Inout_ PPH_FILE_POOL Pool,
_Inout_ PPH_FILE_POOL_VIEW View
);
VOID PhFppRemoveViewByBase(
_Inout_ PPH_FILE_POOL Pool,
_Inout_ PPH_FILE_POOL_VIEW View
);
PPH_FILE_POOL_VIEW PhFppFindViewByBase(
_Inout_ PPH_FILE_POOL Pool,
_In_ PVOID Base
);
PPH_FILE_POOL_VIEW PhFppCreateView(
_Inout_ PPH_FILE_POOL Pool,
_In_ ULONG SegmentIndex
);
VOID PhFppDestroyView(
_Inout_ PPH_FILE_POOL Pool,
_Inout_ PPH_FILE_POOL_VIEW View
);
VOID PhFppActivateView(
_Inout_ PPH_FILE_POOL Pool,
_Inout_ PPH_FILE_POOL_VIEW View
);
VOID PhFppDeactivateView(
_Inout_ PPH_FILE_POOL Pool,
_Inout_ PPH_FILE_POOL_VIEW View
);
VOID PhFppReferenceView(
_Inout_ PPH_FILE_POOL Pool,
_Inout_ PPH_FILE_POOL_VIEW View
);
VOID PhFppDereferenceView(
_Inout_ PPH_FILE_POOL Pool,
_Inout_ PPH_FILE_POOL_VIEW View
);
PPH_FP_BLOCK_HEADER PhFppReferenceSegment(
_Inout_ PPH_FILE_POOL Pool,
_In_ ULONG SegmentIndex
);
VOID PhFppDereferenceSegment(
_Inout_ PPH_FILE_POOL Pool,
_In_ ULONG SegmentIndex
);
VOID PhFppReferenceSegmentByBase(
_Inout_ PPH_FILE_POOL Pool,
_In_ PVOID Base
);
VOID PhFppDereferenceSegmentByBase(
_Inout_ PPH_FILE_POOL Pool,
_In_ PVOID Base
);
// Bitmap allocation
PPH_FP_BLOCK_HEADER PhFppAllocateBlocks(
_Inout_ PPH_FILE_POOL Pool,
_In_ PPH_FP_BLOCK_HEADER FirstBlock,
_Inout_ PPH_FP_SEGMENT_HEADER SegmentHeader,
_In_ ULONG NumberOfBlocks
);
VOID PhFppFreeBlocks(
_Inout_ PPH_FILE_POOL Pool,
_In_ PPH_FP_BLOCK_HEADER FirstBlock,
_Inout_ PPH_FP_SEGMENT_HEADER SegmentHeader,
_In_ PPH_FP_BLOCK_HEADER BlockHeader
);
// Free list
ULONG PhFppComputeFreeListIndex(
_In_ PPH_FILE_POOL Pool,
_In_ ULONG NumberOfBlocks
);
BOOLEAN PhFppInsertFreeList(
_Inout_ PPH_FILE_POOL Pool,
_In_ ULONG FreeListIndex,
_In_ ULONG SegmentIndex,
_In_ PPH_FP_SEGMENT_HEADER SegmentHeader
);
BOOLEAN PhFppRemoveFreeList(
_Inout_ PPH_FILE_POOL Pool,
_In_ ULONG FreeListIndex,
_In_ ULONG SegmentIndex,
_In_ PPH_FP_SEGMENT_HEADER SegmentHeader
);
// Misc.
PPH_FP_BLOCK_HEADER PhFppGetHeaderBlock(
_In_ PPH_FILE_POOL Pool,
_In_ PVOID Block
);
ULONG PhFppEncodeRva(
_In_ PPH_FILE_POOL Pool,
_In_ ULONG SegmentIndex,
_In_ PPH_FP_BLOCK_HEADER FirstBlock,
_In_ PVOID Address
);
ULONG PhFppDecodeRva(
_In_ PPH_FILE_POOL Pool,
_In_ ULONG Rva,
_Out_ PULONG SegmentIndex
);
#endif

204
phlib/include/filestream.h Normal file
View File

@@ -0,0 +1,204 @@
#ifndef _PH_FILESTREAM_H
#define _PH_FILESTREAM_H
#ifdef __cplusplus
extern "C" {
#endif
// Core flags (PhCreateFileStream2)
/** Indicates that the file stream object should not close the file handle upon deletion. */
#define PH_FILE_STREAM_HANDLE_UNOWNED 0x1
/**
* Indicates that the file stream object should not buffer I/O operations. Note that this does not
* prevent the operating system from buffering I/O.
*/
#define PH_FILE_STREAM_UNBUFFERED 0x2
/**
* Indicates that the file handle supports asynchronous operations. The file handle must not have
* been opened with FILE_SYNCHRONOUS_IO_ALERT or FILE_SYNCHRONOUS_IO_NONALERT.
*/
#define PH_FILE_STREAM_ASYNCHRONOUS 0x4
/**
* Indicates that the file stream object should maintain the file position and not use the file
* object's own file position.
*/
#define PH_FILE_STREAM_OWN_POSITION 0x8
// Higher-level flags (PhCreateFileStream)
#define PH_FILE_STREAM_APPEND 0x00010000
// Internal flags
/** Indicates that at least one write has been issued to the file handle. */
#define PH_FILE_STREAM_WRITTEN 0x80000000
// Seek
typedef enum _PH_SEEK_ORIGIN
{
SeekStart,
SeekCurrent,
SeekEnd
} PH_SEEK_ORIGIN;
typedef struct _PH_FILE_STREAM
{
HANDLE FileHandle;
ULONG Flags;
LARGE_INTEGER Position; // file object position, *not* the actual position
PVOID Buffer;
ULONG BufferLength;
ULONG ReadPosition; // read position in buffer
ULONG ReadLength; // how much available to read from buffer
ULONG WritePosition; // write position in buffer
} PH_FILE_STREAM, *PPH_FILE_STREAM;
extern PPH_OBJECT_TYPE PhFileStreamType;
BOOLEAN
NTAPI
PhFileStreamInitialization(
VOID
);
PHLIBAPI
NTSTATUS
NTAPI
PhCreateFileStream(
_Out_ PPH_FILE_STREAM *FileStream,
_In_ PWSTR FileName,
_In_ ACCESS_MASK DesiredAccess,
_In_ ULONG ShareMode,
_In_ ULONG CreateDisposition,
_In_ ULONG Flags
);
PHLIBAPI
NTSTATUS
NTAPI
PhCreateFileStream2(
_Out_ PPH_FILE_STREAM *FileStream,
_In_ HANDLE FileHandle,
_In_ ULONG Flags,
_In_ ULONG BufferLength
);
PHLIBAPI
VOID
NTAPI
PhVerifyFileStream(
_In_ PPH_FILE_STREAM FileStream
);
PHLIBAPI
NTSTATUS
NTAPI
PhReadFileStream(
_Inout_ PPH_FILE_STREAM FileStream,
_Out_writes_bytes_(Length) PVOID Buffer,
_In_ ULONG Length,
_Out_opt_ PULONG ReadLength
);
PHLIBAPI
NTSTATUS
NTAPI
PhWriteFileStream(
_Inout_ PPH_FILE_STREAM FileStream,
_In_reads_bytes_(Length) PVOID Buffer,
_In_ ULONG Length
);
PHLIBAPI
NTSTATUS
NTAPI
PhFlushFileStream(
_Inout_ PPH_FILE_STREAM FileStream,
_In_ BOOLEAN Full
);
PHLIBAPI
VOID
NTAPI
PhGetPositionFileStream(
_In_ PPH_FILE_STREAM FileStream,
_Out_ PLARGE_INTEGER Position
);
PHLIBAPI
NTSTATUS
NTAPI
PhSeekFileStream(
_Inout_ PPH_FILE_STREAM FileStream,
_In_ PLARGE_INTEGER Offset,
_In_ PH_SEEK_ORIGIN Origin
);
PHLIBAPI
NTSTATUS
NTAPI
PhLockFileStream(
_Inout_ PPH_FILE_STREAM FileStream,
_In_ PLARGE_INTEGER Position,
_In_ PLARGE_INTEGER Length,
_In_ BOOLEAN Wait,
_In_ BOOLEAN Shared
);
PHLIBAPI
NTSTATUS
NTAPI
PhUnlockFileStream(
_Inout_ PPH_FILE_STREAM FileStream,
_In_ PLARGE_INTEGER Position,
_In_ PLARGE_INTEGER Length
);
PHLIBAPI
NTSTATUS
NTAPI
PhWriteStringAsUtf8FileStream(
_Inout_ PPH_FILE_STREAM FileStream,
_In_ PPH_STRINGREF String
);
PHLIBAPI
NTSTATUS
NTAPI
PhWriteStringAsUtf8FileStream2(
_Inout_ PPH_FILE_STREAM FileStream,
_In_ PWSTR String
);
PHLIBAPI
NTSTATUS
NTAPI
PhWriteStringAsUtf8FileStreamEx(
_Inout_ PPH_FILE_STREAM FileStream,
_In_ PWSTR Buffer,
_In_ SIZE_T Length
);
PHLIBAPI
NTSTATUS
NTAPI
PhWriteStringFormatAsUtf8FileStream_V(
_Inout_ PPH_FILE_STREAM FileStream,
_In_ _Printf_format_string_ PWSTR Format,
_In_ va_list ArgPtr
);
PHLIBAPI
NTSTATUS
NTAPI
PhWriteStringFormatAsUtf8FileStream(
_Inout_ PPH_FILE_STREAM FileStream,
_In_ _Printf_format_string_ PWSTR Format,
...
);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,40 @@
#ifndef _PH_FILESTREAMP_H
#define _PH_FILESTREAMP_H
VOID NTAPI PhpFileStreamDeleteProcedure(
_In_ PVOID Object,
_In_ ULONG Flags
);
NTSTATUS PhpAllocateBufferFileStream(
_Inout_ PPH_FILE_STREAM FileStream
);
NTSTATUS PhpReadFileStream(
_Inout_ PPH_FILE_STREAM FileStream,
_Out_writes_bytes_(Length) PVOID Buffer,
_In_ ULONG Length,
_Out_opt_ PULONG ReadLength
);
NTSTATUS PhpWriteFileStream(
_Inout_ PPH_FILE_STREAM FileStream,
_In_reads_bytes_(Length) PVOID Buffer,
_In_ ULONG Length
);
NTSTATUS PhpFlushReadFileStream(
_Inout_ PPH_FILE_STREAM FileStream
);
NTSTATUS PhpFlushWriteFileStream(
_Inout_ PPH_FILE_STREAM FileStream
);
NTSTATUS PhpSeekFileStream(
_Inout_ PPH_FILE_STREAM FileStream,
_In_ PLARGE_INTEGER Offset,
_In_ PH_SEEK_ORIGIN Origin
);
#endif

255
phlib/include/graph.h Normal file
View File

@@ -0,0 +1,255 @@
#ifndef _PH_GRAPH_H
#define _PH_GRAPH_H
#ifdef __cplusplus
extern "C" {
#endif
// Graph drawing
extern RECT PhNormalGraphTextMargin;
extern RECT PhNormalGraphTextPadding;
#define PH_GRAPH_USE_GRID_X 0x1
#define PH_GRAPH_USE_GRID_Y 0x2
#define PH_GRAPH_LOGARITHMIC_GRID_Y 0x4
#define PH_GRAPH_USE_LINE_2 0x10
#define PH_GRAPH_OVERLAY_LINE_2 0x20
#define PH_GRAPH_LABEL_MAX_Y 0x1000
typedef PPH_STRING (NTAPI *PPH_GRAPH_LABEL_Y_FUNCTION)(
_In_ struct _PH_GRAPH_DRAW_INFO *DrawInfo,
_In_ ULONG DataIndex,
_In_ FLOAT Value,
_In_ FLOAT Parameter
);
typedef struct _PH_GRAPH_DRAW_INFO
{
// Basic
ULONG Width;
ULONG Height;
ULONG Flags;
ULONG Step;
COLORREF BackColor;
// Data/lines
ULONG LineDataCount;
PFLOAT LineData1;
PFLOAT LineData2;
COLORREF LineColor1;
COLORREF LineColor2;
COLORREF LineBackColor1;
COLORREF LineBackColor2;
// Grid
COLORREF GridColor;
ULONG GridWidth;
FLOAT GridHeight;
ULONG GridXOffset;
ULONG GridYThreshold;
FLOAT GridBase; // Base for logarithmic grid
// y-axis label
PPH_GRAPH_LABEL_Y_FUNCTION LabelYFunction;
FLOAT LabelYFunctionParameter;
HFONT LabelYFont;
COLORREF LabelYColor;
ULONG LabelMaxYIndexLimit;
// Text
PH_STRINGREF Text;
RECT TextRect;
RECT TextBoxRect;
HFONT TextFont;
COLORREF TextColor;
COLORREF TextBoxColor;
} PH_GRAPH_DRAW_INFO, *PPH_GRAPH_DRAW_INFO;
// Graph control
#define PH_GRAPH_CLASSNAME L"PhGraph"
PHLIBAPI
BOOLEAN PhGraphControlInitialization(
VOID
);
PHLIBAPI
VOID PhDrawGraphDirect(
_In_ HDC hdc,
_In_ PVOID Bits,
_In_ PPH_GRAPH_DRAW_INFO DrawInfo
);
PHLIBAPI
VOID PhSetGraphText(
_In_ HDC hdc,
_Inout_ PPH_GRAPH_DRAW_INFO DrawInfo,
_In_ PPH_STRINGREF Text,
_In_ PRECT Margin,
_In_ PRECT Padding,
_In_ ULONG Align
);
// Configuration
typedef struct _PH_GRAPH_OPTIONS
{
COLORREF FadeOutBackColor;
ULONG FadeOutWidth;
HCURSOR DefaultCursor;
} PH_GRAPH_OPTIONS, *PPH_GRAPH_OPTIONS;
// Styles
#define GC_STYLE_FADEOUT 0x1
#define GC_STYLE_DRAW_PANEL 0x2
// Messages
#define GCM_GETDRAWINFO (WM_USER + 1301)
#define GCM_SETDRAWINFO (WM_USER + 1302)
#define GCM_DRAW (WM_USER + 1303)
#define GCM_MOVEGRID (WM_USER + 1304)
#define GCM_GETBUFFEREDCONTEXT (WM_USER + 1305)
#define GCM_SETTOOLTIP (WM_USER + 1306)
#define GCM_UPDATETOOLTIP (WM_USER + 1307)
#define GCM_GETOPTIONS (WM_USER + 1308)
#define GCM_SETOPTIONS (WM_USER + 1309)
#define Graph_GetDrawInfo(hWnd, DrawInfo) \
SendMessage((hWnd), GCM_GETDRAWINFO, 0, (LPARAM)(DrawInfo))
#define Graph_SetDrawInfo(hWnd, DrawInfo) \
SendMessage((hWnd), GCM_SETDRAWINFO, 0, (LPARAM)(DrawInfo))
#define Graph_Draw(hWnd) \
SendMessage((hWnd), GCM_DRAW, 0, 0)
#define Graph_MoveGrid(hWnd, Increment) \
SendMessage((hWnd), GCM_MOVEGRID, (WPARAM)(Increment), 0)
#define Graph_GetBufferedContext(hWnd) \
((HDC)SendMessage((hWnd), GCM_GETBUFFEREDCONTEXT, 0, 0))
#define Graph_SetTooltip(hWnd, Enable) \
((HDC)SendMessage((hWnd), GCM_SETTOOLTIP, (WPARAM)(Enable), 0))
#define Graph_UpdateTooltip(hWnd) \
((HDC)SendMessage((hWnd), GCM_UPDATETOOLTIP, 0, 0))
#define Graph_GetOptions(hWnd, Options) \
SendMessage((hWnd), GCM_GETOPTIONS, 0, (LPARAM)(Options))
#define Graph_SetOptions(hWnd, Options) \
SendMessage((hWnd), GCM_SETOPTIONS, 0, (LPARAM)(Options))
// Notifications
#define GCN_GETDRAWINFO (WM_USER + 1351)
#define GCN_GETTOOLTIPTEXT (WM_USER + 1352)
#define GCN_MOUSEEVENT (WM_USER + 1353)
#define GCN_DRAWPANEL (WM_USER + 1354)
typedef struct _PH_GRAPH_GETDRAWINFO
{
NMHDR Header;
PPH_GRAPH_DRAW_INFO DrawInfo;
} PH_GRAPH_GETDRAWINFO, *PPH_GRAPH_GETDRAWINFO;
typedef struct _PH_GRAPH_GETTOOLTIPTEXT
{
NMHDR Header;
ULONG Index;
ULONG TotalCount;
PH_STRINGREF Text; // must be null-terminated
} PH_GRAPH_GETTOOLTIPTEXT, *PPH_GRAPH_GETTOOLTIPTEXT;
typedef struct _PH_GRAPH_MOUSEEVENT
{
NMHDR Header;
ULONG Index;
ULONG TotalCount;
ULONG Message;
ULONG Keys;
POINT Point;
} PH_GRAPH_MOUSEEVENT, *PPH_GRAPH_MOUSEEVENT;
typedef struct _PH_GRAPH_DRAWPANEL
{
NMHDR Header;
HDC hdc;
RECT Rect;
} PH_GRAPH_DRAWPANEL, *PPH_GRAPH_DRAWPANEL;
// Graph buffer management
#define PH_GRAPH_DATA_COUNT(Width, Step) (((Width) + (Step) - 1) / (Step) + 1) // round up in division
typedef struct _PH_GRAPH_BUFFERS
{
PFLOAT Data1; // invalidate by setting Valid to FALSE
PFLOAT Data2; // invalidate by setting Valid to FALSE
ULONG AllocatedCount;
BOOLEAN Valid; // indicates the data is valid
} PH_GRAPH_BUFFERS, *PPH_GRAPH_BUFFERS;
PHLIBAPI
VOID PhInitializeGraphBuffers(
_Out_ PPH_GRAPH_BUFFERS Buffers
);
PHLIBAPI
VOID PhDeleteGraphBuffers(
_Inout_ PPH_GRAPH_BUFFERS Buffers
);
PHLIBAPI
VOID PhGetDrawInfoGraphBuffers(
_Inout_ PPH_GRAPH_BUFFERS Buffers,
_Inout_ PPH_GRAPH_DRAW_INFO DrawInfo,
_In_ ULONG DataCount
);
// Graph control state
// The basic buffer management structure was moved out of this section because
// the text management is not needed for most cases.
typedef struct _PH_GRAPH_STATE
{
// Union for compatibility
union
{
struct
{
PFLOAT Data1; // invalidate by setting Valid to FALSE
PFLOAT Data2; // invalidate by setting Valid to FALSE
ULONG AllocatedCount;
BOOLEAN Valid; // indicates the data is valid
};
PH_GRAPH_BUFFERS Buffers;
};
PPH_STRING Text;
PPH_STRING TooltipText; // invalidate by setting TooltipIndex to -1
ULONG TooltipIndex; // indicates the tooltip text is valid for this index
} PH_GRAPH_STATE, *PPH_GRAPH_STATE;
PHLIBAPI
VOID PhInitializeGraphState(
_Out_ PPH_GRAPH_STATE State
);
PHLIBAPI
VOID PhDeleteGraphState(
_Inout_ PPH_GRAPH_STATE State
);
PHLIBAPI
VOID PhGraphStateGetDrawInfo(
_Inout_ PPH_GRAPH_STATE State,
_In_ PPH_GRAPH_GETDRAWINFO GetDrawInfo,
_In_ ULONG DataCount
);
#ifdef __cplusplus
}
#endif
#endif

723
phlib/include/guisup.h Normal file
View File

@@ -0,0 +1,723 @@
#ifndef _PH_PHGUI_H
#define _PH_PHGUI_H
#pragma once
#include <commctrl.h>
#ifdef __cplusplus
extern "C" {
#endif
// guisup
typedef BOOL (WINAPI *_ChangeWindowMessageFilter)(
_In_ UINT message,
_In_ DWORD dwFlag
);
typedef BOOL (WINAPI *_IsImmersiveProcess)(
_In_ HANDLE hProcess
);
#define RFF_NOBROWSE 0x0001
#define RFF_NODEFAULT 0x0002
#define RFF_CALCDIRECTORY 0x0004
#define RFF_NOLABEL 0x0008
#define RFF_NOSEPARATEMEM 0x0020
#define RFN_VALIDATE (-510)
typedef struct _NMRUNFILEDLGW
{
NMHDR hdr;
LPCWSTR lpszFile;
LPCWSTR lpszDirectory;
UINT nShow;
} NMRUNFILEDLGW, *LPNMRUNFILEDLGW, *PNMRUNFILEDLGW;
typedef NMRUNFILEDLGW NMRUNFILEDLG;
typedef PNMRUNFILEDLGW PNMRUNFILEDLG;
typedef LPNMRUNFILEDLGW LPNMRUNFILEDLG;
#define RF_OK 0x0000
#define RF_CANCEL 0x0001
#define RF_RETRY 0x0002
typedef HANDLE HTHEME;
typedef BOOL (WINAPI *_RunFileDlg)(
_In_ HWND hwndOwner,
_In_opt_ HICON hIcon,
_In_opt_ LPCWSTR lpszDirectory,
_In_opt_ LPCWSTR lpszTitle,
_In_opt_ LPCWSTR lpszDescription,
_In_ ULONG uFlags
);
typedef HRESULT (WINAPI *_SHAutoComplete)(
_In_ HWND hwndEdit,
_In_ DWORD dwFlags
);
extern _ChangeWindowMessageFilter ChangeWindowMessageFilter_I;
extern _IsImmersiveProcess IsImmersiveProcess_I;
extern _RunFileDlg RunFileDlg;
extern _SHAutoComplete SHAutoComplete_I;
PHLIBAPI
VOID PhGuiSupportInitialization(
VOID
);
PHLIBAPI
VOID PhSetControlTheme(
_In_ HWND Handle,
_In_ PWSTR Theme
);
FORCEINLINE VOID PhSetWindowStyle(
_In_ HWND Handle,
_In_ LONG_PTR Mask,
_In_ LONG_PTR Value
)
{
LONG_PTR style;
style = GetWindowLongPtr(Handle, GWL_STYLE);
style = (style & ~Mask) | (Value & Mask);
SetWindowLongPtr(Handle, GWL_STYLE, style);
}
FORCEINLINE VOID PhSetWindowExStyle(
_In_ HWND Handle,
_In_ LONG_PTR Mask,
_In_ LONG_PTR Value
)
{
LONG_PTR style;
style = GetWindowLongPtr(Handle, GWL_EXSTYLE);
style = (style & ~Mask) | (Value & Mask);
SetWindowLongPtr(Handle, GWL_EXSTYLE, style);
}
#ifndef WM_REFLECT
#define WM_REFLECT 0x2000
#endif
#define REFLECT_MESSAGE(hwnd, msg, wParam, lParam) \
{ \
LRESULT result_ = PhReflectMessage(hwnd, msg, wParam, lParam); \
\
if (result_) \
return result_; \
}
#define REFLECT_MESSAGE_DLG(hwndDlg, hwnd, msg, wParam, lParam) \
{ \
LRESULT result_ = PhReflectMessage(hwnd, msg, wParam, lParam); \
\
if (result_) \
{ \
SetWindowLongPtr(hwndDlg, DWLP_MSGRESULT, result_); \
return TRUE; \
} \
}
FORCEINLINE LRESULT PhReflectMessage(
_In_ HWND Handle,
_In_ UINT Message,
_In_ WPARAM wParam,
_In_ LPARAM lParam
)
{
if (Message == WM_NOTIFY)
{
LPNMHDR header = (LPNMHDR)lParam;
if (header->hwndFrom == Handle)
return SendMessage(Handle, WM_REFLECT + Message, wParam, lParam);
}
return 0;
}
#define PH_DEFINE_MAKE_ATOM(AtomName) \
do { \
static UNICODE_STRING atomName = RTL_CONSTANT_STRING(AtomName); \
static PH_INITONCE initOnce = PH_INITONCE_INIT; \
static RTL_ATOM atom = 0; \
\
if (PhBeginInitOnce(&initOnce)) \
{ \
NtAddAtom(atomName.Buffer, atomName.Length, &atom); \
PhEndInitOnce(&initOnce); \
} \
\
if (atom) \
return (PWSTR)(ULONG_PTR)atom; \
else \
return atomName.Buffer; \
} while (0)
FORCEINLINE VOID PhSetListViewStyle(
_In_ HWND Handle,
_In_ BOOLEAN AllowDragDrop,
_In_ BOOLEAN ShowLabelTips
)
{
ULONG style;
style = LVS_EX_FULLROWSELECT | LVS_EX_DOUBLEBUFFER | LVS_EX_INFOTIP;
if (AllowDragDrop)
style |= LVS_EX_HEADERDRAGDROP;
if (ShowLabelTips)
style |= LVS_EX_LABELTIP;
ListView_SetExtendedListViewStyleEx(
Handle,
style,
-1
);
}
PHLIBAPI
INT PhAddListViewColumn(
_In_ HWND ListViewHandle,
_In_ INT Index,
_In_ INT DisplayIndex,
_In_ INT SubItemIndex,
_In_ INT Format,
_In_ INT Width,
_In_ PWSTR Text
);
PHLIBAPI
INT PhAddListViewItem(
_In_ HWND ListViewHandle,
_In_ INT Index,
_In_ PWSTR Text,
_In_opt_ PVOID Param
);
PHLIBAPI
INT PhFindListViewItemByFlags(
_In_ HWND ListViewHandle,
_In_ INT StartIndex,
_In_ ULONG Flags
);
PHLIBAPI
INT PhFindListViewItemByParam(
_In_ HWND ListViewHandle,
_In_ INT StartIndex,
_In_opt_ PVOID Param
);
PHLIBAPI
LOGICAL PhGetListViewItemImageIndex(
_In_ HWND ListViewHandle,
_In_ INT Index,
_Out_ PINT ImageIndex
);
PHLIBAPI
LOGICAL PhGetListViewItemParam(
_In_ HWND ListViewHandle,
_In_ INT Index,
_Out_ PVOID *Param
);
PHLIBAPI
VOID PhRemoveListViewItem(
_In_ HWND ListViewHandle,
_In_ INT Index
);
PHLIBAPI
VOID PhSetListViewItemImageIndex(
_In_ HWND ListViewHandle,
_In_ INT Index,
_In_ INT ImageIndex
);
PHLIBAPI
VOID PhSetListViewSubItem(
_In_ HWND ListViewHandle,
_In_ INT Index,
_In_ INT SubItemIndex,
_In_ PWSTR Text
);
PHLIBAPI
BOOLEAN PhLoadListViewColumnSettings(
_In_ HWND ListViewHandle,
_In_ PPH_STRING Settings
);
PHLIBAPI
PPH_STRING PhSaveListViewColumnSettings(
_In_ HWND ListViewHandle
);
PHLIBAPI
INT PhAddTabControlTab(
_In_ HWND TabControlHandle,
_In_ INT Index,
_In_ PWSTR Text
);
#define PhaGetDlgItemText(hwndDlg, id) \
PH_AUTO_T(PH_STRING, PhGetWindowText(GetDlgItem(hwndDlg, id)))
PHLIBAPI
PPH_STRING PhGetWindowText(
_In_ HWND hwnd
);
#define PH_GET_WINDOW_TEXT_INTERNAL 0x1
#define PH_GET_WINDOW_TEXT_LENGTH_ONLY 0x2
PHLIBAPI
ULONG PhGetWindowTextEx(
_In_ HWND hwnd,
_In_ ULONG Flags,
_Out_opt_ PPH_STRING *Text
);
PHLIBAPI
VOID PhAddComboBoxStrings(
_In_ HWND hWnd,
_In_ PWSTR *Strings,
_In_ ULONG NumberOfStrings
);
PHLIBAPI
PPH_STRING PhGetComboBoxString(
_In_ HWND hwnd,
_In_ INT Index
);
PHLIBAPI
INT PhSelectComboBoxString(
_In_ HWND hwnd,
_In_ PWSTR String,
_In_ BOOLEAN Partial
);
PHLIBAPI
PPH_STRING PhGetListBoxString(
_In_ HWND hwnd,
_In_ INT Index
);
PHLIBAPI
VOID PhSetStateAllListViewItems(
_In_ HWND hWnd,
_In_ ULONG State,
_In_ ULONG Mask
);
PHLIBAPI
PVOID PhGetSelectedListViewItemParam(
_In_ HWND hWnd
);
PHLIBAPI
VOID PhGetSelectedListViewItemParams(
_In_ HWND hWnd,
_Out_ PVOID **Items,
_Out_ PULONG NumberOfItems
);
PHLIBAPI
VOID PhSetImageListBitmap(
_In_ HIMAGELIST ImageList,
_In_ INT Index,
_In_ HINSTANCE InstanceHandle,
_In_ LPCWSTR BitmapName
);
#define PH_LOAD_ICON_SHARED 0x1
#define PH_LOAD_ICON_SIZE_SMALL 0x2
#define PH_LOAD_ICON_SIZE_LARGE 0x4
#define PH_LOAD_ICON_STRICT 0x8
PHLIBAPI
HICON PhLoadIcon(
_In_opt_ HINSTANCE InstanceHandle,
_In_ PWSTR Name,
_In_ ULONG Flags,
_In_opt_ ULONG Width,
_In_opt_ ULONG Height
);
PHLIBAPI
VOID PhGetStockApplicationIcon(
_Out_opt_ HICON *SmallIcon,
_Out_opt_ HICON *LargeIcon
);
PHLIBAPI
HICON PhGetFileShellIcon(
_In_opt_ PWSTR FileName,
_In_opt_ PWSTR DefaultExtension,
_In_ BOOLEAN LargeIcon
);
PHLIBAPI
VOID PhSetClipboardString(
_In_ HWND hWnd,
_In_ PPH_STRINGREF String
);
typedef struct _DLGTEMPLATEEX
{
WORD dlgVer;
WORD signature;
DWORD helpID;
DWORD exStyle;
DWORD style;
WORD cDlgItems;
short x;
short y;
short cx;
short cy;
} DLGTEMPLATEEX, *PDLGTEMPLATEEX;
PHLIBAPI
HWND PhCreateDialogFromTemplate(
_In_ HWND Parent,
_In_ ULONG Style,
_In_ PVOID Instance,
_In_ PWSTR Template,
_In_ DLGPROC DialogProc,
_In_ PVOID Parameter
);
PHLIBAPI
BOOLEAN PhModalPropertySheet(
_Inout_ PROPSHEETHEADER *Header
);
#define PH_ANCHOR_LEFT 0x1
#define PH_ANCHOR_TOP 0x2
#define PH_ANCHOR_RIGHT 0x4
#define PH_ANCHOR_BOTTOM 0x8
#define PH_ANCHOR_ALL 0xf
// This interface is horrible and should be rewritten, but it works for now.
#define PH_LAYOUT_FORCE_INVALIDATE 0x1000 // invalidate the control when it is resized
#define PH_LAYOUT_TAB_CONTROL 0x2000 // this is a dummy item, a hack for the tab control
#define PH_LAYOUT_IMMEDIATE_RESIZE 0x4000 // needed for the tab control hack
#define PH_LAYOUT_DUMMY_MASK (PH_LAYOUT_TAB_CONTROL) // items that don't have a window handle, or don't actually get their window resized
typedef struct _PH_LAYOUT_ITEM
{
HWND Handle;
struct _PH_LAYOUT_ITEM *ParentItem; // for rectangle calculation
struct _PH_LAYOUT_ITEM *LayoutParentItem; // for actual resizing
ULONG LayoutNumber;
ULONG NumberOfChildren;
HDWP DeferHandle;
RECT Rect;
RECT OrigRect;
RECT Margin;
ULONG Anchor;
} PH_LAYOUT_ITEM, *PPH_LAYOUT_ITEM;
typedef struct _PH_LAYOUT_MANAGER
{
PPH_LIST List;
PH_LAYOUT_ITEM RootItem;
ULONG LayoutNumber;
} PH_LAYOUT_MANAGER, *PPH_LAYOUT_MANAGER;
PHLIBAPI
VOID PhInitializeLayoutManager(
_Out_ PPH_LAYOUT_MANAGER Manager,
_In_ HWND RootWindowHandle
);
PHLIBAPI
VOID PhDeleteLayoutManager(
_Inout_ PPH_LAYOUT_MANAGER Manager
);
PHLIBAPI
PPH_LAYOUT_ITEM PhAddLayoutItem(
_Inout_ PPH_LAYOUT_MANAGER Manager,
_In_ HWND Handle,
_In_opt_ PPH_LAYOUT_ITEM ParentItem,
_In_ ULONG Anchor
);
PHLIBAPI
PPH_LAYOUT_ITEM PhAddLayoutItemEx(
_Inout_ PPH_LAYOUT_MANAGER Manager,
_In_ HWND Handle,
_In_opt_ PPH_LAYOUT_ITEM ParentItem,
_In_ ULONG Anchor,
_In_ RECT Margin
);
PHLIBAPI
VOID PhLayoutManagerLayout(
_Inout_ PPH_LAYOUT_MANAGER Manager
);
FORCEINLINE VOID PhResizingMinimumSize(
_Inout_ PRECT Rect,
_In_ WPARAM Edge,
_In_ LONG MinimumWidth,
_In_ LONG MinimumHeight
)
{
if (Edge == WMSZ_BOTTOMRIGHT || Edge == WMSZ_RIGHT || Edge == WMSZ_TOPRIGHT)
{
if (Rect->right - Rect->left < MinimumWidth)
Rect->right = Rect->left + MinimumWidth;
}
else if (Edge == WMSZ_BOTTOMLEFT || Edge == WMSZ_LEFT || Edge == WMSZ_TOPLEFT)
{
if (Rect->right - Rect->left < MinimumWidth)
Rect->left = Rect->right - MinimumWidth;
}
if (Edge == WMSZ_BOTTOMRIGHT || Edge == WMSZ_BOTTOM || Edge == WMSZ_BOTTOMLEFT)
{
if (Rect->bottom - Rect->top < MinimumHeight)
Rect->bottom = Rect->top + MinimumHeight;
}
else if (Edge == WMSZ_TOPRIGHT || Edge == WMSZ_TOP || Edge == WMSZ_TOPLEFT)
{
if (Rect->bottom - Rect->top < MinimumHeight)
Rect->top = Rect->bottom - MinimumHeight;
}
}
FORCEINLINE VOID PhCopyControlRectangle(
_In_ HWND ParentWindowHandle,
_In_ HWND FromControlHandle,
_In_ HWND ToControlHandle
)
{
RECT windowRect;
GetWindowRect(FromControlHandle, &windowRect);
MapWindowPoints(NULL, ParentWindowHandle, (POINT *)&windowRect, 2);
MoveWindow(ToControlHandle, windowRect.left, windowRect.top,
windowRect.right - windowRect.left, windowRect.bottom - windowRect.top, FALSE);
}
// icotobmp
PHLIBAPI
HBITMAP
NTAPI
PhIconToBitmap(
_In_ HICON Icon,
_In_ ULONG Width,
_In_ ULONG Height
);
// extlv
#define PH_ALIGN_CENTER 0x0
#define PH_ALIGN_LEFT 0x1
#define PH_ALIGN_RIGHT 0x2
#define PH_ALIGN_TOP 0x4
#define PH_ALIGN_BOTTOM 0x8
typedef enum _PH_ITEM_STATE
{
// The item is normal. Use the ItemColorFunction to determine the color of the item.
NormalItemState = 0,
// The item is new. On the next tick, change the state to NormalItemState. When an item is in
// this state, highlight it in NewColor.
NewItemState,
// The item is being removed. On the next tick, delete the item. When an item is in this state,
// highlight it in RemovingColor.
RemovingItemState
} PH_ITEM_STATE;
typedef COLORREF (NTAPI *PPH_EXTLV_GET_ITEM_COLOR)(
_In_ INT Index,
_In_ PVOID Param,
_In_opt_ PVOID Context
);
typedef HFONT (NTAPI *PPH_EXTLV_GET_ITEM_FONT)(
_In_ INT Index,
_In_ PVOID Param,
_In_opt_ PVOID Context
);
PHLIBAPI
VOID
NTAPI
PhSetExtendedListView(
_In_ HWND hWnd
);
PHLIBAPI
VOID
NTAPI
PhSetHeaderSortIcon(
_In_ HWND hwnd,
_In_ INT Index,
_In_ PH_SORT_ORDER Order
);
// next 1122
#define ELVM_ADDFALLBACKCOLUMN (WM_APP + 1106)
#define ELVM_ADDFALLBACKCOLUMNS (WM_APP + 1109)
#define ELVM_RESERVED5 (WM_APP + 1120)
#define ELVM_INIT (WM_APP + 1102)
#define ELVM_SETCOLUMNWIDTH (WM_APP + 1121)
#define ELVM_SETCOMPAREFUNCTION (WM_APP + 1104)
#define ELVM_SETCONTEXT (WM_APP + 1103)
#define ELVM_SETCURSOR (WM_APP + 1114)
#define ELVM_RESERVED4 (WM_APP + 1118)
#define ELVM_SETITEMCOLORFUNCTION (WM_APP + 1111)
#define ELVM_SETITEMFONTFUNCTION (WM_APP + 1117)
#define ELVM_RESERVED1 (WM_APP + 1112)
#define ELVM_SETREDRAW (WM_APP + 1116)
#define ELVM_RESERVED2 (WM_APP + 1113)
#define ELVM_SETSORT (WM_APP + 1108)
#define ELVM_SETSORTFAST (WM_APP + 1119)
#define ELVM_RESERVED0 (WM_APP + 1110)
#define ELVM_SETTRISTATE (WM_APP + 1107)
#define ELVM_SETTRISTATECOMPAREFUNCTION (WM_APP + 1105)
#define ELVM_SORTITEMS (WM_APP + 1101)
#define ELVM_RESERVED3 (WM_APP + 1115)
#define ExtendedListView_AddFallbackColumn(hWnd, Column) \
SendMessage((hWnd), ELVM_ADDFALLBACKCOLUMN, (WPARAM)(Column), 0)
#define ExtendedListView_AddFallbackColumns(hWnd, NumberOfColumns, Columns) \
SendMessage((hWnd), ELVM_ADDFALLBACKCOLUMNS, (WPARAM)(NumberOfColumns), (LPARAM)(Columns))
#define ExtendedListView_Init(hWnd) \
SendMessage((hWnd), ELVM_INIT, 0, 0)
#define ExtendedListView_SetColumnWidth(hWnd, Column, Width) \
SendMessage((hWnd), ELVM_SETCOLUMNWIDTH, (WPARAM)(Column), (LPARAM)(Width))
#define ExtendedListView_SetCompareFunction(hWnd, Column, CompareFunction) \
SendMessage((hWnd), ELVM_SETCOMPAREFUNCTION, (WPARAM)(Column), (LPARAM)(CompareFunction))
#define ExtendedListView_SetContext(hWnd, Context) \
SendMessage((hWnd), ELVM_SETCONTEXT, 0, (LPARAM)(Context))
#define ExtendedListView_SetCursor(hWnd, Cursor) \
SendMessage((hWnd), ELVM_SETCURSOR, 0, (LPARAM)(Cursor))
#define ExtendedListView_SetItemColorFunction(hWnd, ItemColorFunction) \
SendMessage((hWnd), ELVM_SETITEMCOLORFUNCTION, 0, (LPARAM)(ItemColorFunction))
#define ExtendedListView_SetItemFontFunction(hWnd, ItemFontFunction) \
SendMessage((hWnd), ELVM_SETITEMFONTFUNCTION, 0, (LPARAM)(ItemFontFunction))
#define ExtendedListView_SetRedraw(hWnd, Redraw) \
SendMessage((hWnd), ELVM_SETREDRAW, (WPARAM)(Redraw), 0)
#define ExtendedListView_SetSort(hWnd, Column, Order) \
SendMessage((hWnd), ELVM_SETSORT, (WPARAM)(Column), (LPARAM)(Order))
#define ExtendedListView_SetSortFast(hWnd, Fast) \
SendMessage((hWnd), ELVM_SETSORTFAST, (WPARAM)(Fast), 0)
#define ExtendedListView_SetTriState(hWnd, TriState) \
SendMessage((hWnd), ELVM_SETTRISTATE, (WPARAM)(TriState), 0)
#define ExtendedListView_SetTriStateCompareFunction(hWnd, CompareFunction) \
SendMessage((hWnd), ELVM_SETTRISTATECOMPAREFUNCTION, 0, (LPARAM)(CompareFunction))
#define ExtendedListView_SortItems(hWnd) \
SendMessage((hWnd), ELVM_SORTITEMS, 0, 0)
#define ELVSCW_AUTOSIZE (-1)
#define ELVSCW_AUTOSIZE_USEHEADER (-2)
#define ELVSCW_AUTOSIZE_REMAININGSPACE (-3)
/**
* Gets the brightness of a color.
*
* \param Color The color.
*
* \return A value ranging from 0 to 255, indicating the brightness of the color.
*/
FORCEINLINE
ULONG
PhGetColorBrightness(
_In_ COLORREF Color
)
{
ULONG r = Color & 0xff;
ULONG g = (Color >> 8) & 0xff;
ULONG b = (Color >> 16) & 0xff;
ULONG min;
ULONG max;
min = r;
if (g < min) min = g;
if (b < min) min = b;
max = r;
if (g > max) max = g;
if (b > max) max = b;
return (min + max) / 2;
}
FORCEINLINE
COLORREF
PhHalveColorBrightness(
_In_ COLORREF Color
)
{
/*return RGB(
(UCHAR)Color / 2,
(UCHAR)(Color >> 8) / 2,
(UCHAR)(Color >> 16) / 2
);*/
// Since all targets are little-endian, we can use the following method.
*((PUCHAR)&Color) /= 2;
*((PUCHAR)&Color + 1) /= 2;
*((PUCHAR)&Color + 2) /= 2;
return Color;
}
FORCEINLINE
COLORREF
PhMakeColorBrighter(
_In_ COLORREF Color,
_In_ UCHAR Increment
)
{
UCHAR r;
UCHAR g;
UCHAR b;
r = (UCHAR)Color;
g = (UCHAR)(Color >> 8);
b = (UCHAR)(Color >> 16);
if (r <= 255 - Increment)
r += Increment;
else
r = 255;
if (g <= 255 - Increment)
g += Increment;
else
g = 255;
if (b <= 255 - Increment)
b += Increment;
else
b = 255;
return RGB(r, g, b);
}
#ifdef __cplusplus
}
#endif
#endif

43
phlib/include/guisupp.h Normal file
View File

@@ -0,0 +1,43 @@
#ifndef _PH_GUISUPP_H
#define _PH_GUISUPP_H
typedef HRESULT (WINAPI *_LoadIconMetric)(
_In_ HINSTANCE hinst,
_In_ PCWSTR pszName,
_In_ int lims,
_Out_ HICON *phico
);
typedef HRESULT (WINAPI *_LoadIconWithScaleDown)(
_In_ HINSTANCE hinst,
_In_ PCWSTR pszName,
_In_ int cx,
_In_ int cy,
_Out_ HICON *phico
);
typedef struct _PHP_ICON_ENTRY
{
HINSTANCE InstanceHandle;
PWSTR Name;
ULONG Width;
ULONG Height;
HICON Icon;
} PHP_ICON_ENTRY, *PPHP_ICON_ENTRY;
#define PHP_ICON_ENTRY_SIZE_SMALL (-1)
#define PHP_ICON_ENTRY_SIZE_LARGE (-2)
FORCEINLINE ULONG PhpGetIconEntrySize(
_In_ ULONG InputSize,
_In_ ULONG Flags
)
{
if (Flags & PH_LOAD_ICON_SIZE_SMALL)
return PHP_ICON_ENTRY_SIZE_SMALL;
if (Flags & PH_LOAD_ICON_SIZE_LARGE)
return PHP_ICON_ENTRY_SIZE_LARGE;
return InputSize;
}
#endif

167
phlib/include/handle.h Normal file
View File

@@ -0,0 +1,167 @@
#ifndef _PH_HANDLE_H
#define _PH_HANDLE_H
#ifdef __cplusplus
extern "C" {
#endif
struct _PH_HANDLE_TABLE;
typedef struct _PH_HANDLE_TABLE *PPH_HANDLE_TABLE;
typedef struct _PH_HANDLE_TABLE_ENTRY
{
union
{
PVOID Object;
ULONG_PTR Value;
struct
{
/** The type of the entry; 1 if the entry is free, otherwise 0 if the entry is in use. */
ULONG_PTR Type : 1;
/**
* Whether the entry is not locked; 1 if the entry is not locked, otherwise 0 if the
* entry is locked.
*/
ULONG_PTR Locked : 1;
ULONG_PTR Value : sizeof(ULONG_PTR) * 8 - 2;
} TypeAndValue;
};
union
{
ACCESS_MASK GrantedAccess;
ULONG NextFreeValue;
ULONG_PTR Value2;
};
} PH_HANDLE_TABLE_ENTRY, *PPH_HANDLE_TABLE_ENTRY;
#define PH_HANDLE_TABLE_SAFE
#define PH_HANDLE_TABLE_FREE_COUNT 64
#define PH_HANDLE_TABLE_STRICT_FIFO 0x1
#define PH_HANDLE_TABLE_VALID_FLAGS 0x1
PHLIBAPI
PPH_HANDLE_TABLE
NTAPI
PhCreateHandleTable(
VOID
);
PHLIBAPI
VOID
NTAPI
PhDestroyHandleTable(
_In_ _Post_invalid_ PPH_HANDLE_TABLE HandleTable
);
PHLIBAPI
BOOLEAN
NTAPI
PhLockHandleTableEntry(
_Inout_ PPH_HANDLE_TABLE HandleTable,
_Inout_ PPH_HANDLE_TABLE_ENTRY HandleTableEntry
);
PHLIBAPI
VOID
NTAPI
PhUnlockHandleTableEntry(
_Inout_ PPH_HANDLE_TABLE HandleTable,
_Inout_ PPH_HANDLE_TABLE_ENTRY HandleTableEntry
);
PHLIBAPI
HANDLE
NTAPI
PhCreateHandle(
_Inout_ PPH_HANDLE_TABLE HandleTable,
_In_ PPH_HANDLE_TABLE_ENTRY HandleTableEntry
);
PHLIBAPI
BOOLEAN
NTAPI
PhDestroyHandle(
_Inout_ PPH_HANDLE_TABLE HandleTable,
_In_ HANDLE Handle,
_In_opt_ PPH_HANDLE_TABLE_ENTRY HandleTableEntry
);
PHLIBAPI
PPH_HANDLE_TABLE_ENTRY
NTAPI
PhLookupHandleTableEntry(
_In_ PPH_HANDLE_TABLE HandleTable,
_In_ HANDLE Handle
);
typedef BOOLEAN (NTAPI *PPH_ENUM_HANDLE_TABLE_CALLBACK)(
_In_ PPH_HANDLE_TABLE HandleTable,
_In_ HANDLE Handle,
_In_ PPH_HANDLE_TABLE_ENTRY HandleTableEntry,
_In_opt_ PVOID Context
);
PHLIBAPI
VOID
NTAPI
PhEnumHandleTable(
_In_ PPH_HANDLE_TABLE HandleTable,
_In_ PPH_ENUM_HANDLE_TABLE_CALLBACK Callback,
_In_opt_ PVOID Context
);
PHLIBAPI
VOID
NTAPI
PhSweepHandleTable(
_In_ PPH_HANDLE_TABLE HandleTable,
_In_ PPH_ENUM_HANDLE_TABLE_CALLBACK Callback,
_In_opt_ PVOID Context
);
typedef enum _PH_HANDLE_TABLE_INFORMATION_CLASS
{
HandleTableBasicInformation,
HandleTableFlagsInformation,
MaxHandleTableInfoClass
} PH_HANDLE_TABLE_INFORMATION_CLASS;
typedef struct _PH_HANDLE_TABLE_BASIC_INFORMATION
{
ULONG Count;
ULONG Flags;
ULONG TableLevel;
} PH_HANDLE_TABLE_BASIC_INFORMATION, *PPH_HANDLE_TABLE_BASIC_INFORMATION;
typedef struct _PH_HANDLE_TABLE_FLAGS_INFORMATION
{
ULONG Flags;
} PH_HANDLE_TABLE_FLAGS_INFORMATION, *PPH_HANDLE_TABLE_FLAGS_INFORMATION;
PHLIBAPI
NTSTATUS
NTAPI
PhQueryInformationHandleTable(
_In_ PPH_HANDLE_TABLE HandleTable,
_In_ PH_HANDLE_TABLE_INFORMATION_CLASS InformationClass,
_Out_writes_bytes_opt_(BufferLength) PVOID Buffer,
_In_ ULONG BufferLength,
_Out_opt_ PULONG ReturnLength
);
PHLIBAPI
NTSTATUS
NTAPI
PhSetInformationHandleTable(
_Inout_ PPH_HANDLE_TABLE HandleTable,
_In_ PH_HANDLE_TABLE_INFORMATION_CLASS InformationClass,
_In_reads_bytes_(BufferLength) PVOID Buffer,
_In_ ULONG BufferLength
);
#ifdef __cplusplus
}
#endif
#endif

147
phlib/include/handlep.h Normal file
View File

@@ -0,0 +1,147 @@
#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

49
phlib/include/hexedit.h Normal file
View File

@@ -0,0 +1,49 @@
#ifndef _PH_HEXEDIT_H
#define _PH_HEXEDIT_H
#ifdef __cplusplus
extern "C" {
#endif
#define PH_HEXEDIT_CLASSNAME L"PhHexEdit"
#define EDIT_NONE 0
#define EDIT_ASCII 1
#define EDIT_HIGH 2
#define EDIT_LOW 3
PHLIBAPI
BOOLEAN PhHexEditInitialization(
VOID
);
#define HEM_SETBUFFER (WM_USER + 1)
#define HEM_SETDATA (WM_USER + 2)
#define HEM_GETBUFFER (WM_USER + 3)
#define HEM_SETSEL (WM_USER + 4)
#define HEM_SETEDITMODE (WM_USER + 5)
#define HEM_SETBYTESPERROW (WM_USER + 6)
#define HexEdit_SetBuffer(hWnd, Buffer, Length) \
SendMessage((hWnd), HEM_SETBUFFER, (WPARAM)(Length), (LPARAM)(Buffer))
#define HexEdit_SetData(hWnd, Buffer, Length) \
SendMessage((hWnd), HEM_SETDATA, (WPARAM)(Length), (LPARAM)(Buffer))
#define HexEdit_GetBuffer(hWnd, Length) \
((PUCHAR)SendMessage((hWnd), HEM_GETBUFFER, (WPARAM)(Length), 0))
#define HexEdit_SetSel(hWnd, Start, End) \
SendMessage((hWnd), HEM_SETSEL, (WPARAM)(Start), (LPARAM)(End))
#define HexEdit_SetEditMode(hWnd, Mode) \
SendMessage((hWnd), HEM_SETEDITMODE, (WPARAM)(Mode), 0)
#define HexEdit_SetBytesPerRow(hWnd, BytesPerRow) \
SendMessage((hWnd), HEM_SETBYTESPERROW, (WPARAM)(BytesPerRow), 0)
#ifdef __cplusplus
}
#endif
#endif

201
phlib/include/hexeditp.h Normal file
View File

@@ -0,0 +1,201 @@
#ifndef _PH_HEXEDITP_H
#define _PH_HEXEDITP_H
typedef struct _PHP_HEXEDIT_CONTEXT
{
PUCHAR Data;
LONG Length;
BOOLEAN UserBuffer;
LONG TopIndex; // index of first visible byte on screen
LONG CurrentAddress;
LONG CurrentMode;
LONG SelStart;
LONG SelEnd;
LONG BytesPerRow;
LONG LinesPerPage;
BOOLEAN ShowAddress;
BOOLEAN ShowAscii;
BOOLEAN ShowHex;
BOOLEAN AddressIsWide;
BOOLEAN AllowLengthChange;
BOOLEAN NoAddressChange;
BOOLEAN HalfPage;
HFONT Font;
LONG LineHeight;
LONG NullWidth;
PWCHAR CharBuffer;
ULONG CharBufferLength;
BOOLEAN Update;
LONG HexOffset;
LONG AsciiOffset;
LONG AddressOffset;
BOOLEAN HasCapture;
POINT EditPosition;
} PHP_HEXEDIT_CONTEXT, *PPHP_HEXEDIT_CONTEXT;
#define IS_PRINTABLE(Byte) ((ULONG)((Byte) - ' ') <= (ULONG)('~' - ' '))
#define TO_HEX(Buffer, Byte) \
{ \
*(Buffer)++ = PhIntegerToChar[(Byte) >> 4]; \
*(Buffer)++ = PhIntegerToChar[(Byte) & 0xf]; \
}
#define REDRAW_WINDOW(hwnd) \
RedrawWindow((hwnd), NULL, NULL, RDW_INVALIDATE | RDW_UPDATENOW | RDW_ERASE)
VOID PhpCreateHexEditContext(
_Out_ PPHP_HEXEDIT_CONTEXT *Context
);
VOID PhpFreeHexEditContext(
_In_ _Post_invalid_ PPHP_HEXEDIT_CONTEXT Context
);
LRESULT CALLBACK PhpHexEditWndProc(
_In_ HWND hwnd,
_In_ UINT uMsg,
_In_ WPARAM wParam,
_In_ LPARAM lParam
);
VOID PhpHexEditUpdateMetrics(
_In_ HWND hwnd,
_In_ PPHP_HEXEDIT_CONTEXT Context,
_In_ BOOLEAN UpdateLineHeight,
_In_opt_ HDC hdc
);
VOID PhpHexEditOnPaint(
_In_ HWND hwnd,
_In_ PPHP_HEXEDIT_CONTEXT Context,
_In_ PAINTSTRUCT *PaintStruct,
_In_ HDC hdc
);
VOID PhpHexEditUpdateScrollbars(
_In_ HWND hwnd,
_In_ PPHP_HEXEDIT_CONTEXT Context
);
FORCEINLINE BOOLEAN PhpHexEditHasSelected(
_In_ PPHP_HEXEDIT_CONTEXT Context
)
{
return Context->SelStart != -1;
}
VOID PhpHexEditCreateAddressCaret(
_In_ HWND hwnd,
_In_ PPHP_HEXEDIT_CONTEXT Context
);
VOID PhpHexEditCreateEditCaret(
_In_ HWND hwnd,
_In_ PPHP_HEXEDIT_CONTEXT Context
);
VOID PhpHexEditRepositionCaret(
_In_ HWND hwnd,
_In_ PPHP_HEXEDIT_CONTEXT Context,
_In_ LONG Position
);
VOID PhpHexEditCalculatePosition(
_In_ HWND hwnd,
_In_ PPHP_HEXEDIT_CONTEXT Context,
_In_ LONG X,
_In_ LONG Y,
_Out_ POINT *Point
);
VOID PhpHexEditMove(
_In_ HWND hwnd,
_In_ PPHP_HEXEDIT_CONTEXT Context,
_In_ LONG X,
_In_ LONG Y
);
VOID PhpHexEditSetSel(
_In_ HWND hwnd,
_In_ PPHP_HEXEDIT_CONTEXT Context,
_In_ LONG S,
_In_ LONG E
);
VOID PhpHexEditScrollTo(
_In_ HWND hwnd,
_In_ PPHP_HEXEDIT_CONTEXT Context,
_In_ LONG Position
);
VOID PhpHexEditClearEdit(
_In_ HWND hwnd,
_In_ PPHP_HEXEDIT_CONTEXT Context
);
VOID PhpHexEditCopyEdit(
_In_ HWND hwnd,
_In_ PPHP_HEXEDIT_CONTEXT Context
);
VOID PhpHexEditCutEdit(
_In_ HWND hwnd,
_In_ PPHP_HEXEDIT_CONTEXT Context
);
VOID PhpHexEditPasteEdit(
_In_ HWND hwnd,
_In_ PPHP_HEXEDIT_CONTEXT Context
);
VOID PhpHexEditSelectAll(
_In_ HWND hwnd,
_In_ PPHP_HEXEDIT_CONTEXT Context
);
VOID PhpHexEditUndoEdit(
_In_ HWND hwnd,
_In_ PPHP_HEXEDIT_CONTEXT Context
);
VOID PhpHexEditNormalizeSel(
_In_ HWND hwnd,
_In_ PPHP_HEXEDIT_CONTEXT Context
);
VOID PhpHexEditSelDelete(
_In_ HWND hwnd,
_In_ PPHP_HEXEDIT_CONTEXT Context,
_In_ LONG S,
_In_ LONG E
);
VOID PhpHexEditSelInsert(
_In_ HWND hwnd,
_In_ PPHP_HEXEDIT_CONTEXT Context,
_In_ LONG S,
_In_ LONG L
);
VOID PhpHexEditSetBuffer(
_In_ HWND hwnd,
_In_ PPHP_HEXEDIT_CONTEXT Context,
_In_ PUCHAR Data,
_In_ ULONG Length
);
VOID PhpHexEditSetData(
_In_ HWND hwnd,
_In_ PPHP_HEXEDIT_CONTEXT Context,
_In_ PUCHAR Data,
_In_ ULONG Length
);
#endif

138
phlib/include/hndlinfo.h Normal file
View File

@@ -0,0 +1,138 @@
#ifndef _PH_HNDLINFO_H
#define _PH_HNDLINFO_H
#ifdef __cplusplus
extern "C" {
#endif
#define MAX_OBJECT_TYPE_NUMBER 257
typedef PPH_STRING (NTAPI *PPH_GET_CLIENT_ID_NAME)(
_In_ PCLIENT_ID ClientId
);
PHLIBAPI
PPH_GET_CLIENT_ID_NAME
NTAPI
PhSetHandleClientIdFunction(
_In_ PPH_GET_CLIENT_ID_NAME GetClientIdName
);
PHLIBAPI
PPH_STRING
NTAPI
PhFormatNativeKeyName(
_In_ PPH_STRING Name
);
PHLIBAPI
NTSTATUS
NTAPI
PhGetSectionFileName(
_In_ HANDLE SectionHandle,
_Out_ PPH_STRING *FileName
);
PHLIBAPI
_Callback_ PPH_STRING
NTAPI
PhStdGetClientIdName(
_In_ PCLIENT_ID ClientId
);
PHLIBAPI
NTSTATUS
NTAPI
PhGetHandleInformation(
_In_ HANDLE ProcessHandle,
_In_ HANDLE Handle,
_In_ ULONG ObjectTypeNumber,
_Out_opt_ POBJECT_BASIC_INFORMATION BasicInformation,
_Out_opt_ PPH_STRING *TypeName,
_Out_opt_ PPH_STRING *ObjectName,
_Out_opt_ PPH_STRING *BestObjectName
);
PHLIBAPI
NTSTATUS
NTAPI
PhGetHandleInformationEx(
_In_ HANDLE ProcessHandle,
_In_ HANDLE Handle,
_In_ ULONG ObjectTypeNumber,
_Reserved_ ULONG Flags,
_Out_opt_ PNTSTATUS SubStatus,
_Out_opt_ POBJECT_BASIC_INFORMATION BasicInformation,
_Out_opt_ PPH_STRING *TypeName,
_Out_opt_ PPH_STRING *ObjectName,
_Out_opt_ PPH_STRING *BestObjectName,
_Reserved_ PVOID *ExtraInformation
);
#define PH_FIRST_OBJECT_TYPE(ObjectTypes) \
(POBJECT_TYPE_INFORMATION)((PCHAR)(ObjectTypes) + ALIGN_UP(sizeof(OBJECT_TYPES_INFORMATION), ULONG_PTR))
#define PH_NEXT_OBJECT_TYPE(ObjectType) \
(POBJECT_TYPE_INFORMATION)((PCHAR)(ObjectType) + sizeof(OBJECT_TYPE_INFORMATION) + \
ALIGN_UP(ObjectType->TypeName.MaximumLength, ULONG_PTR))
PHLIBAPI
NTSTATUS
NTAPI
PhEnumObjectTypes(
_Out_ POBJECT_TYPES_INFORMATION *ObjectTypes
);
PHLIBAPI
ULONG
NTAPI
PhGetObjectTypeNumber(
_In_ PUNICODE_STRING TypeName
);
PHLIBAPI
NTSTATUS
NTAPI
PhCallWithTimeout(
_In_ PUSER_THREAD_START_ROUTINE Routine,
_In_opt_ PVOID Context,
_In_opt_ PLARGE_INTEGER AcquireTimeout,
_In_ PLARGE_INTEGER CallTimeout
);
PHLIBAPI
NTSTATUS
NTAPI
PhCallNtQueryObjectWithTimeout(
_In_ HANDLE Handle,
_In_ OBJECT_INFORMATION_CLASS ObjectInformationClass,
_Out_writes_bytes_opt_(ObjectInformationLength) PVOID ObjectInformation,
_In_ ULONG ObjectInformationLength,
_Out_opt_ PULONG ReturnLength
);
PHLIBAPI
NTSTATUS
NTAPI
PhCallNtQuerySecurityObjectWithTimeout(
_In_ HANDLE Handle,
_In_ SECURITY_INFORMATION SecurityInformation,
_Out_writes_bytes_opt_(Length) PSECURITY_DESCRIPTOR SecurityDescriptor,
_In_ ULONG Length,
_Out_ PULONG LengthNeeded
);
PHLIBAPI
NTSTATUS
NTAPI
PhCallNtSetSecurityObjectWithTimeout(
_In_ HANDLE Handle,
_In_ SECURITY_INFORMATION SecurityInformation,
_In_ PSECURITY_DESCRIPTOR SecurityDescriptor
);
#ifdef __cplusplus
}
#endif
#endif

242
phlib/include/kphapi.h Normal file
View File

@@ -0,0 +1,242 @@
#ifndef _KPHAPI_H
#define _KPHAPI_H
// This file contains KProcessHacker definitions shared across kernel-mode and user-mode.
// Process information
typedef enum _KPH_PROCESS_INFORMATION_CLASS
{
KphProcessReserved1 = 1,
KphProcessReserved2 = 2,
KphProcessReserved3 = 3,
MaxKphProcessInfoClass
} KPH_PROCESS_INFORMATION_CLASS;
// Thread information
typedef enum _KPH_THREAD_INFORMATION_CLASS
{
KphThreadReserved1 = 1,
KphThreadReserved2 = 2,
KphThreadReserved3 = 3,
MaxKphThreadInfoClass
} KPH_THREAD_INFORMATION_CLASS;
// Process handle information
typedef struct _KPH_PROCESS_HANDLE
{
HANDLE Handle;
PVOID Object;
ACCESS_MASK GrantedAccess;
USHORT ObjectTypeIndex;
USHORT Reserved1;
ULONG HandleAttributes;
ULONG Reserved2;
} KPH_PROCESS_HANDLE, *PKPH_PROCESS_HANDLE;
typedef struct _KPH_PROCESS_HANDLE_INFORMATION
{
ULONG HandleCount;
KPH_PROCESS_HANDLE Handles[1];
} KPH_PROCESS_HANDLE_INFORMATION, *PKPH_PROCESS_HANDLE_INFORMATION;
// Object information
typedef enum _KPH_OBJECT_INFORMATION_CLASS
{
KphObjectBasicInformation, // q: OBJECT_BASIC_INFORMATION
KphObjectNameInformation, // q: OBJECT_NAME_INFORMATION
KphObjectTypeInformation, // q: OBJECT_TYPE_INFORMATION
KphObjectHandleFlagInformation, // qs: OBJECT_HANDLE_FLAG_INFORMATION
KphObjectProcessBasicInformation, // q: PROCESS_BASIC_INFORMATION
KphObjectThreadBasicInformation, // q: THREAD_BASIC_INFORMATION
KphObjectEtwRegBasicInformation, // q: ETWREG_BASIC_INFORMATION
KphObjectFileObjectInformation, // q: KPH_FILE_OBJECT_INFORMATION
KphObjectFileObjectDriver, // q: KPH_FILE_OBJECT_DRIVER
MaxKphObjectInfoClass
} KPH_OBJECT_INFORMATION_CLASS;
typedef struct _KPH_FILE_OBJECT_INFORMATION
{
BOOLEAN LockOperation;
BOOLEAN DeletePending;
BOOLEAN ReadAccess;
BOOLEAN WriteAccess;
BOOLEAN DeleteAccess;
BOOLEAN SharedRead;
BOOLEAN SharedWrite;
BOOLEAN SharedDelete;
LARGE_INTEGER CurrentByteOffset;
ULONG Flags;
} KPH_FILE_OBJECT_INFORMATION, *PKPH_FILE_OBJECT_INFORMATION;
typedef struct _KPH_FILE_OBJECT_DRIVER
{
HANDLE DriverHandle;
} KPH_FILE_OBJECT_DRIVER, *PKPH_FILE_OBJECT_DRIVER;
// Driver information
typedef enum _DRIVER_INFORMATION_CLASS
{
DriverBasicInformation,
DriverNameInformation,
DriverServiceKeyNameInformation,
MaxDriverInfoClass
} DRIVER_INFORMATION_CLASS;
typedef struct _DRIVER_BASIC_INFORMATION
{
ULONG Flags;
PVOID DriverStart;
ULONG DriverSize;
} DRIVER_BASIC_INFORMATION, *PDRIVER_BASIC_INFORMATION;
typedef struct _DRIVER_NAME_INFORMATION
{
UNICODE_STRING DriverName;
} DRIVER_NAME_INFORMATION, *PDRIVER_NAME_INFORMATION;
typedef struct _DRIVER_SERVICE_KEY_NAME_INFORMATION
{
UNICODE_STRING ServiceKeyName;
} DRIVER_SERVICE_KEY_NAME_INFORMATION, *PDRIVER_SERVICE_KEY_NAME_INFORMATION;
// ETW registration object information
typedef struct _ETWREG_BASIC_INFORMATION
{
GUID Guid;
ULONG_PTR SessionId;
} ETWREG_BASIC_INFORMATION, *PETWREG_BASIC_INFORMATION;
// Device
#define KPH_DEVICE_SHORT_NAME L"KProcessHacker3"
#define KPH_DEVICE_TYPE 0x9999
#define KPH_DEVICE_NAME (L"\\Device\\" KPH_DEVICE_SHORT_NAME)
// Parameters
typedef enum _KPH_SECURITY_LEVEL
{
KphSecurityNone = 0, // all clients are allowed
KphSecurityPrivilegeCheck = 1, // require SeDebugPrivilege
KphSecuritySignatureCheck = 2, // require trusted signature
KphSecuritySignatureAndPrivilegeCheck = 3, // require trusted signature and SeDebugPrivilege
KphMaxSecurityLevel
} KPH_SECURITY_LEVEL, *PKPH_SECURITY_LEVEL;
typedef struct _KPH_DYN_STRUCT_DATA
{
SHORT EgeGuid;
SHORT EpObjectTable;
SHORT Reserved0;
SHORT Reserved1;
SHORT Reserved2;
SHORT EreGuidEntry;
SHORT HtHandleContentionEvent;
SHORT OtName;
SHORT OtIndex;
SHORT ObDecodeShift;
SHORT ObAttributesShift;
} KPH_DYN_STRUCT_DATA, *PKPH_DYN_STRUCT_DATA;
typedef struct _KPH_DYN_PACKAGE
{
USHORT MajorVersion;
USHORT MinorVersion;
USHORT ServicePackMajor; // -1 to ignore
USHORT BuildNumber; // -1 to ignore
ULONG ResultingNtVersion; // PHNT_*
KPH_DYN_STRUCT_DATA StructData;
} KPH_DYN_PACKAGE, *PKPH_DYN_PACKAGE;
#define KPH_DYN_CONFIGURATION_VERSION 3
#define KPH_DYN_MAXIMUM_PACKAGES 64
typedef struct _KPH_DYN_CONFIGURATION
{
ULONG Version;
ULONG NumberOfPackages;
KPH_DYN_PACKAGE Packages[1];
} KPH_DYN_CONFIGURATION, *PKPH_DYN_CONFIGURATION;
// Verification
#ifdef __BCRYPT_H__
#define KPH_SIGN_ALGORITHM BCRYPT_ECDSA_P256_ALGORITHM
#define KPH_SIGN_ALGORITHM_BITS 256
#define KPH_HASH_ALGORITHM BCRYPT_SHA256_ALGORITHM
#define KPH_BLOB_PUBLIC BCRYPT_ECCPUBLIC_BLOB
#endif
#define KPH_SIGNATURE_MAX_SIZE (128 * 1024) // 128 kB
typedef ULONG KPH_KEY, *PKPH_KEY;
typedef enum _KPH_KEY_LEVEL
{
KphKeyLevel1 = 1,
KphKeyLevel2 = 2
} KPH_KEY_LEVEL;
#define KPH_KEY_BACKOFF_TIME ((LONGLONG)(100 * 1000 * 10)) // 100ms
#define KPH_PROCESS_READ_ACCESS \
(PROCESS_QUERY_INFORMATION | PROCESS_QUERY_LIMITED_INFORMATION | PROCESS_VM_READ)
#define KPH_THREAD_READ_ACCESS \
(THREAD_QUERY_INFORMATION | THREAD_QUERY_LIMITED_INFORMATION | THREAD_GET_CONTEXT)
#define KPH_TOKEN_READ_ACCESS \
(TOKEN_QUERY | TOKEN_QUERY_SOURCE)
// Features
// No features defined.
// Control codes
#define KPH_CTL_CODE(x) CTL_CODE(KPH_DEVICE_TYPE, 0x800 + x, METHOD_NEITHER, FILE_ANY_ACCESS)
// General
#define KPH_GETFEATURES KPH_CTL_CODE(0)
#define KPH_VERIFYCLIENT KPH_CTL_CODE(1)
#define KPH_RETRIEVEKEY KPH_CTL_CODE(2) // User-mode only
// Processes
#define KPH_OPENPROCESS KPH_CTL_CODE(50) // L1/L2 protected API
#define KPH_OPENPROCESSTOKEN KPH_CTL_CODE(51) // L1/L2 protected API
#define KPH_OPENPROCESSJOB KPH_CTL_CODE(52)
#define KPH_RESERVED53 KPH_CTL_CODE(53)
#define KPH_RESERVED54 KPH_CTL_CODE(54)
#define KPH_TERMINATEPROCESS KPH_CTL_CODE(55) // L2 protected API
#define KPH_RESERVED56 KPH_CTL_CODE(56)
#define KPH_RESERVED57 KPH_CTL_CODE(57)
#define KPH_READVIRTUALMEMORYUNSAFE KPH_CTL_CODE(58) // L2 protected API
#define KPH_QUERYINFORMATIONPROCESS KPH_CTL_CODE(59)
#define KPH_SETINFORMATIONPROCESS KPH_CTL_CODE(60)
// Threads
#define KPH_OPENTHREAD KPH_CTL_CODE(100) // L1/L2 protected API
#define KPH_OPENTHREADPROCESS KPH_CTL_CODE(101)
#define KPH_RESERVED102 KPH_CTL_CODE(102)
#define KPH_RESERVED103 KPH_CTL_CODE(103)
#define KPH_RESERVED104 KPH_CTL_CODE(104)
#define KPH_RESERVED105 KPH_CTL_CODE(105)
#define KPH_CAPTURESTACKBACKTRACETHREAD KPH_CTL_CODE(106)
#define KPH_QUERYINFORMATIONTHREAD KPH_CTL_CODE(107)
#define KPH_SETINFORMATIONTHREAD KPH_CTL_CODE(108)
// Handles
#define KPH_ENUMERATEPROCESSHANDLES KPH_CTL_CODE(150)
#define KPH_QUERYINFORMATIONOBJECT KPH_CTL_CODE(151)
#define KPH_SETINFORMATIONOBJECT KPH_CTL_CODE(152)
#define KPH_RESERVED153 KPH_CTL_CODE(153)
// Misc.
#define KPH_OPENDRIVER KPH_CTL_CODE(200)
#define KPH_QUERYINFORMATIONDRIVER KPH_CTL_CODE(201)
#endif

300
phlib/include/kphuser.h Normal file
View File

@@ -0,0 +1,300 @@
#ifndef _PH_KPHUSER_H
#define _PH_KPHUSER_H
#include <kphapi.h>
#ifdef __cplusplus
extern "C" {
#endif
typedef struct _KPH_PARAMETERS
{
KPH_SECURITY_LEVEL SecurityLevel;
BOOLEAN CreateDynamicConfiguration;
} KPH_PARAMETERS, *PKPH_PARAMETERS;
PHLIBAPI
NTSTATUS
NTAPI
KphConnect(
_In_opt_ PWSTR DeviceName
);
PHLIBAPI
NTSTATUS
NTAPI
KphConnect2(
_In_opt_ PWSTR DeviceName,
_In_ PWSTR FileName
);
PHLIBAPI
NTSTATUS
NTAPI
KphConnect2Ex(
_In_opt_ PWSTR DeviceName,
_In_ PWSTR FileName,
_In_opt_ PKPH_PARAMETERS Parameters
);
PHLIBAPI
NTSTATUS
NTAPI
KphDisconnect(
VOID
);
PHLIBAPI
BOOLEAN
NTAPI
KphIsConnected(
VOID
);
PHLIBAPI
BOOLEAN
NTAPI
KphIsVerified(
VOID
);
PHLIBAPI
NTSTATUS
NTAPI
KphSetParameters(
_In_opt_ PWSTR DeviceName,
_In_ PKPH_PARAMETERS Parameters
);
PHLIBAPI
NTSTATUS
NTAPI
KphInstall(
_In_opt_ PWSTR DeviceName,
_In_ PWSTR FileName
);
PHLIBAPI
NTSTATUS
NTAPI
KphInstallEx(
_In_opt_ PWSTR DeviceName,
_In_ PWSTR FileName,
_In_opt_ PKPH_PARAMETERS Parameters
);
PHLIBAPI
NTSTATUS
NTAPI
KphUninstall(
_In_opt_ PWSTR DeviceName
);
PHLIBAPI
NTSTATUS
NTAPI
KphGetFeatures(
_Out_ PULONG Features
);
PHLIBAPI
NTSTATUS
NTAPI
KphVerifyClient(
_In_reads_bytes_(SignatureSize) PUCHAR Signature,
_In_ ULONG SignatureSize
);
PHLIBAPI
NTSTATUS
NTAPI
KphOpenProcess(
_Out_ PHANDLE ProcessHandle,
_In_ ACCESS_MASK DesiredAccess,
_In_ PCLIENT_ID ClientId
);
PHLIBAPI
NTSTATUS
NTAPI
KphOpenProcessToken(
_In_ HANDLE ProcessHandle,
_In_ ACCESS_MASK DesiredAccess,
_Out_ PHANDLE TokenHandle
);
PHLIBAPI
NTSTATUS
NTAPI
KphOpenProcessJob(
_In_ HANDLE ProcessHandle,
_In_ ACCESS_MASK DesiredAccess,
_Out_ PHANDLE JobHandle
);
PHLIBAPI
NTSTATUS
NTAPI
KphTerminateProcess(
_In_ HANDLE ProcessHandle,
_In_ NTSTATUS ExitStatus
);
PHLIBAPI
NTSTATUS
NTAPI
KphReadVirtualMemoryUnsafe(
_In_opt_ HANDLE ProcessHandle,
_In_ PVOID BaseAddress,
_Out_writes_bytes_(BufferSize) PVOID Buffer,
_In_ SIZE_T BufferSize,
_Out_opt_ PSIZE_T NumberOfBytesRead
);
PHLIBAPI
NTSTATUS
NTAPI
KphQueryInformationProcess(
_In_ HANDLE ProcessHandle,
_In_ KPH_PROCESS_INFORMATION_CLASS ProcessInformationClass,
_Out_writes_bytes_(ProcessInformationLength) PVOID ProcessInformation,
_In_ ULONG ProcessInformationLength,
_Out_opt_ PULONG ReturnLength
);
PHLIBAPI
NTSTATUS
NTAPI
KphSetInformationProcess(
_In_ HANDLE ProcessHandle,
_In_ KPH_PROCESS_INFORMATION_CLASS ProcessInformationClass,
_In_reads_bytes_(ProcessInformationLength) PVOID ProcessInformation,
_In_ ULONG ProcessInformationLength
);
PHLIBAPI
NTSTATUS
NTAPI
KphOpenThread(
_Out_ PHANDLE ThreadHandle,
_In_ ACCESS_MASK DesiredAccess,
_In_ PCLIENT_ID ClientId
);
PHLIBAPI
NTSTATUS
NTAPI
KphOpenThreadProcess(
_In_ HANDLE ThreadHandle,
_In_ ACCESS_MASK DesiredAccess,
_Out_ PHANDLE ProcessHandle
);
PHLIBAPI
NTSTATUS
NTAPI
KphCaptureStackBackTraceThread(
_In_ HANDLE ThreadHandle,
_In_ ULONG FramesToSkip,
_In_ ULONG FramesToCapture,
_Out_writes_(FramesToCapture) PVOID *BackTrace,
_Out_opt_ PULONG CapturedFrames,
_Out_opt_ PULONG BackTraceHash
);
PHLIBAPI
NTSTATUS
NTAPI
KphQueryInformationThread(
_In_ HANDLE ThreadHandle,
_In_ KPH_THREAD_INFORMATION_CLASS ThreadInformationClass,
_Out_writes_bytes_(ThreadInformationLength) PVOID ThreadInformation,
_In_ ULONG ThreadInformationLength,
_Out_opt_ PULONG ReturnLength
);
PHLIBAPI
NTSTATUS
NTAPI
KphSetInformationThread(
_In_ HANDLE ThreadHandle,
_In_ KPH_THREAD_INFORMATION_CLASS ThreadInformationClass,
_In_reads_bytes_(ThreadInformationLength) PVOID ThreadInformation,
_In_ ULONG ThreadInformationLength
);
PHLIBAPI
NTSTATUS
NTAPI
KphEnumerateProcessHandles(
_In_ HANDLE ProcessHandle,
_Out_writes_bytes_(BufferLength) PVOID Buffer,
_In_opt_ ULONG BufferLength,
_Out_opt_ PULONG ReturnLength
);
PHLIBAPI
NTSTATUS
NTAPI
KphEnumerateProcessHandles2(
_In_ HANDLE ProcessHandle,
_Out_ PKPH_PROCESS_HANDLE_INFORMATION *Handles
);
PHLIBAPI
NTSTATUS
NTAPI
KphQueryInformationObject(
_In_ HANDLE ProcessHandle,
_In_ HANDLE Handle,
_In_ KPH_OBJECT_INFORMATION_CLASS ObjectInformationClass,
_Out_writes_bytes_(ObjectInformationLength) PVOID ObjectInformation,
_In_ ULONG ObjectInformationLength,
_Out_opt_ PULONG ReturnLength
);
PHLIBAPI
NTSTATUS
NTAPI
KphSetInformationObject(
_In_ HANDLE ProcessHandle,
_In_ HANDLE Handle,
_In_ KPH_OBJECT_INFORMATION_CLASS ObjectInformationClass,
_In_reads_bytes_(ObjectInformationLength) PVOID ObjectInformation,
_In_ ULONG ObjectInformationLength
);
PHLIBAPI
NTSTATUS
NTAPI
KphOpenDriver(
_Out_ PHANDLE DriverHandle,
_In_ ACCESS_MASK DesiredAccess,
_In_ POBJECT_ATTRIBUTES ObjectAttributes
);
PHLIBAPI
NTSTATUS
NTAPI
KphQueryInformationDriver(
_In_ HANDLE DriverHandle,
_In_ DRIVER_INFORMATION_CLASS DriverInformationClass,
_Out_writes_bytes_(DriverInformationLength) PVOID DriverInformation,
_In_ ULONG DriverInformationLength,
_Out_opt_ PULONG ReturnLength
);
// kphdata
PHLIBAPI
NTSTATUS
NTAPI
KphInitializeDynamicPackage(
_Out_ PKPH_DYN_PACKAGE Package
);
#ifdef __cplusplus
}
#endif
#endif

127
phlib/include/kphuserp.h Normal file
View File

@@ -0,0 +1,127 @@
#ifndef _PH_KPHUSERP_H
#define _PH_KPHUSERP_H
typedef NTSTATUS (NTAPI *PKPHP_WITH_KEY_CONTINUATION)(
_In_ KPH_KEY Key,
_In_ PVOID Context
);
NTSTATUS KphpDeviceIoControl(
_In_ ULONG KphControlCode,
_In_ PVOID InBuffer,
_In_ ULONG InBufferLength
);
typedef struct _KPHP_RETRIEVE_KEY_CONTEXT
{
IO_STATUS_BLOCK Iosb;
PKPHP_WITH_KEY_CONTINUATION Continuation;
PVOID Context;
NTSTATUS Status;
} KPHP_RETRIEVE_KEY_CONTEXT, *PKPHP_RETRIEVE_KEY_CONTEXT;
VOID KphpWithKeyApcRoutine(
_In_ PVOID ApcContext,
_In_ PIO_STATUS_BLOCK IoStatusBlock,
_In_ ULONG Reserved
);
NTSTATUS KphpWithKey(
_In_ KPH_KEY_LEVEL KeyLevel,
_In_ PKPHP_WITH_KEY_CONTINUATION Continuation,
_In_ PVOID Context
);
// Get L1 key
typedef struct _KPHP_GET_L1_KEY_CONTEXT
{
PKPH_KEY Key;
} KPHP_GET_L1_KEY_CONTEXT, *PKPHP_GET_L1_KEY_CONTEXT;
NTSTATUS KphpGetL1KeyContinuation(
_In_ KPH_KEY Key,
_In_ PVOID Context
);
NTSTATUS KphpGetL1Key(
_Out_ PKPH_KEY Key
);
// Open process
typedef struct _KPH_OPEN_PROCESS_INPUT
{
PHANDLE ProcessHandle;
ACCESS_MASK DesiredAccess;
PCLIENT_ID ClientId;
KPH_KEY Key;
} KPH_OPEN_PROCESS_INPUT, *PKPH_OPEN_PROCESS_INPUT;
NTSTATUS KphpOpenProcessContinuation(
_In_ KPH_KEY Key,
_In_ PVOID Context
);
// Open process token
typedef struct _KPH_OPEN_PROCESS_TOKEN_INPUT
{
HANDLE ProcessHandle;
ACCESS_MASK DesiredAccess;
PHANDLE TokenHandle;
KPH_KEY Key;
} KPH_OPEN_PROCESS_TOKEN_INPUT, *PKPH_OPEN_PROCESS_TOKEN_INPUT;
NTSTATUS KphpOpenProcessTokenContinuation(
_In_ KPH_KEY Key,
_In_ PVOID Context
);
// Terminate process
typedef struct _KPH_TERMINATE_PROCESS_INPUT
{
HANDLE ProcessHandle;
NTSTATUS ExitStatus;
KPH_KEY Key;
} KPH_TERMINATE_PROCESS_INPUT, *PKPH_TERMINATE_PROCESS_INPUT;
NTSTATUS KphpTerminateProcessContinuation(
_In_ KPH_KEY Key,
_In_ PVOID Context
);
// Read virtual memory, unsafe
typedef struct _KPH_READ_VIRTUAL_MEMORY_UNSAFE_INPUT
{
HANDLE ProcessHandle;
PVOID BaseAddress;
PVOID Buffer;
SIZE_T BufferSize;
PSIZE_T NumberOfBytesRead;
KPH_KEY Key;
} KPH_READ_VIRTUAL_MEMORY_UNSAFE_INPUT, *PKPH_READ_VIRTUAL_MEMORY_UNSAFE_INPUT;
NTSTATUS KphpReadVirtualMemoryUnsafeContinuation(
_In_ KPH_KEY Key,
_In_ PVOID Context
);
// Open thread
typedef struct _KPH_OPEN_THREAD_INPUT
{
PHANDLE ThreadHandle;
ACCESS_MASK DesiredAccess;
PCLIENT_ID ClientId;
KPH_KEY Key;
} KPH_OPEN_THREAD_INPUT, *PKPH_OPEN_THREAD_INPUT;
NTSTATUS KphpOpenThreadContinuation(
_In_ KPH_KEY Key,
_In_ PVOID Context
);
#endif

88
phlib/include/lsasup.h Normal file
View File

@@ -0,0 +1,88 @@
#ifndef _PH_LSASUP_H
#define _PH_LSASUP_H
#ifdef __cplusplus
extern "C" {
#endif
PHLIBAPI
NTSTATUS
NTAPI
PhOpenLsaPolicy(
_Out_ PLSA_HANDLE PolicyHandle,
_In_ ACCESS_MASK DesiredAccess,
_In_opt_ PUNICODE_STRING SystemName
);
PHLIBAPI
LSA_HANDLE
NTAPI
PhGetLookupPolicyHandle(
VOID
);
PHLIBAPI
BOOLEAN
NTAPI
PhLookupPrivilegeName(
_In_ PLUID PrivilegeValue,
_Out_ PPH_STRING *PrivilegeName
);
PHLIBAPI
BOOLEAN
NTAPI
PhLookupPrivilegeDisplayName(
_In_ PPH_STRINGREF PrivilegeName,
_Out_ PPH_STRING *PrivilegeDisplayName
);
PHLIBAPI
BOOLEAN
NTAPI
PhLookupPrivilegeValue(
_In_ PPH_STRINGREF PrivilegeName,
_Out_ PLUID PrivilegeValue
);
PHLIBAPI
NTSTATUS
NTAPI
PhLookupSid(
_In_ PSID Sid,
_Out_opt_ PPH_STRING *Name,
_Out_opt_ PPH_STRING *DomainName,
_Out_opt_ PSID_NAME_USE NameUse
);
PHLIBAPI
NTSTATUS
NTAPI
PhLookupName(
_In_ PPH_STRINGREF Name,
_Out_opt_ PSID *Sid,
_Out_opt_ PPH_STRING *DomainName,
_Out_opt_ PSID_NAME_USE NameUse
);
PHLIBAPI
PPH_STRING
NTAPI
PhGetSidFullName(
_In_ PSID Sid,
_In_ BOOLEAN IncludeDomain,
_Out_opt_ PSID_NAME_USE NameUse
);
PHLIBAPI
PPH_STRING
NTAPI
PhSidToStringSid(
_In_ PSID Sid
);
#ifdef __cplusplus
}
#endif
#endif

388
phlib/include/mapimg.h Normal file
View File

@@ -0,0 +1,388 @@
#ifndef _PH_MAPIMG_H
#define _PH_MAPIMG_H
#ifdef __cplusplus
extern "C" {
#endif
typedef struct _PH_MAPPED_IMAGE
{
PVOID ViewBase;
SIZE_T Size;
PIMAGE_NT_HEADERS NtHeaders;
ULONG NumberOfSections;
PIMAGE_SECTION_HEADER Sections;
USHORT Magic;
} PH_MAPPED_IMAGE, *PPH_MAPPED_IMAGE;
PHLIBAPI
NTSTATUS
NTAPI
PhInitializeMappedImage(
_Out_ PPH_MAPPED_IMAGE MappedImage,
_In_ PVOID ViewBase,
_In_ SIZE_T Size
);
PHLIBAPI
NTSTATUS
NTAPI
PhLoadMappedImage(
_In_opt_ PWSTR FileName,
_In_opt_ HANDLE FileHandle,
_In_ BOOLEAN ReadOnly,
_Out_ PPH_MAPPED_IMAGE MappedImage
);
PHLIBAPI
NTSTATUS
NTAPI
PhUnloadMappedImage(
_Inout_ PPH_MAPPED_IMAGE MappedImage
);
PHLIBAPI
NTSTATUS
NTAPI
PhMapViewOfEntireFile(
_In_opt_ PWSTR FileName,
_In_opt_ HANDLE FileHandle,
_In_ BOOLEAN ReadOnly,
_Out_ PVOID *ViewBase,
_Out_ PSIZE_T Size
);
PHLIBAPI
PIMAGE_SECTION_HEADER
NTAPI
PhMappedImageRvaToSection(
_In_ PPH_MAPPED_IMAGE MappedImage,
_In_ ULONG Rva
);
PHLIBAPI
PVOID
NTAPI
PhMappedImageRvaToVa(
_In_ PPH_MAPPED_IMAGE MappedImage,
_In_ ULONG Rva,
_Out_opt_ PIMAGE_SECTION_HEADER *Section
);
PHLIBAPI
BOOLEAN
NTAPI
PhGetMappedImageSectionName(
_In_ PIMAGE_SECTION_HEADER Section,
_Out_writes_opt_z_(Count) PSTR Buffer,
_In_ ULONG Count,
_Out_opt_ PULONG ReturnCount
);
PHLIBAPI
NTSTATUS
NTAPI
PhGetMappedImageDataEntry(
_In_ PPH_MAPPED_IMAGE MappedImage,
_In_ ULONG Index,
_Out_ PIMAGE_DATA_DIRECTORY *Entry
);
PHLIBAPI
NTSTATUS
NTAPI
PhGetMappedImageLoadConfig32(
_In_ PPH_MAPPED_IMAGE MappedImage,
_Out_ PIMAGE_LOAD_CONFIG_DIRECTORY32 *LoadConfig
);
PHLIBAPI
NTSTATUS
NTAPI
PhGetMappedImageLoadConfig64(
_In_ PPH_MAPPED_IMAGE MappedImage,
_Out_ PIMAGE_LOAD_CONFIG_DIRECTORY64 *LoadConfig
);
typedef struct _PH_REMOTE_MAPPED_IMAGE
{
PVOID ViewBase;
PIMAGE_NT_HEADERS NtHeaders;
ULONG NumberOfSections;
PIMAGE_SECTION_HEADER Sections;
USHORT Magic;
} PH_REMOTE_MAPPED_IMAGE, *PPH_REMOTE_MAPPED_IMAGE;
NTSTATUS
NTAPI
PhLoadRemoteMappedImage(
_In_ HANDLE ProcessHandle,
_In_ PVOID ViewBase,
_Out_ PPH_REMOTE_MAPPED_IMAGE RemoteMappedImage
);
NTSTATUS
NTAPI
PhUnloadRemoteMappedImage(
_Inout_ PPH_REMOTE_MAPPED_IMAGE RemoteMappedImage
);
typedef struct _PH_MAPPED_IMAGE_EXPORTS
{
PPH_MAPPED_IMAGE MappedImage;
ULONG NumberOfEntries;
PIMAGE_DATA_DIRECTORY DataDirectory;
PIMAGE_EXPORT_DIRECTORY ExportDirectory;
PULONG AddressTable;
PULONG NamePointerTable;
PUSHORT OrdinalTable;
} PH_MAPPED_IMAGE_EXPORTS, *PPH_MAPPED_IMAGE_EXPORTS;
typedef struct _PH_MAPPED_IMAGE_EXPORT_ENTRY
{
USHORT Ordinal;
PSTR Name;
} PH_MAPPED_IMAGE_EXPORT_ENTRY, *PPH_MAPPED_IMAGE_EXPORT_ENTRY;
typedef struct _PH_MAPPED_IMAGE_EXPORT_FUNCTION
{
PVOID Function;
PSTR ForwardedName;
} PH_MAPPED_IMAGE_EXPORT_FUNCTION, *PPH_MAPPED_IMAGE_EXPORT_FUNCTION;
PHLIBAPI
NTSTATUS
NTAPI
PhGetMappedImageExports(
_Out_ PPH_MAPPED_IMAGE_EXPORTS Exports,
_In_ PPH_MAPPED_IMAGE MappedImage
);
PHLIBAPI
NTSTATUS
NTAPI
PhGetMappedImageExportEntry(
_In_ PPH_MAPPED_IMAGE_EXPORTS Exports,
_In_ ULONG Index,
_Out_ PPH_MAPPED_IMAGE_EXPORT_ENTRY Entry
);
PHLIBAPI
NTSTATUS
NTAPI
PhGetMappedImageExportFunction(
_In_ PPH_MAPPED_IMAGE_EXPORTS Exports,
_In_opt_ PSTR Name,
_In_opt_ USHORT Ordinal,
_Out_ PPH_MAPPED_IMAGE_EXPORT_FUNCTION Function
);
PHLIBAPI
NTSTATUS
NTAPI
PhGetMappedImageExportFunctionRemote(
_In_ PPH_MAPPED_IMAGE_EXPORTS Exports,
_In_opt_ PSTR Name,
_In_opt_ USHORT Ordinal,
_In_ PVOID RemoteBase,
_Out_ PVOID *Function
);
#define PH_MAPPED_IMAGE_DELAY_IMPORTS 0x1
typedef struct _PH_MAPPED_IMAGE_IMPORTS
{
PPH_MAPPED_IMAGE MappedImage;
ULONG Flags;
ULONG NumberOfDlls;
union
{
PIMAGE_IMPORT_DESCRIPTOR DescriptorTable;
PVOID DelayDescriptorTable;
};
} PH_MAPPED_IMAGE_IMPORTS, *PPH_MAPPED_IMAGE_IMPORTS;
typedef struct _PH_MAPPED_IMAGE_IMPORT_DLL
{
PPH_MAPPED_IMAGE MappedImage;
ULONG Flags;
PSTR Name;
ULONG NumberOfEntries;
union
{
PIMAGE_IMPORT_DESCRIPTOR Descriptor;
PVOID DelayDescriptor;
};
PVOID *LookupTable;
} PH_MAPPED_IMAGE_IMPORT_DLL, *PPH_MAPPED_IMAGE_IMPORT_DLL;
typedef struct _PH_MAPPED_IMAGE_IMPORT_ENTRY
{
PSTR Name;
union
{
USHORT Ordinal;
USHORT NameHint;
};
} PH_MAPPED_IMAGE_IMPORT_ENTRY, *PPH_MAPPED_IMAGE_IMPORT_ENTRY;
PHLIBAPI
NTSTATUS
NTAPI
PhGetMappedImageImports(
_Out_ PPH_MAPPED_IMAGE_IMPORTS Imports,
_In_ PPH_MAPPED_IMAGE MappedImage
);
PHLIBAPI
NTSTATUS
NTAPI
PhGetMappedImageImportDll(
_In_ PPH_MAPPED_IMAGE_IMPORTS Imports,
_In_ ULONG Index,
_Out_ PPH_MAPPED_IMAGE_IMPORT_DLL ImportDll
);
PHLIBAPI
NTSTATUS
NTAPI
PhGetMappedImageImportEntry(
_In_ PPH_MAPPED_IMAGE_IMPORT_DLL ImportDll,
_In_ ULONG Index,
_Out_ PPH_MAPPED_IMAGE_IMPORT_ENTRY Entry
);
PHLIBAPI
NTSTATUS
NTAPI
PhGetMappedImageDelayImports(
_Out_ PPH_MAPPED_IMAGE_IMPORTS Imports,
_In_ PPH_MAPPED_IMAGE MappedImage
);
USHORT
NTAPI
PhCheckSum(
_In_ ULONG Sum,
_In_reads_(Count) PUSHORT Buffer,
_In_ ULONG Count
);
PHLIBAPI
ULONG
NTAPI
PhCheckSumMappedImage(
_In_ PPH_MAPPED_IMAGE MappedImage
);
// maplib
struct _PH_MAPPED_ARCHIVE;
typedef struct _PH_MAPPED_ARCHIVE *PPH_MAPPED_ARCHIVE;
typedef enum _PH_MAPPED_ARCHIVE_MEMBER_TYPE
{
NormalArchiveMemberType,
LinkerArchiveMemberType,
LongnamesArchiveMemberType
} PH_MAPPED_ARCHIVE_MEMBER_TYPE;
typedef struct _PH_MAPPED_ARCHIVE_MEMBER
{
PPH_MAPPED_ARCHIVE MappedArchive;
PH_MAPPED_ARCHIVE_MEMBER_TYPE Type;
PSTR Name;
ULONG Size;
PVOID Data;
PIMAGE_ARCHIVE_MEMBER_HEADER Header;
CHAR NameBuffer[20];
} PH_MAPPED_ARCHIVE_MEMBER, *PPH_MAPPED_ARCHIVE_MEMBER;
typedef struct _PH_MAPPED_ARCHIVE
{
PVOID ViewBase;
SIZE_T Size;
PH_MAPPED_ARCHIVE_MEMBER FirstLinkerMember;
PH_MAPPED_ARCHIVE_MEMBER SecondLinkerMember;
PH_MAPPED_ARCHIVE_MEMBER LongnamesMember;
BOOLEAN HasLongnamesMember;
PPH_MAPPED_ARCHIVE_MEMBER FirstStandardMember;
PPH_MAPPED_ARCHIVE_MEMBER LastStandardMember;
} PH_MAPPED_ARCHIVE, *PPH_MAPPED_ARCHIVE;
typedef struct _PH_MAPPED_ARCHIVE_IMPORT_ENTRY
{
PSTR Name;
PSTR DllName;
union
{
USHORT Ordinal;
USHORT NameHint;
};
BYTE Type;
BYTE NameType;
USHORT Machine;
} PH_MAPPED_ARCHIVE_IMPORT_ENTRY, *PPH_MAPPED_ARCHIVE_IMPORT_ENTRY;
PHLIBAPI
NTSTATUS
NTAPI
PhInitializeMappedArchive(
_Out_ PPH_MAPPED_ARCHIVE MappedArchive,
_In_ PVOID ViewBase,
_In_ SIZE_T Size
);
PHLIBAPI
NTSTATUS
NTAPI
PhLoadMappedArchive(
_In_opt_ PWSTR FileName,
_In_opt_ HANDLE FileHandle,
_In_ BOOLEAN ReadOnly,
_Out_ PPH_MAPPED_ARCHIVE MappedArchive
);
PHLIBAPI
NTSTATUS
NTAPI
PhUnloadMappedArchive(
_Inout_ PPH_MAPPED_ARCHIVE MappedArchive
);
PHLIBAPI
NTSTATUS
NTAPI
PhGetNextMappedArchiveMember(
_In_ PPH_MAPPED_ARCHIVE_MEMBER Member,
_Out_ PPH_MAPPED_ARCHIVE_MEMBER NextMember
);
PHLIBAPI
BOOLEAN
NTAPI
PhIsMappedArchiveMemberShortFormat(
_In_ PPH_MAPPED_ARCHIVE_MEMBER Member
);
PHLIBAPI
NTSTATUS
NTAPI
PhGetMappedArchiveImportEntry(
_In_ PPH_MAPPED_ARCHIVE_MEMBER Member,
_Out_ PPH_MAPPED_ARCHIVE_IMPORT_ENTRY Entry
);
#ifdef __cplusplus
}
#endif
#endif

11
phlib/include/ph.h Normal file
View File

@@ -0,0 +1,11 @@
#ifndef _PH_PH_H
#define _PH_PH_H
#pragma once
#include <phbase.h>
#include <phnative.h>
#include <phnativeinl.h>
#include <phutil.h>
#endif

45
phlib/include/phbase.h Normal file
View File

@@ -0,0 +1,45 @@
#ifndef _PH_PHBASE_H
#define _PH_PHBASE_H
#pragma once
#ifndef PHLIB_NO_DEFAULT_LIB
#pragma comment(lib, "ntdll.lib")
#pragma comment(lib, "comctl32.lib")
#pragma comment(lib, "version.lib")
#endif
// nonstandard extension used : nameless struct/union
#pragma warning(disable: 4201)
// nonstandard extension used : bit field types other than int
#pragma warning(disable: 4214)
// 'function': attributes not present on previous declaration
#pragma warning(disable: 4985)
#ifndef UNICODE
#define UNICODE
#endif
#ifndef _CRT_SECURE_NO_WARNINGS
#define _CRT_SECURE_NO_WARNINGS
#endif
#if !defined(_PHLIB_)
#define PHLIBAPI __declspec(dllimport)
#else
#define PHLIBAPI
#endif
#include <phnt_windows.h>
#include <phnt.h>
#include <phsup.h>
#include <ref.h>
#include <queuedlock.h>
#include <stdlib.h>
#include <phconfig.h>
#include <phbasesup.h>
#include <phdata.h>
#endif

3740
phlib/include/phbasesup.h Normal file

File diff suppressed because it is too large Load Diff

109
phlib/include/phconfig.h Normal file
View File

@@ -0,0 +1,109 @@
#ifndef _PH_PHCONFIG_H
#define _PH_PHCONFIG_H
#ifdef __cplusplus
extern "C" {
#endif
#define _User_set_
PHLIBAPI extern _User_set_ PVOID PhLibImageBase;
PHLIBAPI extern _User_set_ PWSTR PhApplicationName;
PHLIBAPI extern _User_set_ ULONG PhGlobalDpi;
PHLIBAPI extern PVOID PhHeapHandle;
PHLIBAPI extern RTL_OSVERSIONINFOEXW PhOsVersion;
PHLIBAPI extern SYSTEM_BASIC_INFORMATION PhSystemBasicInformation;
PHLIBAPI extern ULONG WindowsVersion;
PHLIBAPI extern ACCESS_MASK ProcessQueryAccess;
PHLIBAPI extern ACCESS_MASK ProcessAllAccess;
PHLIBAPI extern ACCESS_MASK ThreadQueryAccess;
PHLIBAPI extern ACCESS_MASK ThreadSetAccess;
PHLIBAPI extern ACCESS_MASK ThreadAllAccess;
#define WINDOWS_ANCIENT 0
#define WINDOWS_XP 51
#define WINDOWS_SERVER_2003 52
#define WINDOWS_VISTA 60
#define WINDOWS_7 61
#define WINDOWS_8 62
#define WINDOWS_8_1 63
#define WINDOWS_10 100
#define WINDOWS_NEW MAXLONG
#define WINDOWS_HAS_CONSOLE_HOST (WindowsVersion >= WINDOWS_7)
#define WINDOWS_HAS_CYCLE_TIME (WindowsVersion >= WINDOWS_VISTA)
#define WINDOWS_HAS_IFILEDIALOG (WindowsVersion >= WINDOWS_VISTA)
#define WINDOWS_HAS_IMAGE_FILE_NAME_BY_PROCESS_ID (WindowsVersion >= WINDOWS_VISTA)
#define WINDOWS_HAS_IMMERSIVE (WindowsVersion >= WINDOWS_8)
#define WINDOWS_HAS_LIMITED_ACCESS (WindowsVersion >= WINDOWS_VISTA)
#define WINDOWS_HAS_SERVICE_TAGS (WindowsVersion >= WINDOWS_VISTA)
#define WINDOWS_HAS_UAC (WindowsVersion >= WINDOWS_VISTA)
// Debugging
#ifdef DEBUG
#define dprintf(format, ...) DbgPrint(format, __VA_ARGS__)
#else
#define dprintf(format, ...)
#endif
// global
// Initialization flags
// Features
// Imports
#define PHLIB_INIT_MODULE_RESERVED1 0x1
#define PHLIB_INIT_MODULE_RESERVED2 0x2
/** Needed to use work queues. */
#define PHLIB_INIT_MODULE_RESERVED3 0x4
#define PHLIB_INIT_MODULE_RESERVED4 0x8
/** Needed to use file streams. */
#define PHLIB_INIT_MODULE_FILE_STREAM 0x10
/** Needed to use symbol providers. */
#define PHLIB_INIT_MODULE_SYMBOL_PROVIDER 0x20
#define PHLIB_INIT_MODULE_RESERVED5 0x40
PHLIBAPI
NTSTATUS
NTAPI
PhInitializePhLib(
VOID
);
PHLIBAPI
NTSTATUS
NTAPI
PhInitializePhLibEx(
_In_ ULONG Flags,
_In_opt_ SIZE_T HeapReserveSize,
_In_opt_ SIZE_T HeapCommitSize
);
#ifdef _WIN64
FORCEINLINE
BOOLEAN
PhIsExecutingInWow64(
VOID
)
{
return FALSE;
}
#else
PHLIBAPI
BOOLEAN
NTAPI
PhIsExecutingInWow64(
VOID
);
#endif
#ifdef __cplusplus
}
#endif
#endif

60
phlib/include/phdata.h Normal file
View File

@@ -0,0 +1,60 @@
#ifndef _PH_PHDATA_H
#define _PH_PHDATA_H
#ifdef __cplusplus
extern "C" {
#endif
// SIDs
extern SID PhSeNobodySid;
extern SID PhSeEveryoneSid;
extern SID PhSeLocalSid;
extern SID PhSeCreatorOwnerSid;
extern SID PhSeCreatorGroupSid;
extern SID PhSeDialupSid;
extern SID PhSeNetworkSid;
extern SID PhSeBatchSid;
extern SID PhSeInteractiveSid;
extern SID PhSeServiceSid;
extern SID PhSeAnonymousLogonSid;
extern SID PhSeProxySid;
extern SID PhSeAuthenticatedUserSid;
extern SID PhSeRestrictedCodeSid;
extern SID PhSeTerminalServerUserSid;
extern SID PhSeRemoteInteractiveLogonSid;
extern SID PhSeLocalSystemSid;
extern SID PhSeLocalServiceSid;
extern SID PhSeNetworkServiceSid;
// Unicode
extern PH_STRINGREF PhUnicodeByteOrderMark;
// Characters
extern BOOLEAN PhCharIsPrintable[256];
extern ULONG PhCharToInteger[256];
extern CHAR PhIntegerToChar[69];
extern CHAR PhIntegerToCharUpper[69];
// CRC32
extern ULONG PhCrc32Table[256];
// Enums
extern WCHAR *PhIoPriorityHintNames[MaxIoPriorityTypes];
extern WCHAR *PhPagePriorityNames[MEMORY_PRIORITY_NORMAL + 1];
extern WCHAR *PhKThreadStateNames[MaximumThreadState];
extern WCHAR *PhKWaitReasonNames[MaximumWaitReason];
#ifdef __cplusplus
}
#endif
#endif

49
phlib/include/phintrnl.h Normal file
View File

@@ -0,0 +1,49 @@
#ifndef _PH_PHINTRNL_H
#define _PH_PHINTRNL_H
typedef struct _PHLIB_STATISTICS_BLOCK
{
// basesup
ULONG BaseThreadsCreated;
ULONG BaseThreadsCreateFailed;
ULONG BaseStringBuildersCreated;
ULONG BaseStringBuildersResized;
// ref
ULONG RefObjectsCreated;
ULONG RefObjectsDestroyed;
ULONG RefObjectsAllocated;
ULONG RefObjectsFreed;
ULONG RefObjectsAllocatedFromSmallFreeList;
ULONG RefObjectsFreedToSmallFreeList;
ULONG RefObjectsAllocatedFromTypeFreeList;
ULONG RefObjectsFreedToTypeFreeList;
ULONG RefObjectsDeleteDeferred;
ULONG RefAutoPoolsCreated;
ULONG RefAutoPoolsDestroyed;
ULONG RefAutoPoolsDynamicAllocated;
ULONG RefAutoPoolsDynamicResized;
// queuedlock
ULONG QlBlockSpins;
ULONG QlBlockWaits;
ULONG QlAcquireExclusiveBlocks;
ULONG QlAcquireSharedBlocks;
// workqueue
ULONG WqWorkQueueThreadsCreated;
ULONG WqWorkQueueThreadsCreateFailed;
ULONG WqWorkItemsQueued;
} PHLIB_STATISTICS_BLOCK;
#ifdef DEBUG
extern PHLIB_STATISTICS_BLOCK PhLibStatisticsBlock;
#endif
#ifdef DEBUG
#define PHLIB_INC_STATISTIC(Name) (_InterlockedIncrement(&PhLibStatisticsBlock.Name))
#else
#define PHLIB_INC_STATISTIC(Name)
#endif
#endif

1042
phlib/include/phnative.h Normal file

File diff suppressed because it is too large Load Diff

968
phlib/include/phnativeinl.h Normal file
View File

@@ -0,0 +1,968 @@
#ifndef _PH_PHNATINL_H
#define _PH_PHNATINL_H
#pragma once
// This file contains inlined native API wrapper functions. These functions were previously
// exported, but are now inlined because they are extremely simple wrappers around equivalent native
// API functions.
/**
* Gets basic information for a process.
*
* \param ProcessHandle A handle to a process. The handle must have
* PROCESS_QUERY_LIMITED_INFORMATION access.
* \param BasicInformation A variable which receives the information.
*/
FORCEINLINE
NTSTATUS
PhGetProcessBasicInformation(
_In_ HANDLE ProcessHandle,
_Out_ PPROCESS_BASIC_INFORMATION BasicInformation
)
{
return NtQueryInformationProcess(
ProcessHandle,
ProcessBasicInformation,
BasicInformation,
sizeof(PROCESS_BASIC_INFORMATION),
NULL
);
}
/**
* Gets extended basic information for a process.
*
* \param ProcessHandle A handle to a process. The handle must have
* PROCESS_QUERY_LIMITED_INFORMATION access.
* \param ExtendedBasicInformation A variable which receives the information.
*/
FORCEINLINE
NTSTATUS
PhGetProcessExtendedBasicInformation(
_In_ HANDLE ProcessHandle,
_Out_ PPROCESS_EXTENDED_BASIC_INFORMATION ExtendedBasicInformation
)
{
ExtendedBasicInformation->Size = sizeof(PROCESS_EXTENDED_BASIC_INFORMATION);
return NtQueryInformationProcess(
ProcessHandle,
ProcessBasicInformation,
ExtendedBasicInformation,
sizeof(PROCESS_EXTENDED_BASIC_INFORMATION),
NULL
);
}
/**
* Gets time information for a process.
*
* \param ProcessHandle A handle to a process. The handle must have
* PROCESS_QUERY_LIMITED_INFORMATION access.
* \param Times A variable which receives the information.
*/
FORCEINLINE
NTSTATUS
PhGetProcessTimes(
_In_ HANDLE ProcessHandle,
_Out_ PKERNEL_USER_TIMES Times
)
{
return NtQueryInformationProcess(
ProcessHandle,
ProcessTimes,
Times,
sizeof(KERNEL_USER_TIMES),
NULL
);
}
/**
* Gets a process' session ID.
*
* \param ProcessHandle A handle to a process. The handle must have
* PROCESS_QUERY_LIMITED_INFORMATION access.
* \param SessionId A variable which receives the process' session ID.
*/
FORCEINLINE
NTSTATUS
PhGetProcessSessionId(
_In_ HANDLE ProcessHandle,
_Out_ PULONG SessionId
)
{
NTSTATUS status;
PROCESS_SESSION_INFORMATION sessionInfo;
status = NtQueryInformationProcess(
ProcessHandle,
ProcessSessionInformation,
&sessionInfo,
sizeof(PROCESS_SESSION_INFORMATION),
NULL
);
if (NT_SUCCESS(status))
{
*SessionId = sessionInfo.SessionId;
}
return status;
}
/**
* Gets whether a process is running under 32-bit emulation.
*
* \param ProcessHandle A handle to a process. The handle must have
* PROCESS_QUERY_LIMITED_INFORMATION access.
* \param IsWow64 A variable which receives a boolean indicating whether the process is 32-bit.
*/
FORCEINLINE
NTSTATUS
PhGetProcessIsWow64(
_In_ HANDLE ProcessHandle,
_Out_ PBOOLEAN IsWow64
)
{
NTSTATUS status;
ULONG_PTR wow64;
status = NtQueryInformationProcess(
ProcessHandle,
ProcessWow64Information,
&wow64,
sizeof(ULONG_PTR),
NULL
);
if (NT_SUCCESS(status))
{
*IsWow64 = !!wow64;
}
return status;
}
/**
* Gets a process' WOW64 PEB address.
*
* \param ProcessHandle A handle to a process. The handle must have
* PROCESS_QUERY_LIMITED_INFORMATION access.
* \param Peb32 A variable which receives the base address of the process' WOW64 PEB. If the process
* is 64-bit, the variable receives NULL.
*/
FORCEINLINE
NTSTATUS
PhGetProcessPeb32(
_In_ HANDLE ProcessHandle,
_Out_ PVOID *Peb32
)
{
NTSTATUS status;
ULONG_PTR wow64;
status = NtQueryInformationProcess(
ProcessHandle,
ProcessWow64Information,
&wow64,
sizeof(ULONG_PTR),
NULL
);
if (NT_SUCCESS(status))
{
*Peb32 = (PVOID)wow64;
}
return status;
}
/**
* Gets whether a process is being debugged.
*
* \param ProcessHandle A handle to a process. The handle must have PROCESS_QUERY_INFORMATION
* access.
* \param IsBeingDebugged A variable which receives a boolean indicating whether the process is
* being debugged.
*/
FORCEINLINE
NTSTATUS
PhGetProcessIsBeingDebugged(
_In_ HANDLE ProcessHandle,
_Out_ PBOOLEAN IsBeingDebugged
)
{
NTSTATUS status;
PVOID debugPort;
status = NtQueryInformationProcess(
ProcessHandle,
ProcessDebugPort,
&debugPort,
sizeof(PVOID),
NULL
);
if (NT_SUCCESS(status))
{
*IsBeingDebugged = !!debugPort;
}
return status;
}
/**
* Gets a handle to a process' debug object.
*
* \param ProcessHandle A handle to a process. The handle must have PROCESS_QUERY_INFORMATION
* access.
* \param DebugObjectHandle A variable which receives a handle to the debug object associated with
* the process. You must close the handle when you no longer need it.
*
* \retval STATUS_PORT_NOT_SET The process is not being debugged and has no associated debug object.
*/
FORCEINLINE
NTSTATUS
PhGetProcessDebugObject(
_In_ HANDLE ProcessHandle,
_Out_ PHANDLE DebugObjectHandle
)
{
return NtQueryInformationProcess(
ProcessHandle,
ProcessDebugObjectHandle,
DebugObjectHandle,
sizeof(HANDLE),
NULL
);
}
/**
* Gets a process' no-execute status.
*
* \param ProcessHandle A handle to a process. The handle must have PROCESS_QUERY_INFORMATION
* access.
* \param ExecuteFlags A variable which receives the no-execute flags.
*/
FORCEINLINE
NTSTATUS
PhGetProcessExecuteFlags(
_In_ HANDLE ProcessHandle,
_Out_ PULONG ExecuteFlags
)
{
return NtQueryInformationProcess(
ProcessHandle,
ProcessExecuteFlags,
ExecuteFlags,
sizeof(ULONG),
NULL
);
}
/**
* Gets a process' I/O priority.
*
* \param ProcessHandle A handle to a process. The handle must have
* PROCESS_QUERY_LIMITED_INFORMATION access.
* \param IoPriority A variable which receives the I/O priority of the process.
*/
FORCEINLINE
NTSTATUS
PhGetProcessIoPriority(
_In_ HANDLE ProcessHandle,
_Out_ IO_PRIORITY_HINT *IoPriority
)
{
return NtQueryInformationProcess(
ProcessHandle,
ProcessIoPriority,
IoPriority,
sizeof(IO_PRIORITY_HINT),
NULL
);
}
/**
* Gets a process' page priority.
*
* \param ProcessHandle A handle to a process. The handle must have
* PROCESS_QUERY_LIMITED_INFORMATION access.
* \param PagePriority A variable which receives the page priority of the process.
*/
FORCEINLINE
NTSTATUS
PhGetProcessPagePriority(
_In_ HANDLE ProcessHandle,
_Out_ PULONG PagePriority
)
{
NTSTATUS status;
PAGE_PRIORITY_INFORMATION pagePriorityInfo;
status = NtQueryInformationProcess(
ProcessHandle,
ProcessPagePriority,
&pagePriorityInfo,
sizeof(PAGE_PRIORITY_INFORMATION),
NULL
);
if (NT_SUCCESS(status))
{
*PagePriority = pagePriorityInfo.PagePriority;
}
return status;
}
/**
* Gets a process' cycle count.
*
* \param ProcessHandle A handle to a process. The handle must have
* PROCESS_QUERY_LIMITED_INFORMATION access.
* \param CycleTime A variable which receives the 64-bit cycle time.
*/
FORCEINLINE
NTSTATUS
PhGetProcessCycleTime(
_In_ HANDLE ProcessHandle,
_Out_ PULONG64 CycleTime
)
{
NTSTATUS status;
PROCESS_CYCLE_TIME_INFORMATION cycleTimeInfo;
status = NtQueryInformationProcess(
ProcessHandle,
ProcessCycleTime,
&cycleTimeInfo,
sizeof(PROCESS_CYCLE_TIME_INFORMATION),
NULL
);
if (!NT_SUCCESS(status))
return status;
*CycleTime = cycleTimeInfo.AccumulatedCycles;
return status;
}
FORCEINLINE
NTSTATUS
PhGetProcessConsoleHostProcessId(
_In_ HANDLE ProcessHandle,
_Out_ PHANDLE ConsoleHostProcessId
)
{
NTSTATUS status;
ULONG_PTR consoleHostProcess;
status = NtQueryInformationProcess(
ProcessHandle,
ProcessConsoleHostProcess,
&consoleHostProcess,
sizeof(ULONG_PTR),
NULL
);
if (!NT_SUCCESS(status))
return status;
*ConsoleHostProcessId = (HANDLE)consoleHostProcess;
return status;
}
/**
* Sets a process' affinity mask.
*
* \param ProcessHandle A handle to a process. The handle must have PROCESS_SET_INFORMATION access.
* \param AffinityMask The new affinity mask.
*/
FORCEINLINE
NTSTATUS
PhSetProcessAffinityMask(
_In_ HANDLE ProcessHandle,
_In_ ULONG_PTR AffinityMask
)
{
return NtSetInformationProcess(
ProcessHandle,
ProcessAffinityMask,
&AffinityMask,
sizeof(ULONG_PTR)
);
}
/**
* Sets a process' I/O priority.
*
* \param ProcessHandle A handle to a process. The handle must have PROCESS_SET_INFORMATION access.
* \param IoPriority The new I/O priority.
*/
FORCEINLINE
NTSTATUS
PhSetProcessIoPriority(
_In_ HANDLE ProcessHandle,
_In_ IO_PRIORITY_HINT IoPriority
)
{
return NtSetInformationProcess(
ProcessHandle,
ProcessIoPriority,
&IoPriority,
sizeof(IO_PRIORITY_HINT)
);
}
/**
* Gets basic information for a thread.
*
* \param ThreadHandle A handle to a thread. The handle must have THREAD_QUERY_LIMITED_INFORMATION
* access.
* \param BasicInformation A variable which receives the information.
*/
FORCEINLINE
NTSTATUS
PhGetThreadBasicInformation(
_In_ HANDLE ThreadHandle,
_Out_ PTHREAD_BASIC_INFORMATION BasicInformation
)
{
return NtQueryInformationThread(
ThreadHandle,
ThreadBasicInformation,
BasicInformation,
sizeof(THREAD_BASIC_INFORMATION),
NULL
);
}
/**
* Gets a thread's I/O priority.
*
* \param ThreadHandle A handle to a thread. The handle must have THREAD_QUERY_LIMITED_INFORMATION
* access.
* \param IoPriority A variable which receives the I/O priority of the thread.
*/
FORCEINLINE
NTSTATUS
PhGetThreadIoPriority(
_In_ HANDLE ThreadHandle,
_Out_ IO_PRIORITY_HINT *IoPriority
)
{
return NtQueryInformationThread(
ThreadHandle,
ThreadIoPriority,
IoPriority,
sizeof(IO_PRIORITY_HINT),
NULL
);
}
/**
* Gets a thread's page priority.
*
* \param ThreadHandle A handle to a thread. The handle must have THREAD_QUERY_LIMITED_INFORMATION
* access.
* \param PagePriority A variable which receives the page priority of the thread.
*/
FORCEINLINE
NTSTATUS
PhGetThreadPagePriority(
_In_ HANDLE ThreadHandle,
_Out_ PULONG PagePriority
)
{
NTSTATUS status;
PAGE_PRIORITY_INFORMATION pagePriorityInfo;
status = NtQueryInformationThread(
ThreadHandle,
ThreadPagePriority,
&pagePriorityInfo,
sizeof(PAGE_PRIORITY_INFORMATION),
NULL
);
if (NT_SUCCESS(status))
{
*PagePriority = pagePriorityInfo.PagePriority;
}
return status;
}
/**
* Gets a thread's cycle count.
*
* \param ThreadHandle A handle to a thread. The handle must have THREAD_QUERY_LIMITED_INFORMATION
* access.
* \param CycleTime A variable which receives the 64-bit cycle time.
*/
FORCEINLINE
NTSTATUS
PhGetThreadCycleTime(
_In_ HANDLE ThreadHandle,
_Out_ PULONG64 CycleTime
)
{
NTSTATUS status;
THREAD_CYCLE_TIME_INFORMATION cycleTimeInfo;
status = NtQueryInformationThread(
ThreadHandle,
ThreadCycleTime,
&cycleTimeInfo,
sizeof(THREAD_CYCLE_TIME_INFORMATION),
NULL
);
if (!NT_SUCCESS(status))
return status;
*CycleTime = cycleTimeInfo.AccumulatedCycles;
return status;
}
/**
* Sets a thread's affinity mask.
*
* \param ThreadHandle A handle to a thread. The handle must have THREAD_SET_LIMITED_INFORMATION
* access.
* \param AffinityMask The new affinity mask.
*/
FORCEINLINE
NTSTATUS
PhSetThreadAffinityMask(
_In_ HANDLE ThreadHandle,
_In_ ULONG_PTR AffinityMask
)
{
return NtSetInformationThread(
ThreadHandle,
ThreadAffinityMask,
&AffinityMask,
sizeof(ULONG_PTR)
);
}
/**
* Sets a thread's I/O priority.
*
* \param ThreadHandle A handle to a thread. The handle must have THREAD_SET_LIMITED_INFORMATION
* access.
* \param IoPriority The new I/O priority.
*/
FORCEINLINE
NTSTATUS
PhSetThreadIoPriority(
_In_ HANDLE ThreadHandle,
_In_ IO_PRIORITY_HINT IoPriority
)
{
return NtSetInformationThread(
ThreadHandle,
ThreadIoPriority,
&IoPriority,
sizeof(IO_PRIORITY_HINT)
);
}
FORCEINLINE
NTSTATUS
PhGetJobBasicAndIoAccounting(
_In_ HANDLE JobHandle,
_Out_ PJOBOBJECT_BASIC_AND_IO_ACCOUNTING_INFORMATION BasicAndIoAccounting
)
{
return NtQueryInformationJobObject(
JobHandle,
JobObjectBasicAndIoAccountingInformation,
BasicAndIoAccounting,
sizeof(JOBOBJECT_BASIC_AND_IO_ACCOUNTING_INFORMATION),
NULL
);
}
FORCEINLINE
NTSTATUS
PhGetJobBasicLimits(
_In_ HANDLE JobHandle,
_Out_ PJOBOBJECT_BASIC_LIMIT_INFORMATION BasicLimits
)
{
return NtQueryInformationJobObject(
JobHandle,
JobObjectBasicLimitInformation,
BasicLimits,
sizeof(JOBOBJECT_BASIC_LIMIT_INFORMATION),
NULL
);
}
FORCEINLINE
NTSTATUS
PhGetJobExtendedLimits(
_In_ HANDLE JobHandle,
_Out_ PJOBOBJECT_EXTENDED_LIMIT_INFORMATION ExtendedLimits
)
{
return NtQueryInformationJobObject(
JobHandle,
JobObjectExtendedLimitInformation,
ExtendedLimits,
sizeof(JOBOBJECT_EXTENDED_LIMIT_INFORMATION),
NULL
);
}
FORCEINLINE
NTSTATUS
PhGetJobBasicUiRestrictions(
_In_ HANDLE JobHandle,
_Out_ PJOBOBJECT_BASIC_UI_RESTRICTIONS BasicUiRestrictions
)
{
return NtQueryInformationJobObject(
JobHandle,
JobObjectBasicUIRestrictions,
BasicUiRestrictions,
sizeof(JOBOBJECT_BASIC_UI_RESTRICTIONS),
NULL
);
}
/**
* Gets a token's session ID.
*
* \param TokenHandle A handle to a token. The handle must have TOKEN_QUERY access.
* \param SessionId A variable which receives the session ID.
*/
FORCEINLINE
NTSTATUS
PhGetTokenSessionId(
_In_ HANDLE TokenHandle,
_Out_ PULONG SessionId
)
{
ULONG returnLength;
return NtQueryInformationToken(
TokenHandle,
TokenSessionId,
SessionId,
sizeof(ULONG),
&returnLength
);
}
/**
* Gets a token's elevation type.
*
* \param TokenHandle A handle to a token. The handle must have TOKEN_QUERY access.
* \param ElevationType A variable which receives the elevation type.
*/
FORCEINLINE
NTSTATUS
PhGetTokenElevationType(
_In_ HANDLE TokenHandle,
_Out_ PTOKEN_ELEVATION_TYPE ElevationType
)
{
ULONG returnLength;
return NtQueryInformationToken(
TokenHandle,
TokenElevationType,
ElevationType,
sizeof(TOKEN_ELEVATION_TYPE),
&returnLength
);
}
/**
* Gets whether a token is elevated.
*
* \param TokenHandle A handle to a token. The handle must have TOKEN_QUERY access.
* \param Elevated A variable which receives a boolean indicating whether the token is elevated.
*/
FORCEINLINE
NTSTATUS
PhGetTokenIsElevated(
_In_ HANDLE TokenHandle,
_Out_ PBOOLEAN Elevated
)
{
NTSTATUS status;
TOKEN_ELEVATION elevation;
ULONG returnLength;
status = NtQueryInformationToken(
TokenHandle,
TokenElevation,
&elevation,
sizeof(TOKEN_ELEVATION),
&returnLength
);
if (NT_SUCCESS(status))
{
*Elevated = !!elevation.TokenIsElevated;
}
return status;
}
/**
* Gets a token's statistics.
*
* \param TokenHandle A handle to a token. The handle must have TOKEN_QUERY access.
* \param Statistics A variable which receives the token's statistics.
*/
FORCEINLINE
NTSTATUS
PhGetTokenStatistics(
_In_ HANDLE TokenHandle,
_Out_ PTOKEN_STATISTICS Statistics
)
{
ULONG returnLength;
return NtQueryInformationToken(
TokenHandle,
TokenStatistics,
Statistics,
sizeof(TOKEN_STATISTICS),
&returnLength
);
}
/**
* Gets a token's source.
*
* \param TokenHandle A handle to a token. The handle must have TOKEN_QUERY_SOURCE access.
* \param Source A variable which receives the token's source.
*/
FORCEINLINE
NTSTATUS
PhGetTokenSource(
_In_ HANDLE TokenHandle,
_Out_ PTOKEN_SOURCE Source
)
{
ULONG returnLength;
return NtQueryInformationToken(
TokenHandle,
TokenSource,
Source,
sizeof(TOKEN_SOURCE),
&returnLength
);
}
/**
* Gets a handle to a token's linked token.
*
* \param TokenHandle A handle to a token. The handle must have TOKEN_QUERY access.
* \param LinkedTokenHandle A variable which receives a handle to the linked token. You must close
* the handle using NtClose() when you no longer need it.
*/
FORCEINLINE
NTSTATUS
PhGetTokenLinkedToken(
_In_ HANDLE TokenHandle,
_Out_ PHANDLE LinkedTokenHandle
)
{
NTSTATUS status;
ULONG returnLength;
TOKEN_LINKED_TOKEN linkedToken;
status = NtQueryInformationToken(
TokenHandle,
TokenLinkedToken,
&linkedToken,
sizeof(TOKEN_LINKED_TOKEN),
&returnLength
);
if (!NT_SUCCESS(status))
return status;
*LinkedTokenHandle = linkedToken.LinkedToken;
return status;
}
/**
* Gets whether virtualization is allowed for a token.
*
* \param TokenHandle A handle to a token. The handle must have TOKEN_QUERY access.
* \param IsVirtualizationAllowed A variable which receives a boolean indicating whether
* virtualization is allowed for the token.
*/
FORCEINLINE
NTSTATUS
PhGetTokenIsVirtualizationAllowed(
_In_ HANDLE TokenHandle,
_Out_ PBOOLEAN IsVirtualizationAllowed
)
{
NTSTATUS status;
ULONG returnLength;
ULONG virtualizationAllowed;
status = NtQueryInformationToken(
TokenHandle,
TokenVirtualizationAllowed,
&virtualizationAllowed,
sizeof(ULONG),
&returnLength
);
if (!NT_SUCCESS(status))
return status;
*IsVirtualizationAllowed = !!virtualizationAllowed;
return status;
}
/**
* Gets whether virtualization is enabled for a token.
*
* \param TokenHandle A handle to a token. The handle must have TOKEN_QUERY access.
* \param IsVirtualizationEnabled A variable which receives a boolean indicating whether
* virtualization is enabled for the token.
*/
FORCEINLINE
NTSTATUS
PhGetTokenIsVirtualizationEnabled(
_In_ HANDLE TokenHandle,
_Out_ PBOOLEAN IsVirtualizationEnabled
)
{
NTSTATUS status;
ULONG returnLength;
ULONG virtualizationEnabled;
status = NtQueryInformationToken(
TokenHandle,
TokenVirtualizationEnabled,
&virtualizationEnabled,
sizeof(ULONG),
&returnLength
);
if (!NT_SUCCESS(status))
return status;
*IsVirtualizationEnabled = !!virtualizationEnabled;
return status;
}
FORCEINLINE
NTSTATUS
PhGetEventBasicInformation(
_In_ HANDLE EventHandle,
_Out_ PEVENT_BASIC_INFORMATION BasicInformation
)
{
return NtQueryEvent(
EventHandle,
EventBasicInformation,
BasicInformation,
sizeof(EVENT_BASIC_INFORMATION),
NULL
);
}
FORCEINLINE
NTSTATUS
PhGetMutantBasicInformation(
_In_ HANDLE MutantHandle,
_Out_ PMUTANT_BASIC_INFORMATION BasicInformation
)
{
return NtQueryMutant(
MutantHandle,
MutantBasicInformation,
BasicInformation,
sizeof(MUTANT_BASIC_INFORMATION),
NULL
);
}
FORCEINLINE
NTSTATUS
PhGetMutantOwnerInformation(
_In_ HANDLE MutantHandle,
_Out_ PMUTANT_OWNER_INFORMATION OwnerInformation
)
{
return NtQueryMutant(
MutantHandle,
MutantOwnerInformation,
OwnerInformation,
sizeof(MUTANT_OWNER_INFORMATION),
NULL
);
}
FORCEINLINE
NTSTATUS
PhGetSectionBasicInformation(
_In_ HANDLE SectionHandle,
_Out_ PSECTION_BASIC_INFORMATION BasicInformation
)
{
return NtQuerySection(
SectionHandle,
SectionBasicInformation,
BasicInformation,
sizeof(SECTION_BASIC_INFORMATION),
NULL
);
}
FORCEINLINE
NTSTATUS
PhGetSemaphoreBasicInformation(
_In_ HANDLE SemaphoreHandle,
_Out_ PSEMAPHORE_BASIC_INFORMATION BasicInformation
)
{
return NtQuerySemaphore(
SemaphoreHandle,
SemaphoreBasicInformation,
BasicInformation,
sizeof(SEMAPHORE_BASIC_INFORMATION),
NULL
);
}
FORCEINLINE
NTSTATUS
PhGetTimerBasicInformation(
_In_ HANDLE TimerHandle,
_Out_ PTIMER_BASIC_INFORMATION BasicInformation
)
{
return NtQueryTimer(
TimerHandle,
TimerBasicInformation,
BasicInformation,
sizeof(TIMER_BASIC_INFORMATION),
NULL
);
}
#endif

139
phlib/include/phnet.h Normal file
View File

@@ -0,0 +1,139 @@
#ifndef _PH_PHNET_H
#define _PH_PHNET_H
#include <inaddr.h>
#include <in6addr.h>
#define PH_IPV4_NETWORK_TYPE 0x1
#define PH_IPV6_NETWORK_TYPE 0x2
#define PH_NETWORK_TYPE_MASK 0x3
#define PH_TCP_PROTOCOL_TYPE 0x10
#define PH_UDP_PROTOCOL_TYPE 0x20
#define PH_PROTOCOL_TYPE_MASK 0x30
#define PH_NO_NETWORK_PROTOCOL 0x0
#define PH_TCP4_NETWORK_PROTOCOL (PH_IPV4_NETWORK_TYPE | PH_TCP_PROTOCOL_TYPE)
#define PH_TCP6_NETWORK_PROTOCOL (PH_IPV6_NETWORK_TYPE | PH_TCP_PROTOCOL_TYPE)
#define PH_UDP4_NETWORK_PROTOCOL (PH_IPV4_NETWORK_TYPE | PH_UDP_PROTOCOL_TYPE)
#define PH_UDP6_NETWORK_PROTOCOL (PH_IPV6_NETWORK_TYPE | PH_UDP_PROTOCOL_TYPE)
typedef struct _PH_IP_ADDRESS
{
ULONG Type;
union
{
ULONG Ipv4;
struct in_addr InAddr;
UCHAR Ipv6[16];
struct in6_addr In6Addr;
};
} PH_IP_ADDRESS, *PPH_IP_ADDRESS;
FORCEINLINE BOOLEAN PhEqualIpAddress(
_In_ PPH_IP_ADDRESS Address1,
_In_ PPH_IP_ADDRESS Address2
)
{
if ((Address1->Type | Address2->Type) == 0) // don't check addresses if both are invalid
return TRUE;
if (Address1->Type != Address2->Type)
return FALSE;
if (Address1->Type == PH_IPV4_NETWORK_TYPE)
{
return Address1->Ipv4 == Address2->Ipv4;
}
else
{
#ifdef _WIN64
return
*(PULONG64)(Address1->Ipv6) == *(PULONG64)(Address2->Ipv6) &&
*(PULONG64)(Address1->Ipv6 + 8) == *(PULONG64)(Address2->Ipv6 + 8);
#else
return
*(PULONG)(Address1->Ipv6) == *(PULONG)(Address2->Ipv6) &&
*(PULONG)(Address1->Ipv6 + 4) == *(PULONG)(Address2->Ipv6 + 4) &&
*(PULONG)(Address1->Ipv6 + 8) == *(PULONG)(Address2->Ipv6 + 8) &&
*(PULONG)(Address1->Ipv6 + 12) == *(PULONG)(Address2->Ipv6 + 12);
#endif
}
}
FORCEINLINE ULONG PhHashIpAddress(
_In_ PPH_IP_ADDRESS Address
)
{
ULONG hash = 0;
if (Address->Type == 0)
return 0;
hash = Address->Type | (Address->Type << 16);
if (Address->Type == PH_IPV4_NETWORK_TYPE)
{
hash ^= Address->Ipv4;
}
else
{
hash += *(PULONG)(Address->Ipv6);
hash ^= *(PULONG)(Address->Ipv6 + 4);
hash += *(PULONG)(Address->Ipv6 + 8);
hash ^= *(PULONG)(Address->Ipv6 + 12);
}
return hash;
}
FORCEINLINE BOOLEAN PhIsNullIpAddress(
_In_ PPH_IP_ADDRESS Address
)
{
if (Address->Type == 0)
{
return TRUE;
}
else if (Address->Type == PH_IPV4_NETWORK_TYPE)
{
return Address->Ipv4 == 0;
}
else if (Address->Type == PH_IPV6_NETWORK_TYPE)
{
#ifdef _WIN64
return (*(PULONG64)(Address->Ipv6) | *(PULONG64)(Address->Ipv6 + 8)) == 0;
#else
return (*(PULONG)(Address->Ipv6) | *(PULONG)(Address->Ipv6 + 4) |
*(PULONG)(Address->Ipv6 + 8) | *(PULONG)(Address->Ipv6 + 12)) == 0;
#endif
}
else
{
return TRUE;
}
}
typedef struct _PH_IP_ENDPOINT
{
PH_IP_ADDRESS Address;
ULONG Port;
} PH_IP_ENDPOINT, *PPH_IP_ENDPOINT;
FORCEINLINE BOOLEAN PhEqualIpEndpoint(
_In_ PPH_IP_ENDPOINT Endpoint1,
_In_ PPH_IP_ENDPOINT Endpoint2
)
{
return
PhEqualIpAddress(&Endpoint1->Address, &Endpoint2->Address) &&
Endpoint1->Port == Endpoint2->Port;
}
FORCEINLINE ULONG PhHashIpEndpoint(
_In_ PPH_IP_ENDPOINT Endpoint
)
{
return PhHashIpAddress(&Endpoint->Address) ^ Endpoint->Port;
}
#endif

546
phlib/include/phsup.h Normal file
View File

@@ -0,0 +1,546 @@
#ifndef _PH_PHSUP_H
#define _PH_PHSUP_H
// This header file provides some useful definitions specific to phlib.
#include <intrin.h>
#include <wchar.h>
#include <assert.h>
#include <stdio.h>
// Memory
#define PTR_ADD_OFFSET(Pointer, Offset) ((PVOID)((ULONG_PTR)(Pointer) + (ULONG_PTR)(Offset)))
#define PTR_SUB_OFFSET(Pointer, Offset) ((PVOID)((ULONG_PTR)(Pointer) - (ULONG_PTR)(Offset)))
#define ALIGN_UP_BY(Address, Align) (((ULONG_PTR)(Address) + (Align) - 1) & ~((Align) - 1))
#define ALIGN_UP_POINTER_BY(Pointer, Align) ((PVOID)ALIGN_UP_BY(Pointer, Align))
#define ALIGN_UP(Address, Type) ALIGN_UP_BY(Address, sizeof(Type))
#define ALIGN_UP_POINTER(Pointer, Type) ((PVOID)ALIGN_UP(Pointer, Type))
#define PAGE_SIZE 0x1000
#define PH_LARGE_BUFFER_SIZE (256 * 1024 * 1024)
// Exceptions
#define PhRaiseStatus(Status) RtlRaiseStatus(Status)
#define SIMPLE_EXCEPTION_FILTER(Condition) \
((Condition) ? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH)
// Compiler
#ifdef DEBUG
#define ASSUME_ASSERT(Expression) assert(Expression)
#define ASSUME_NO_DEFAULT assert(FALSE)
#else
#define ASSUME_ASSERT(Expression) __assume(Expression)
#define ASSUME_NO_DEFAULT __assume(FALSE)
#endif
// Time
#define PH_TICKS_PER_NS ((LONG64)1 * 10)
#define PH_TICKS_PER_MS (PH_TICKS_PER_NS * 1000)
#define PH_TICKS_PER_SEC (PH_TICKS_PER_MS * 1000)
#define PH_TICKS_PER_MIN (PH_TICKS_PER_SEC * 60)
#define PH_TICKS_PER_HOUR (PH_TICKS_PER_MIN * 60)
#define PH_TICKS_PER_DAY (PH_TICKS_PER_HOUR * 24)
#define PH_TICKS_PARTIAL_MS(Ticks) (((ULONG64)(Ticks) / PH_TICKS_PER_MS) % 1000)
#define PH_TICKS_PARTIAL_SEC(Ticks) (((ULONG64)(Ticks) / PH_TICKS_PER_SEC) % 60)
#define PH_TICKS_PARTIAL_MIN(Ticks) (((ULONG64)(Ticks) / PH_TICKS_PER_MIN) % 60)
#define PH_TICKS_PARTIAL_HOURS(Ticks) (((ULONG64)(Ticks) / PH_TICKS_PER_HOUR) % 24)
#define PH_TICKS_PARTIAL_DAYS(Ticks) ((ULONG64)(Ticks) / PH_TICKS_PER_DAY)
#define PH_TIMEOUT_MS PH_TICKS_PER_MS
#define PH_TIMEOUT_SEC PH_TICKS_PER_SEC
// Annotations
/**
* Indicates that a function assumes the specified number of references are available for the
* object.
*
* \remarks Usually functions reference objects if they store them for later usage; this annotation
* specifies that the caller must supply these extra references itself. In effect these references
* are "transferred" to the function and must not be used. E.g. if you create an object and
* immediately call a function with _Assume_refs_(1), you may no longer use the object since that
* one reference you held is no longer yours.
*/
#define _Assume_refs_(count)
#define _Callback_
/**
* Indicates that a function may raise a software exception.
*
* \remarks Do not use this annotation for temporary usages of exceptions, e.g. unimplemented
* functions.
*/
#define _May_raise_
/**
* Indicates that a function requires the specified value to be aligned at the specified number of
* bytes.
*/
#define _Needs_align_(align)
// Casts
// Zero extension and sign extension macros
#define C_1uTo2(x) ((unsigned short)(unsigned char)(x))
#define C_1sTo2(x) ((unsigned short)(signed char)(x))
#define C_1uTo4(x) ((unsigned int)(unsigned char)(x))
#define C_1sTo4(x) ((unsigned int)(signed char)(x))
#define C_2uTo4(x) ((unsigned int)(unsigned short)(x))
#define C_2sTo4(x) ((unsigned int)(signed short)(x))
#define C_4uTo8(x) ((unsigned __int64)(unsigned int)(x))
#define C_4sTo8(x) ((unsigned __int64)(signed int)(x))
// Sorting
typedef enum _PH_SORT_ORDER
{
NoSortOrder = 0,
AscendingSortOrder,
DescendingSortOrder
} PH_SORT_ORDER, *PPH_SORT_ORDER;
FORCEINLINE LONG PhModifySort(
_In_ LONG Result,
_In_ PH_SORT_ORDER Order
)
{
if (Order == AscendingSortOrder)
return Result;
else if (Order == DescendingSortOrder)
return -Result;
else
return Result;
}
#define PH_BUILTIN_COMPARE(value1, value2) \
if (value1 > value2) \
return 1; \
else if (value1 < value2) \
return -1; \
\
return 0
FORCEINLINE int charcmp(
_In_ signed char value1,
_In_ signed char value2
)
{
return C_1sTo4(value1 - value2);
}
FORCEINLINE int ucharcmp(
_In_ unsigned char value1,
_In_ unsigned char value2
)
{
PH_BUILTIN_COMPARE(value1, value2);
}
FORCEINLINE int shortcmp(
_In_ signed short value1,
_In_ signed short value2
)
{
return C_2sTo4(value1 - value2);
}
FORCEINLINE int ushortcmp(
_In_ unsigned short value1,
_In_ unsigned short value2
)
{
PH_BUILTIN_COMPARE(value1, value2);
}
FORCEINLINE int intcmp(
_In_ int value1,
_In_ int value2
)
{
return value1 - value2;
}
FORCEINLINE int uintcmp(
_In_ unsigned int value1,
_In_ unsigned int value2
)
{
PH_BUILTIN_COMPARE(value1, value2);
}
FORCEINLINE int int64cmp(
_In_ __int64 value1,
_In_ __int64 value2
)
{
PH_BUILTIN_COMPARE(value1, value2);
}
FORCEINLINE int uint64cmp(
_In_ unsigned __int64 value1,
_In_ unsigned __int64 value2
)
{
PH_BUILTIN_COMPARE(value1, value2);
}
FORCEINLINE int intptrcmp(
_In_ LONG_PTR value1,
_In_ LONG_PTR value2
)
{
PH_BUILTIN_COMPARE(value1, value2);
}
FORCEINLINE int uintptrcmp(
_In_ ULONG_PTR value1,
_In_ ULONG_PTR value2
)
{
PH_BUILTIN_COMPARE(value1, value2);
}
FORCEINLINE int singlecmp(
_In_ float value1,
_In_ float value2
)
{
PH_BUILTIN_COMPARE(value1, value2);
}
FORCEINLINE int doublecmp(
_In_ double value1,
_In_ double value2
)
{
PH_BUILTIN_COMPARE(value1, value2);
}
FORCEINLINE int wcsicmp2(
_In_opt_ PWSTR Value1,
_In_opt_ PWSTR Value2
)
{
if (Value1 && Value2)
return _wcsicmp(Value1, Value2);
else if (!Value1)
return !Value2 ? 0 : -1;
else
return 1;
}
typedef int (__cdecl *PC_COMPARE_FUNCTION)(void *, const void *, const void *);
// Synchronization
#ifndef _WIN64
#ifndef _InterlockedCompareExchangePointer
void *_InterlockedCompareExchangePointer(
void *volatile *Destination,
void *Exchange,
void *Comparand
);
#endif
#if (_MSC_VER < 1900)
#ifndef _InterlockedExchangePointer
FORCEINLINE void *_InterlockedExchangePointer(
void *volatile *Destination,
void *Exchange
)
{
return (PVOID)_InterlockedExchange(
(PLONG_PTR)Destination,
(LONG_PTR)Exchange
);
}
#endif
#endif
#endif
FORCEINLINE LONG_PTR _InterlockedExchangeAddPointer(
_Inout_ _Interlocked_operand_ LONG_PTR volatile *Addend,
_In_ LONG_PTR Value
)
{
#ifdef _WIN64
return (LONG_PTR)_InterlockedExchangeAdd64((PLONG64)Addend, (LONG64)Value);
#else
return (LONG_PTR)_InterlockedExchangeAdd((PLONG)Addend, (LONG)Value);
#endif
}
FORCEINLINE LONG_PTR _InterlockedIncrementPointer(
_Inout_ _Interlocked_operand_ LONG_PTR volatile *Addend
)
{
#ifdef _WIN64
return (LONG_PTR)_InterlockedIncrement64((PLONG64)Addend);
#else
return (LONG_PTR)_InterlockedIncrement((PLONG)Addend);
#endif
}
FORCEINLINE LONG_PTR _InterlockedDecrementPointer(
_Inout_ _Interlocked_operand_ LONG_PTR volatile *Addend
)
{
#ifdef _WIN64
return (LONG_PTR)_InterlockedDecrement64((PLONG64)Addend);
#else
return (LONG_PTR)_InterlockedDecrement((PLONG)Addend);
#endif
}
FORCEINLINE BOOLEAN _InterlockedBitTestAndResetPointer(
_Inout_ _Interlocked_operand_ LONG_PTR volatile *Base,
_In_ LONG_PTR Bit
)
{
#ifdef _WIN64
return _interlockedbittestandreset64((PLONG64)Base, (LONG64)Bit);
#else
return _interlockedbittestandreset((PLONG)Base, (LONG)Bit);
#endif
}
FORCEINLINE BOOLEAN _InterlockedBitTestAndSetPointer(
_Inout_ _Interlocked_operand_ LONG_PTR volatile *Base,
_In_ LONG_PTR Bit
)
{
#ifdef _WIN64
return _interlockedbittestandset64((PLONG64)Base, (LONG64)Bit);
#else
return _interlockedbittestandset((PLONG)Base, (LONG)Bit);
#endif
}
FORCEINLINE BOOLEAN _InterlockedIncrementNoZero(
_Inout_ _Interlocked_operand_ LONG volatile *Addend
)
{
LONG value;
LONG newValue;
value = *Addend;
while (TRUE)
{
if (value == 0)
return FALSE;
if ((newValue = _InterlockedCompareExchange(
Addend,
value + 1,
value
)) == value)
{
return TRUE;
}
value = newValue;
}
}
FORCEINLINE BOOLEAN _InterlockedIncrementPositive(
_Inout_ _Interlocked_operand_ LONG volatile *Addend
)
{
LONG value;
LONG newValue;
value = *Addend;
while (TRUE)
{
if (value <= 0)
return FALSE;
if ((newValue = _InterlockedCompareExchange(
Addend,
value + 1,
value
)) == value)
{
return TRUE;
}
value = newValue;
}
}
// Strings
#define PH_INT32_STR_LEN 12
#define PH_INT32_STR_LEN_1 (PH_INT32_STR_LEN + 1)
#define PH_INT64_STR_LEN 50
#define PH_INT64_STR_LEN_1 (PH_INT64_STR_LEN + 1)
#define PH_PTR_STR_LEN 24
#define PH_PTR_STR_LEN_1 (PH_PTR_STR_LEN + 1)
FORCEINLINE VOID PhPrintInt32(
_Out_writes_(PH_INT32_STR_LEN_1) PWSTR Destination,
_In_ LONG Int32
)
{
_ltow(Int32, Destination, 10);
}
FORCEINLINE VOID PhPrintUInt32(
_Out_writes_(PH_INT32_STR_LEN_1) PWSTR Destination,
_In_ ULONG UInt32
)
{
_ultow(UInt32, Destination, 10);
}
FORCEINLINE VOID PhPrintInt64(
_Out_writes_(PH_INT64_STR_LEN_1) PWSTR Destination,
_In_ LONG64 Int64
)
{
_i64tow(Int64, Destination, 10);
}
FORCEINLINE VOID PhPrintUInt64(
_Out_writes_(PH_INT64_STR_LEN_1) PWSTR Destination,
_In_ ULONG64 UInt64
)
{
_ui64tow(UInt64, Destination, 10);
}
FORCEINLINE VOID PhPrintPointer(
_Out_writes_(PH_PTR_STR_LEN_1) PWSTR Destination,
_In_ PVOID Pointer
)
{
Destination[0] = '0';
Destination[1] = 'x';
#ifdef _WIN64
_ui64tow((ULONG64)Pointer, &Destination[2], 16);
#else
_ultow((ULONG)Pointer, &Destination[2], 16);
#endif
}
// Misc.
FORCEINLINE ULONG PhCountBits(
_In_ ULONG Value
)
{
ULONG count = 0;
while (Value)
{
count++;
Value &= Value - 1;
}
return count;
}
FORCEINLINE ULONG PhRoundNumber(
_In_ ULONG Value,
_In_ ULONG Granularity
)
{
return (Value + Granularity / 2) / Granularity * Granularity;
}
FORCEINLINE ULONG PhMultiplyDivide(
_In_ ULONG Number,
_In_ ULONG Numerator,
_In_ ULONG Denominator
)
{
return (ULONG)(((ULONG64)Number * (ULONG64)Numerator + Denominator / 2) / (ULONG64)Denominator);
}
FORCEINLINE LONG PhMultiplyDivideSigned(
_In_ LONG Number,
_In_ ULONG Numerator,
_In_ ULONG Denominator
)
{
if (Number >= 0)
return PhMultiplyDivide(Number, Numerator, Denominator);
else
return -(LONG)PhMultiplyDivide(-Number, Numerator, Denominator);
}
FORCEINLINE VOID PhProbeAddress(
_In_ PVOID UserAddress,
_In_ SIZE_T UserLength,
_In_ PVOID BufferAddress,
_In_ SIZE_T BufferLength,
_In_ ULONG Alignment
)
{
if (UserLength != 0)
{
if (((ULONG_PTR)UserAddress & (Alignment - 1)) != 0)
PhRaiseStatus(STATUS_DATATYPE_MISALIGNMENT);
if (
((ULONG_PTR)UserAddress + UserLength < (ULONG_PTR)UserAddress) ||
((ULONG_PTR)UserAddress < (ULONG_PTR)BufferAddress) ||
((ULONG_PTR)UserAddress + UserLength > (ULONG_PTR)BufferAddress + BufferLength)
)
PhRaiseStatus(STATUS_ACCESS_VIOLATION);
}
}
FORCEINLINE PLARGE_INTEGER PhTimeoutFromMilliseconds(
_Out_ PLARGE_INTEGER Timeout,
_In_ ULONG Milliseconds
)
{
if (Milliseconds == INFINITE)
return NULL;
Timeout->QuadPart = -(LONGLONG)UInt32x32To64(Milliseconds, PH_TIMEOUT_MS);
return Timeout;
}
FORCEINLINE NTSTATUS PhGetLastWin32ErrorAsNtStatus()
{
ULONG win32Result;
// This is needed because NTSTATUS_FROM_WIN32 uses the argument multiple times.
win32Result = GetLastError();
return NTSTATUS_FROM_WIN32(win32Result);
}
FORCEINLINE PVOID PhGetModuleProcAddress(
_In_ PWSTR ModuleName,
_In_ PSTR ProcName
)
{
HMODULE module;
module = GetModuleHandle(ModuleName);
if (module)
return GetProcAddress(module, ProcName);
else
return NULL;
}
#endif

1049
phlib/include/phutil.h Normal file

File diff suppressed because it is too large Load Diff

139
phlib/include/provider.h Normal file
View File

@@ -0,0 +1,139 @@
#ifndef _PH_PROVIDER_H
#define _PH_PROVIDER_H
#ifdef __cplusplus
extern "C" {
#endif
#if defined(DEBUG)
extern PPH_LIST PhDbgProviderList;
extern PH_QUEUED_LOCK PhDbgProviderListLock;
#endif
typedef enum _PH_PROVIDER_THREAD_STATE
{
ProviderThreadRunning,
ProviderThreadStopped,
ProviderThreadStopping
} PH_PROVIDER_THREAD_STATE;
typedef VOID (NTAPI *PPH_PROVIDER_FUNCTION)(
_In_ PVOID Object
);
struct _PH_PROVIDER_THREAD;
typedef struct _PH_PROVIDER_THREAD *PPH_PROVIDER_THREAD;
typedef struct _PH_PROVIDER_REGISTRATION
{
LIST_ENTRY ListEntry;
PPH_PROVIDER_THREAD ProviderThread;
PPH_PROVIDER_FUNCTION Function;
PVOID Object;
ULONG RunId;
BOOLEAN Enabled;
BOOLEAN Unregistering;
BOOLEAN Boosting;
} PH_PROVIDER_REGISTRATION, *PPH_PROVIDER_REGISTRATION;
typedef struct _PH_PROVIDER_THREAD
{
HANDLE ThreadHandle;
HANDLE TimerHandle;
ULONG Interval;
PH_PROVIDER_THREAD_STATE State;
PH_QUEUED_LOCK Lock;
LIST_ENTRY ListHead;
ULONG BoostCount;
} PH_PROVIDER_THREAD, *PPH_PROVIDER_THREAD;
PHLIBAPI
VOID
NTAPI
PhInitializeProviderThread(
_Out_ PPH_PROVIDER_THREAD ProviderThread,
_In_ ULONG Interval
);
PHLIBAPI
VOID
NTAPI
PhDeleteProviderThread(
_Inout_ PPH_PROVIDER_THREAD ProviderThread
);
PHLIBAPI
VOID
NTAPI
PhStartProviderThread(
_Inout_ PPH_PROVIDER_THREAD ProviderThread
);
PHLIBAPI
VOID
NTAPI
PhStopProviderThread(
_Inout_ PPH_PROVIDER_THREAD ProviderThread
);
PHLIBAPI
VOID
NTAPI
PhSetIntervalProviderThread(
_Inout_ PPH_PROVIDER_THREAD ProviderThread,
_In_ ULONG Interval
);
PHLIBAPI
VOID
NTAPI
PhRegisterProvider(
_Inout_ PPH_PROVIDER_THREAD ProviderThread,
_In_ PPH_PROVIDER_FUNCTION Function,
_In_opt_ PVOID Object,
_Out_ PPH_PROVIDER_REGISTRATION Registration
);
PHLIBAPI
VOID
NTAPI
PhUnregisterProvider(
_Inout_ PPH_PROVIDER_REGISTRATION Registration
);
PHLIBAPI
BOOLEAN
NTAPI
PhBoostProvider(
_Inout_ PPH_PROVIDER_REGISTRATION Registration,
_Out_opt_ PULONG FutureRunId
);
PHLIBAPI
ULONG
NTAPI
PhGetRunIdProvider(
_In_ PPH_PROVIDER_REGISTRATION Registration
);
PHLIBAPI
BOOLEAN
NTAPI
PhGetEnabledProvider(
_In_ PPH_PROVIDER_REGISTRATION Registration
);
PHLIBAPI
VOID
NTAPI
PhSetEnabledProvider(
_Inout_ PPH_PROVIDER_REGISTRATION Registration,
_In_ BOOLEAN Enabled
);
#ifdef __cplusplus
}
#endif
#endif

349
phlib/include/queuedlock.h Normal file
View File

@@ -0,0 +1,349 @@
#ifndef _PH_QUEUEDLOCK_H
#define _PH_QUEUEDLOCK_H
#ifdef __cplusplus
extern "C" {
#endif
#define PH_QUEUED_LOCK_OWNED ((ULONG_PTR)0x1)
#define PH_QUEUED_LOCK_OWNED_SHIFT 0
#define PH_QUEUED_LOCK_WAITERS ((ULONG_PTR)0x2)
// Valid only if Waiters = 0
#define PH_QUEUED_LOCK_SHARED_INC ((ULONG_PTR)0x4)
#define PH_QUEUED_LOCK_SHARED_SHIFT 2
// Valid only if Waiters = 1
#define PH_QUEUED_LOCK_TRAVERSING ((ULONG_PTR)0x4)
#define PH_QUEUED_LOCK_MULTIPLE_SHARED ((ULONG_PTR)0x8)
#define PH_QUEUED_LOCK_FLAGS ((ULONG_PTR)0xf)
#define PhGetQueuedLockSharedOwners(Value) \
((ULONG_PTR)(Value) >> PH_QUEUED_LOCK_SHARED_SHIFT)
#define PhGetQueuedLockWaitBlock(Value) \
((PPH_QUEUED_WAIT_BLOCK)((ULONG_PTR)(Value) & ~PH_QUEUED_LOCK_FLAGS))
typedef struct _PH_QUEUED_LOCK
{
ULONG_PTR Value;
} PH_QUEUED_LOCK, *PPH_QUEUED_LOCK;
#define PH_QUEUED_LOCK_INIT { 0 }
#define PH_QUEUED_WAITER_EXCLUSIVE 0x1
#define PH_QUEUED_WAITER_SPINNING 0x2
#define PH_QUEUED_WAITER_SPINNING_SHIFT 1
typedef struct DECLSPEC_ALIGN(16) _PH_QUEUED_WAIT_BLOCK
{
/** A pointer to the next wait block, i.e. the wait block pushed onto the list before this one. */
struct _PH_QUEUED_WAIT_BLOCK *Next;
/**
* A pointer to the previous wait block, i.e. the wait block pushed onto the list after this
* one.
*/
struct _PH_QUEUED_WAIT_BLOCK *Previous;
/** A pointer to the last wait block, i.e. the first waiter pushed onto the list. */
struct _PH_QUEUED_WAIT_BLOCK *Last;
ULONG SharedOwners;
ULONG Flags;
} PH_QUEUED_WAIT_BLOCK, *PPH_QUEUED_WAIT_BLOCK;
BOOLEAN PhQueuedLockInitialization(
VOID
);
// Queued lock
FORCEINLINE
VOID
PhInitializeQueuedLock(
_Out_ PPH_QUEUED_LOCK QueuedLock
)
{
QueuedLock->Value = 0;
}
PHLIBAPI
VOID
FASTCALL
PhfAcquireQueuedLockExclusive(
_Inout_ PPH_QUEUED_LOCK QueuedLock
);
_Acquires_exclusive_lock_(*QueuedLock)
FORCEINLINE
VOID
PhAcquireQueuedLockExclusive(
_Inout_ PPH_QUEUED_LOCK QueuedLock
)
{
if (_InterlockedBitTestAndSetPointer((PLONG_PTR)&QueuedLock->Value, PH_QUEUED_LOCK_OWNED_SHIFT))
{
// Owned bit was already set. Slow path.
PhfAcquireQueuedLockExclusive(QueuedLock);
}
}
PHLIBAPI
VOID
FASTCALL
PhfAcquireQueuedLockShared(
_Inout_ PPH_QUEUED_LOCK QueuedLock
);
_Acquires_shared_lock_(*QueuedLock)
FORCEINLINE
VOID
PhAcquireQueuedLockShared(
_Inout_ PPH_QUEUED_LOCK QueuedLock
)
{
if ((ULONG_PTR)_InterlockedCompareExchangePointer(
(PVOID *)&QueuedLock->Value,
(PVOID)(PH_QUEUED_LOCK_OWNED | PH_QUEUED_LOCK_SHARED_INC),
(PVOID)0
) != 0)
{
PhfAcquireQueuedLockShared(QueuedLock);
}
}
_When_(return != 0, _Acquires_exclusive_lock_(*QueuedLock))
FORCEINLINE
BOOLEAN
PhTryAcquireQueuedLockExclusive(
_Inout_ PPH_QUEUED_LOCK QueuedLock
)
{
if (!_InterlockedBitTestAndSetPointer((PLONG_PTR)&QueuedLock->Value, PH_QUEUED_LOCK_OWNED_SHIFT))
{
return TRUE;
}
else
{
return FALSE;
}
}
PHLIBAPI
VOID
FASTCALL
PhfReleaseQueuedLockExclusive(
_Inout_ PPH_QUEUED_LOCK QueuedLock
);
PHLIBAPI
VOID
FASTCALL
PhfWakeForReleaseQueuedLock(
_Inout_ PPH_QUEUED_LOCK QueuedLock,
_In_ ULONG_PTR Value
);
_Releases_exclusive_lock_(*QueuedLock)
FORCEINLINE
VOID
PhReleaseQueuedLockExclusive(
_Inout_ PPH_QUEUED_LOCK QueuedLock
)
{
ULONG_PTR value;
value = (ULONG_PTR)_InterlockedExchangeAddPointer((PLONG_PTR)&QueuedLock->Value, -(LONG_PTR)PH_QUEUED_LOCK_OWNED);
if ((value & (PH_QUEUED_LOCK_WAITERS | PH_QUEUED_LOCK_TRAVERSING)) == PH_QUEUED_LOCK_WAITERS)
{
PhfWakeForReleaseQueuedLock(QueuedLock, value - PH_QUEUED_LOCK_OWNED);
}
}
PHLIBAPI
VOID
FASTCALL
PhfReleaseQueuedLockShared(
_Inout_ PPH_QUEUED_LOCK QueuedLock
);
_Releases_shared_lock_(*QueuedLock)
FORCEINLINE
VOID
PhReleaseQueuedLockShared(
_Inout_ PPH_QUEUED_LOCK QueuedLock
)
{
ULONG_PTR value;
value = PH_QUEUED_LOCK_OWNED | PH_QUEUED_LOCK_SHARED_INC;
if ((ULONG_PTR)_InterlockedCompareExchangePointer(
(PVOID *)&QueuedLock->Value,
(PVOID)0,
(PVOID)value
) != value)
{
PhfReleaseQueuedLockShared(QueuedLock);
}
}
FORCEINLINE
VOID
PhAcquireReleaseQueuedLockExclusive(
_Inout_ PPH_QUEUED_LOCK QueuedLock
)
{
BOOLEAN owned;
MemoryBarrier();
owned = !!(QueuedLock->Value & PH_QUEUED_LOCK_OWNED);
MemoryBarrier();
if (owned)
{
PhAcquireQueuedLockExclusive(QueuedLock);
PhReleaseQueuedLockExclusive(QueuedLock);
}
}
FORCEINLINE
BOOLEAN
PhTryAcquireReleaseQueuedLockExclusive(
_Inout_ PPH_QUEUED_LOCK QueuedLock
)
{
BOOLEAN owned;
// Need two memory barriers because we don't want the compiler re-ordering the following check
// in either direction.
MemoryBarrier();
owned = !(QueuedLock->Value & PH_QUEUED_LOCK_OWNED);
MemoryBarrier();
return owned;
}
// Condition variable
typedef struct _PH_QUEUED_LOCK PH_CONDITION, *PPH_CONDITION;
#define PH_CONDITION_INIT PH_QUEUED_LOCK_INIT
FORCEINLINE
VOID
PhInitializeCondition(
_Out_ PPH_CONDITION Condition
)
{
PhInitializeQueuedLock(Condition);
}
#define PhPulseCondition PhfPulseCondition
PHLIBAPI
VOID
FASTCALL
PhfPulseCondition(
_Inout_ PPH_CONDITION Condition
);
#define PhPulseAllCondition PhfPulseAllCondition
PHLIBAPI
VOID
FASTCALL
PhfPulseAllCondition(
_Inout_ PPH_CONDITION Condition
);
#define PhWaitForCondition PhfWaitForCondition
PHLIBAPI
VOID
FASTCALL
PhfWaitForCondition(
_Inout_ PPH_CONDITION Condition,
_Inout_ PPH_QUEUED_LOCK Lock,
_In_opt_ PLARGE_INTEGER Timeout
);
#define PH_CONDITION_WAIT_QUEUED_LOCK 0x1
#define PH_CONDITION_WAIT_CRITICAL_SECTION 0x2
#define PH_CONDITION_WAIT_FAST_LOCK 0x4
#define PH_CONDITION_WAIT_LOCK_TYPE_MASK 0xfff
#define PH_CONDITION_WAIT_SHARED 0x1000
#define PH_CONDITION_WAIT_SPIN 0x2000
#define PhWaitForConditionEx PhfWaitForConditionEx
PHLIBAPI
VOID
FASTCALL
PhfWaitForConditionEx(
_Inout_ PPH_CONDITION Condition,
_Inout_ PVOID Lock,
_In_ ULONG Flags,
_In_opt_ PLARGE_INTEGER Timeout
);
// Wake event
typedef struct _PH_QUEUED_LOCK PH_WAKE_EVENT, *PPH_WAKE_EVENT;
#define PH_WAKE_EVENT_INIT PH_QUEUED_LOCK_INIT
FORCEINLINE
VOID
PhInitializeWakeEvent(
_Out_ PPH_WAKE_EVENT WakeEvent
)
{
PhInitializeQueuedLock(WakeEvent);
}
#define PhQueueWakeEvent PhfQueueWakeEvent
PHLIBAPI
VOID
FASTCALL
PhfQueueWakeEvent(
_Inout_ PPH_WAKE_EVENT WakeEvent,
_Out_ PPH_QUEUED_WAIT_BLOCK WaitBlock
);
PHLIBAPI
VOID
FASTCALL
PhfSetWakeEvent(
_Inout_ PPH_WAKE_EVENT WakeEvent,
_Inout_opt_ PPH_QUEUED_WAIT_BLOCK WaitBlock
);
FORCEINLINE
VOID
PhSetWakeEvent(
_Inout_ PPH_WAKE_EVENT WakeEvent,
_Inout_opt_ PPH_QUEUED_WAIT_BLOCK WaitBlock
)
{
// The wake event is similar to a synchronization event in that it does not have thread-safe
// pulsing; we can simply skip the function call if there's nothing to wake. However, if we're
// cancelling a wait (WaitBlock != NULL) we need to make the call.
if (WakeEvent->Value || WaitBlock)
PhfSetWakeEvent(WakeEvent, WaitBlock);
}
#define PhWaitForWakeEvent PhfWaitForWakeEvent
PHLIBAPI
NTSTATUS
FASTCALL
PhfWaitForWakeEvent(
_Inout_ PPH_WAKE_EVENT WakeEvent,
_Inout_ PPH_QUEUED_WAIT_BLOCK WaitBlock,
_In_ BOOLEAN Spin,
_In_opt_ PLARGE_INTEGER Timeout
);
#ifdef __cplusplus
}
#endif
#endif

309
phlib/include/ref.h Normal file
View File

@@ -0,0 +1,309 @@
/*
* 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

175
phlib/include/refp.h Normal file
View File

@@ -0,0 +1,175 @@
/*
* 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_REFP_H
#define _PH_REFP_H
#define PH_OBJECT_TYPE_TABLE_SIZE 256
/** The object was allocated from the small free list. */
#define PH_OBJECT_FROM_SMALL_FREE_LIST 0x1
/** The object was allocated from the type free list. */
#define PH_OBJECT_FROM_TYPE_FREE_LIST 0x2
/**
* The object header contains object manager information including the reference count of an object
* and its type.
*/
typedef struct _PH_OBJECT_HEADER
{
union
{
struct
{
USHORT TypeIndex;
UCHAR Flags;
UCHAR Reserved1;
#ifdef _WIN64
ULONG Reserved2;
#endif
union
{
LONG RefCount;
struct
{
LONG SavedTypeIndex : 16;
LONG SavedFlags : 8;
LONG Reserved : 7;
LONG DeferDelete : 1; // MUST be the high bit, so that RefCount < 0 when deferring delete
};
};
#ifdef _WIN64
ULONG Reserved3;
#endif
};
SLIST_ENTRY DeferDeleteListEntry;
};
#ifdef DEBUG
PVOID StackBackTrace[16];
LIST_ENTRY ObjectListEntry;
#endif
/**
* The body of the object. For use by the \ref PhObjectToObjectHeader and
* \ref PhObjectHeaderToObject macros.
*/
QUAD_PTR Body;
} PH_OBJECT_HEADER, *PPH_OBJECT_HEADER;
#ifndef DEBUG
#ifdef _WIN64
C_ASSERT(FIELD_OFFSET(PH_OBJECT_HEADER, TypeIndex) == 0x0);
C_ASSERT(FIELD_OFFSET(PH_OBJECT_HEADER, Flags) == 0x2);
C_ASSERT(FIELD_OFFSET(PH_OBJECT_HEADER, Reserved1) == 0x3);
C_ASSERT(FIELD_OFFSET(PH_OBJECT_HEADER, Reserved2) == 0x4);
C_ASSERT(FIELD_OFFSET(PH_OBJECT_HEADER, RefCount) == 0x8);
C_ASSERT(FIELD_OFFSET(PH_OBJECT_HEADER, Reserved3) == 0xc);
C_ASSERT(FIELD_OFFSET(PH_OBJECT_HEADER, DeferDeleteListEntry) == 0x0);
C_ASSERT(FIELD_OFFSET(PH_OBJECT_HEADER, Body) == 0x10);
#else
C_ASSERT(FIELD_OFFSET(PH_OBJECT_HEADER, TypeIndex) == 0x0);
C_ASSERT(FIELD_OFFSET(PH_OBJECT_HEADER, Flags) == 0x2);
C_ASSERT(FIELD_OFFSET(PH_OBJECT_HEADER, Reserved1) == 0x3);
C_ASSERT(FIELD_OFFSET(PH_OBJECT_HEADER, RefCount) == 0x4);
C_ASSERT(FIELD_OFFSET(PH_OBJECT_HEADER, DeferDeleteListEntry) == 0x0);
C_ASSERT(FIELD_OFFSET(PH_OBJECT_HEADER, Body) == 0x8);
#endif
#endif
/**
* Gets a pointer to the object header for an object.
*
* \param Object A pointer to an object.
*
* \return A pointer to the object header of the object.
*/
#define PhObjectToObjectHeader(Object) ((PPH_OBJECT_HEADER)CONTAINING_RECORD((PCHAR)(Object), PH_OBJECT_HEADER, Body))
/**
* Gets a pointer to an object from an object header.
*
* \param ObjectHeader A pointer to an object header.
*
* \return A pointer to an object.
*/
#define PhObjectHeaderToObject(ObjectHeader) ((PVOID)&((PPH_OBJECT_HEADER)(ObjectHeader))->Body)
/**
* Calculates the total size to allocate for an object.
*
* \param Size The size of the object to allocate.
*
* \return The new size, including space for the object header.
*/
#define PhAddObjectHeaderSize(Size) ((Size) + FIELD_OFFSET(PH_OBJECT_HEADER, Body))
/** An object type specifies a kind of object and its delete procedure. */
typedef struct _PH_OBJECT_TYPE
{
/** The flags that were used to create the object type. */
USHORT Flags;
UCHAR TypeIndex;
UCHAR Reserved;
/** The total number of objects of this type that are alive. */
ULONG NumberOfObjects;
/** An optional procedure called when objects of this type are freed. */
PPH_TYPE_DELETE_PROCEDURE DeleteProcedure;
/** The name of the type. */
PWSTR Name;
/** A free list to use when allocating for this type. */
PH_FREE_LIST FreeList;
} PH_OBJECT_TYPE, *PPH_OBJECT_TYPE;
/**
* Increments a reference count, but will never increment from a nonpositive value to 1.
*
* \param RefCount A pointer to a reference count.
*/
FORCEINLINE
BOOLEAN
PhpInterlockedIncrementSafe(
_Inout_ PLONG RefCount
)
{
/* Here we will attempt to increment the reference count, making sure that it is positive. */
return _InterlockedIncrementPositive(RefCount);
}
PPH_OBJECT_HEADER PhpAllocateObject(
_In_ PPH_OBJECT_TYPE ObjectType,
_In_ SIZE_T ObjectSize
);
VOID PhpFreeObject(
_In_ PPH_OBJECT_HEADER ObjectHeader
);
VOID PhpDeferDeleteObject(
_In_ PPH_OBJECT_HEADER ObjectHeader
);
NTSTATUS PhpDeferDeleteObjectRoutine(
_In_ PVOID Parameter
);
#endif

163
phlib/include/secedit.h Normal file
View File

@@ -0,0 +1,163 @@
#ifndef _PH_SECEDIT_H
#define _PH_SECEDIT_H
#ifdef __cplusplus
extern "C" {
#endif
// secedit
typedef struct _PH_ACCESS_ENTRY
{
PWSTR Name;
ACCESS_MASK Access;
BOOLEAN General;
BOOLEAN Specific;
PWSTR ShortName;
} PH_ACCESS_ENTRY, *PPH_ACCESS_ENTRY;
PHLIBAPI
HPROPSHEETPAGE
NTAPI
PhCreateSecurityPage(
_In_ PWSTR ObjectName,
_In_ PPH_GET_OBJECT_SECURITY GetObjectSecurity,
_In_ PPH_SET_OBJECT_SECURITY SetObjectSecurity,
_In_opt_ PVOID Context,
_In_ PPH_ACCESS_ENTRY AccessEntries,
_In_ ULONG NumberOfAccessEntries
);
PHLIBAPI
VOID
NTAPI
PhEditSecurity(
_In_ HWND hWnd,
_In_ PWSTR ObjectName,
_In_ PPH_GET_OBJECT_SECURITY GetObjectSecurity,
_In_ PPH_SET_OBJECT_SECURITY SetObjectSecurity,
_In_opt_ PVOID Context,
_In_ PPH_ACCESS_ENTRY AccessEntries,
_In_ ULONG NumberOfAccessEntries
);
typedef struct _PH_STD_OBJECT_SECURITY
{
PPH_OPEN_OBJECT OpenObject;
PWSTR ObjectType;
PVOID Context;
} PH_STD_OBJECT_SECURITY, *PPH_STD_OBJECT_SECURITY;
FORCEINLINE ACCESS_MASK PhGetAccessForGetSecurity(
_In_ SECURITY_INFORMATION SecurityInformation
)
{
ACCESS_MASK access = 0;
if (
(SecurityInformation & OWNER_SECURITY_INFORMATION) ||
(SecurityInformation & GROUP_SECURITY_INFORMATION) ||
(SecurityInformation & DACL_SECURITY_INFORMATION)
)
{
access |= READ_CONTROL;
}
if (SecurityInformation & SACL_SECURITY_INFORMATION)
{
access |= ACCESS_SYSTEM_SECURITY;
}
return access;
}
FORCEINLINE ACCESS_MASK PhGetAccessForSetSecurity(
_In_ SECURITY_INFORMATION SecurityInformation
)
{
ACCESS_MASK access = 0;
if (
(SecurityInformation & OWNER_SECURITY_INFORMATION) ||
(SecurityInformation & GROUP_SECURITY_INFORMATION)
)
{
access |= WRITE_OWNER;
}
if (SecurityInformation & DACL_SECURITY_INFORMATION)
{
access |= WRITE_DAC;
}
if (SecurityInformation & SACL_SECURITY_INFORMATION)
{
access |= ACCESS_SYSTEM_SECURITY;
}
return access;
}
PHLIBAPI
_Callback_ NTSTATUS
NTAPI
PhStdGetObjectSecurity(
_Out_ PSECURITY_DESCRIPTOR *SecurityDescriptor,
_In_ SECURITY_INFORMATION SecurityInformation,
_In_opt_ PVOID Context
);
PHLIBAPI
_Callback_ NTSTATUS
NTAPI
PhStdSetObjectSecurity(
_In_ PSECURITY_DESCRIPTOR SecurityDescriptor,
_In_ SECURITY_INFORMATION SecurityInformation,
_In_opt_ PVOID Context
);
PHLIBAPI
NTSTATUS
NTAPI
PhGetSeObjectSecurity(
_In_ HANDLE Handle,
_In_ ULONG ObjectType,
_In_ SECURITY_INFORMATION SecurityInformation,
_Out_ PSECURITY_DESCRIPTOR *SecurityDescriptor
);
PHLIBAPI
NTSTATUS
NTAPI
PhSetSeObjectSecurity(
_In_ HANDLE Handle,
_In_ ULONG ObjectType,
_In_ SECURITY_INFORMATION SecurityInformation,
_In_ PSECURITY_DESCRIPTOR SecurityDescriptor
);
// secdata
PHLIBAPI
BOOLEAN
NTAPI
PhGetAccessEntries(
_In_ PWSTR Type,
_Out_ PPH_ACCESS_ENTRY *AccessEntries,
_Out_ PULONG NumberOfAccessEntries
);
PHLIBAPI
PPH_STRING
NTAPI
PhGetAccessString(
_In_ ACCESS_MASK Access,
_In_ PPH_ACCESS_ENTRY AccessEntries,
_In_ ULONG NumberOfAccessEntries
);
#ifdef __cplusplus
}
#endif
#endif

100
phlib/include/seceditp.h Normal file
View File

@@ -0,0 +1,100 @@
#ifndef _PH_SECEDITP_H
#define _PH_SECEDITP_H
#include <aclui.h>
#include <aclapi.h>
typedef struct
{
ISecurityInformationVtbl *VTable;
ULONG RefCount;
PPH_STRING ObjectName;
PPH_GET_OBJECT_SECURITY GetObjectSecurity;
PPH_SET_OBJECT_SECURITY SetObjectSecurity;
PVOID Context;
PSI_ACCESS AccessEntries;
ULONG NumberOfAccessEntries;
} PhSecurityInformation;
ISecurityInformation *PhSecurityInformation_Create(
_In_ PWSTR ObjectName,
_In_ PPH_GET_OBJECT_SECURITY GetObjectSecurity,
_In_ PPH_SET_OBJECT_SECURITY SetObjectSecurity,
_In_opt_ PVOID Context,
_In_ PPH_ACCESS_ENTRY AccessEntries,
_In_ ULONG NumberOfAccessEntries
);
HRESULT STDMETHODCALLTYPE PhSecurityInformation_QueryInterface(
_In_ ISecurityInformation *This,
_In_ REFIID Riid,
_Out_ PVOID *Object
);
ULONG STDMETHODCALLTYPE PhSecurityInformation_AddRef(
_In_ ISecurityInformation *This
);
ULONG STDMETHODCALLTYPE PhSecurityInformation_Release(
_In_ ISecurityInformation *This
);
HRESULT STDMETHODCALLTYPE PhSecurityInformation_GetObjectInformation(
_In_ ISecurityInformation *This,
_Out_ PSI_OBJECT_INFO ObjectInfo
);
HRESULT STDMETHODCALLTYPE PhSecurityInformation_GetSecurity(
_In_ ISecurityInformation *This,
_In_ SECURITY_INFORMATION RequestedInformation,
_Out_ PSECURITY_DESCRIPTOR *SecurityDescriptor,
_In_ BOOL Default
);
HRESULT STDMETHODCALLTYPE PhSecurityInformation_SetSecurity(
_In_ ISecurityInformation *This,
_In_ SECURITY_INFORMATION SecurityInformation,
_In_ PSECURITY_DESCRIPTOR SecurityDescriptor
);
HRESULT STDMETHODCALLTYPE PhSecurityInformation_GetAccessRights(
_In_ ISecurityInformation *This,
_In_ const GUID *ObjectType,
_In_ ULONG Flags,
_Out_ PSI_ACCESS *Access,
_Out_ PULONG Accesses,
_Out_ PULONG DefaultAccess
);
HRESULT STDMETHODCALLTYPE PhSecurityInformation_MapGeneric(
_In_ ISecurityInformation *This,
_In_ const GUID *ObjectType,
_In_ PUCHAR AceFlags,
_Inout_ PACCESS_MASK Mask
);
HRESULT STDMETHODCALLTYPE PhSecurityInformation_GetInheritTypes(
_In_ ISecurityInformation *This,
_Out_ PSI_INHERIT_TYPE *InheritTypes,
_Out_ PULONG InheritTypesCount
);
HRESULT STDMETHODCALLTYPE PhSecurityInformation_PropertySheetPageCallback(
_In_ ISecurityInformation *This,
_In_ HWND hwnd,
_In_ UINT uMsg,
_In_ SI_PAGE_TYPE uPage
);
typedef HPROPSHEETPAGE (WINAPI *_CreateSecurityPage)(
_In_ LPSECURITYINFO psi
);
typedef BOOL (WINAPI *_EditSecurity)(
_In_ HWND hwndOwner,
_In_ LPSECURITYINFO psi
);
#endif

146
phlib/include/svcsup.h Normal file
View File

@@ -0,0 +1,146 @@
#ifndef _PH_SVCSUP_H
#define _PH_SVCSUP_H
#ifdef __cplusplus
extern "C" {
#endif
extern WCHAR *PhServiceTypeStrings[10];
extern WCHAR *PhServiceStartTypeStrings[5];
extern WCHAR *PhServiceErrorControlStrings[4];
PHLIBAPI
PVOID
NTAPI
PhEnumServices(
_In_ SC_HANDLE ScManagerHandle,
_In_opt_ ULONG Type,
_In_opt_ ULONG State,
_Out_ PULONG Count
);
PHLIBAPI
SC_HANDLE
NTAPI
PhOpenService(
_In_ PWSTR ServiceName,
_In_ ACCESS_MASK DesiredAccess
);
PHLIBAPI
PVOID
NTAPI
PhGetServiceConfig(
_In_ SC_HANDLE ServiceHandle
);
PHLIBAPI
PVOID
NTAPI
PhQueryServiceVariableSize(
_In_ SC_HANDLE ServiceHandle,
_In_ ULONG InfoLevel
);
PHLIBAPI
PPH_STRING
NTAPI
PhGetServiceDescription(
_In_ SC_HANDLE ServiceHandle
);
PHLIBAPI
BOOLEAN
NTAPI
PhGetServiceDelayedAutoStart(
_In_ SC_HANDLE ServiceHandle,
_Out_ PBOOLEAN DelayedAutoStart
);
PHLIBAPI
BOOLEAN
NTAPI
PhSetServiceDelayedAutoStart(
_In_ SC_HANDLE ServiceHandle,
_In_ BOOLEAN DelayedAutoStart
);
PHLIBAPI
PWSTR
NTAPI
PhGetServiceStateString(
_In_ ULONG ServiceState
);
PHLIBAPI
PWSTR
NTAPI
PhGetServiceTypeString(
_In_ ULONG ServiceType
);
PHLIBAPI
ULONG
NTAPI
PhGetServiceTypeInteger(
_In_ PWSTR ServiceType
);
PHLIBAPI
PWSTR
NTAPI
PhGetServiceStartTypeString(
_In_ ULONG ServiceStartType
);
PHLIBAPI
ULONG
NTAPI
PhGetServiceStartTypeInteger(
_In_ PWSTR ServiceStartType
);
PHLIBAPI
PWSTR
NTAPI
PhGetServiceErrorControlString(
_In_ ULONG ServiceErrorControl
);
PHLIBAPI
ULONG
NTAPI
PhGetServiceErrorControlInteger(
_In_ PWSTR ServiceErrorControl
);
PHLIBAPI
PPH_STRING
NTAPI
PhGetServiceNameFromTag(
_In_ HANDLE ProcessId,
_In_ PVOID ServiceTag
);
PHLIBAPI
NTSTATUS
NTAPI
PhGetThreadServiceTag(
_In_ HANDLE ThreadHandle,
_In_opt_ HANDLE ProcessHandle,
_Out_ PVOID *ServiceTag
);
PHLIBAPI
NTSTATUS
NTAPI
PhGetServiceDllParameter(
_In_ PPH_STRINGREF ServiceName,
_Out_ PPH_STRING *ServiceDll
);
#ifdef __cplusplus
}
#endif
#endif

303
phlib/include/symprv.h Normal file
View File

@@ -0,0 +1,303 @@
#ifndef _PH_SYMPRV_H
#define _PH_SYMPRV_H
#ifdef __cplusplus
extern "C" {
#endif
extern PPH_OBJECT_TYPE PhSymbolProviderType;
extern PH_CALLBACK PhSymInitCallback;
#define PH_MAX_SYMBOL_NAME_LEN 128
typedef struct _PH_SYMBOL_PROVIDER
{
LIST_ENTRY ModulesListHead;
PH_QUEUED_LOCK ModulesListLock;
HANDLE ProcessHandle;
BOOLEAN IsRealHandle;
BOOLEAN IsRegistered;
PH_INITONCE InitOnce;
PH_AVL_TREE ModulesSet;
PH_CALLBACK EventCallback;
} PH_SYMBOL_PROVIDER, *PPH_SYMBOL_PROVIDER;
typedef enum _PH_SYMBOL_RESOLVE_LEVEL
{
PhsrlFunction,
PhsrlModule,
PhsrlAddress,
PhsrlInvalid
} PH_SYMBOL_RESOLVE_LEVEL, *PPH_SYMBOL_RESOLVE_LEVEL;
typedef struct _PH_SYMBOL_INFORMATION
{
ULONG64 Address;
ULONG64 ModuleBase;
ULONG Index;
ULONG Size;
} PH_SYMBOL_INFORMATION, *PPH_SYMBOL_INFORMATION;
typedef struct _PH_SYMBOL_LINE_INFORMATION
{
ULONG LineNumber;
ULONG64 Address;
} PH_SYMBOL_LINE_INFORMATION, *PPH_SYMBOL_LINE_INFORMATION;
typedef enum _PH_SYMBOL_EVENT_TYPE
{
SymbolDeferredSymbolLoadStart = 1,
SymbolDeferredSymbolLoadComplete = 2,
SymbolDeferredSymbolLoadFailure = 3,
SymbolSymbolsUnloaded = 4,
SymbolDeferredSymbolLoadCancel = 7
} PH_SYMBOL_EVENT_TYPE;
typedef struct _PH_SYMBOL_EVENT_DATA
{
PPH_SYMBOL_PROVIDER SymbolProvider;
PH_SYMBOL_EVENT_TYPE Type;
ULONG64 BaseAddress;
ULONG CheckSum;
ULONG TimeStamp;
PPH_STRING FileName;
} PH_SYMBOL_EVENT_DATA, *PPH_SYMBOL_EVENT_DATA;
PHLIBAPI
BOOLEAN
NTAPI
PhSymbolProviderInitialization(
VOID
);
PHLIBAPI
VOID
NTAPI
PhSymbolProviderCompleteInitialization(
_In_opt_ PVOID DbgHelpBase
);
PHLIBAPI
PPH_SYMBOL_PROVIDER
NTAPI
PhCreateSymbolProvider(
_In_opt_ HANDLE ProcessId
);
PHLIBAPI
BOOLEAN
NTAPI
PhGetLineFromAddress(
_In_ PPH_SYMBOL_PROVIDER SymbolProvider,
_In_ ULONG64 Address,
_Out_ PPH_STRING *FileName,
_Out_opt_ PULONG Displacement,
_Out_opt_ PPH_SYMBOL_LINE_INFORMATION Information
);
PHLIBAPI
ULONG64
NTAPI
PhGetModuleFromAddress(
_In_ PPH_SYMBOL_PROVIDER SymbolProvider,
_In_ ULONG64 Address,
_Out_opt_ PPH_STRING *FileName
);
PHLIBAPI
PPH_STRING
NTAPI
PhGetSymbolFromAddress(
_In_ PPH_SYMBOL_PROVIDER SymbolProvider,
_In_ ULONG64 Address,
_Out_opt_ PPH_SYMBOL_RESOLVE_LEVEL ResolveLevel,
_Out_opt_ PPH_STRING *FileName,
_Out_opt_ PPH_STRING *SymbolName,
_Out_opt_ PULONG64 Displacement
);
PHLIBAPI
BOOLEAN
NTAPI
PhGetSymbolFromName(
_In_ PPH_SYMBOL_PROVIDER SymbolProvider,
_In_ PWSTR Name,
_Out_ PPH_SYMBOL_INFORMATION Information
);
PHLIBAPI
BOOLEAN
NTAPI
PhLoadModuleSymbolProvider(
_In_ PPH_SYMBOL_PROVIDER SymbolProvider,
_In_ PWSTR FileName,
_In_ ULONG64 BaseAddress,
_In_ ULONG Size
);
PHLIBAPI
VOID
NTAPI
PhSetOptionsSymbolProvider(
_In_ ULONG Mask,
_In_ ULONG Value
);
PHLIBAPI
VOID
NTAPI
PhSetSearchPathSymbolProvider(
_In_ PPH_SYMBOL_PROVIDER SymbolProvider,
_In_ PWSTR Path
);
#ifdef _WIN64
PHLIBAPI
NTSTATUS
NTAPI
PhAccessOutOfProcessFunctionEntry(
_In_ HANDLE ProcessHandle,
_In_ ULONG64 ControlPc,
_Out_ PRUNTIME_FUNCTION Function
);
#endif
PHLIBAPI
ULONG64
__stdcall
PhGetModuleBase64(
_In_ HANDLE hProcess,
_In_ DWORD64 dwAddr
);
PHLIBAPI
PVOID
__stdcall
PhFunctionTableAccess64(
_In_ HANDLE hProcess,
_In_ DWORD64 AddrBase
);
#ifndef _DBGHELP_
// Some of the types used below are defined in dbghelp.h.
typedef struct _tagSTACKFRAME64 *LPSTACKFRAME64;
typedef struct _tagADDRESS64 *LPADDRESS64;
typedef BOOL (__stdcall *PREAD_PROCESS_MEMORY_ROUTINE64)(
_In_ HANDLE hProcess,
_In_ DWORD64 qwBaseAddress,
_Out_writes_bytes_(nSize) PVOID lpBuffer,
_In_ DWORD nSize,
_Out_ LPDWORD lpNumberOfBytesRead
);
typedef PVOID (__stdcall *PFUNCTION_TABLE_ACCESS_ROUTINE64)(
_In_ HANDLE ahProcess,
_In_ DWORD64 AddrBase
);
typedef DWORD64 (__stdcall *PGET_MODULE_BASE_ROUTINE64)(
_In_ HANDLE hProcess,
_In_ DWORD64 Address
);
typedef DWORD64 (__stdcall *PTRANSLATE_ADDRESS_ROUTINE64)(
_In_ HANDLE hProcess,
_In_ HANDLE hThread,
_In_ LPADDRESS64 lpaddr
);
typedef enum _MINIDUMP_TYPE MINIDUMP_TYPE;
typedef struct _MINIDUMP_EXCEPTION_INFORMATION *PMINIDUMP_EXCEPTION_INFORMATION;
typedef struct _MINIDUMP_USER_STREAM_INFORMATION *PMINIDUMP_USER_STREAM_INFORMATION;
typedef struct _MINIDUMP_CALLBACK_INFORMATION *PMINIDUMP_CALLBACK_INFORMATION;
#endif
PHLIBAPI
BOOLEAN
NTAPI
PhStackWalk(
_In_ ULONG MachineType,
_In_ HANDLE ProcessHandle,
_In_ HANDLE ThreadHandle,
_Inout_ LPSTACKFRAME64 StackFrame,
_Inout_ PVOID ContextRecord,
_In_opt_ PPH_SYMBOL_PROVIDER SymbolProvider,
_In_opt_ PREAD_PROCESS_MEMORY_ROUTINE64 ReadMemoryRoutine,
_In_opt_ PFUNCTION_TABLE_ACCESS_ROUTINE64 FunctionTableAccessRoutine,
_In_opt_ PGET_MODULE_BASE_ROUTINE64 GetModuleBaseRoutine,
_In_opt_ PTRANSLATE_ADDRESS_ROUTINE64 TranslateAddress
);
PHLIBAPI
BOOLEAN
NTAPI
PhWriteMiniDumpProcess(
_In_ HANDLE ProcessHandle,
_In_ HANDLE ProcessId,
_In_ HANDLE FileHandle,
_In_ MINIDUMP_TYPE DumpType,
_In_opt_ PMINIDUMP_EXCEPTION_INFORMATION ExceptionParam,
_In_opt_ PMINIDUMP_USER_STREAM_INFORMATION UserStreamParam,
_In_opt_ PMINIDUMP_CALLBACK_INFORMATION CallbackParam
);
// High-level stack walking
#define PH_THREAD_STACK_FRAME_I386 0x1
#define PH_THREAD_STACK_FRAME_AMD64 0x2
#define PH_THREAD_STACK_FRAME_KERNEL 0x4
#define PH_THREAD_STACK_FRAME_FPO_DATA_PRESENT 0x100
/** Contains information about a thread stack frame. */
typedef struct _PH_THREAD_STACK_FRAME
{
PVOID PcAddress;
PVOID ReturnAddress;
PVOID FrameAddress;
PVOID StackAddress;
PVOID BStoreAddress;
PVOID Params[4];
ULONG Flags;
} PH_THREAD_STACK_FRAME, *PPH_THREAD_STACK_FRAME;
#define PH_WALK_I386_STACK 0x1
#define PH_WALK_AMD64_STACK 0x2
#define PH_WALK_KERNEL_STACK 0x10
/**
* A callback function passed to PhWalkThreadStack() and called for each stack frame.
*
* \param StackFrame A structure providing information about the stack frame.
* \param Context A user-defined value passed to PhWalkThreadStack().
*
* \return TRUE to continue the stack walk, FALSE to stop.
*/
typedef BOOLEAN (NTAPI *PPH_WALK_THREAD_STACK_CALLBACK)(
_In_ PPH_THREAD_STACK_FRAME StackFrame,
_In_opt_ PVOID Context
);
PHLIBAPI
NTSTATUS
NTAPI
PhWalkThreadStack(
_In_ HANDLE ThreadHandle,
_In_opt_ HANDLE ProcessHandle,
_In_opt_ PCLIENT_ID ClientId,
_In_opt_ PPH_SYMBOL_PROVIDER SymbolProvider,
_In_ ULONG Flags,
_In_ PPH_WALK_THREAD_STACK_CALLBACK Callback,
_In_opt_ PVOID Context
);
#ifdef __cplusplus
}
#endif
#endif

170
phlib/include/symprvp.h Normal file
View File

@@ -0,0 +1,170 @@
#ifndef _PH_SYMPRVP_H
#define _PH_SYMPRVP_H
typedef BOOL (WINAPI *_SymInitialize)(
_In_ HANDLE hProcess,
_In_opt_ PCSTR UserSearchPath,
_In_ BOOL fInvadeProcess
);
typedef BOOL (WINAPI *_SymCleanup)(
_In_ HANDLE hProcess
);
typedef BOOL (WINAPI *_SymEnumSymbols)(
_In_ HANDLE hProcess,
_In_ ULONG64 BaseOfDll,
_In_opt_ PCSTR Mask,
_In_ PSYM_ENUMERATESYMBOLS_CALLBACK EnumSymbolsCallback,
_In_opt_ const PVOID UserContext
);
typedef BOOL (WINAPI *_SymEnumSymbolsW)(
_In_ HANDLE hProcess,
_In_ ULONG64 BaseOfDll,
_In_opt_ PCWSTR Mask,
_In_ PSYM_ENUMERATESYMBOLS_CALLBACKW EnumSymbolsCallback,
_In_opt_ const PVOID UserContext
);
typedef BOOL (WINAPI *_SymFromAddr)(
_In_ HANDLE hProcess,
_In_ DWORD64 Address,
_Out_opt_ PDWORD64 Displacement,
_Inout_ PSYMBOL_INFO Symbol
);
typedef BOOL (WINAPI *_SymFromAddrW)(
_In_ HANDLE hProcess,
_In_ DWORD64 Address,
_Out_opt_ PDWORD64 Displacement,
_Inout_ PSYMBOL_INFOW Symbol
);
typedef BOOL (WINAPI *_SymFromName)(
_In_ HANDLE hProcess,
_In_ PCSTR Name,
_Inout_ PSYMBOL_INFO Symbol
);
typedef BOOL (WINAPI *_SymFromNameW)(
_In_ HANDLE hProcess,
_In_ PCWSTR Name,
_Inout_ PSYMBOL_INFOW Symbol
);
typedef BOOL (WINAPI *_SymGetLineFromAddr64)(
_In_ HANDLE hProcess,
_In_ DWORD64 dwAddr,
_Out_ PDWORD pdwDisplacement,
_Out_ PIMAGEHLP_LINE64 Line
);
typedef BOOL (WINAPI *_SymGetLineFromAddrW64)(
_In_ HANDLE hProcess,
_In_ DWORD64 dwAddr,
_Out_ PDWORD pdwDisplacement,
_Out_ PIMAGEHLP_LINEW64 Line
);
typedef DWORD64 (WINAPI *_SymLoadModule64)(
_In_ HANDLE hProcess,
_In_opt_ HANDLE hFile,
_In_opt_ PCSTR ImageName,
_In_opt_ PCSTR ModuleName,
_In_ DWORD64 BaseOfDll,
_In_ DWORD SizeOfDll
);
typedef DWORD64 (WINAPI *_SymLoadModuleExW)(
_In_ HANDLE hProcess,
_In_ HANDLE hFile,
_In_ PCWSTR ImageName,
_In_ PCWSTR ModuleName,
_In_ DWORD64 BaseOfDll,
_In_ DWORD DllSize,
_In_ PMODLOAD_DATA Data,
_In_ DWORD Flags
);
typedef DWORD (WINAPI *_SymGetOptions)();
typedef DWORD (WINAPI *_SymSetOptions)(
_In_ DWORD SymOptions
);
typedef BOOL (WINAPI *_SymGetSearchPath)(
_In_ HANDLE hProcess,
_Out_ PSTR SearchPath,
_In_ DWORD SearchPathLength
);
typedef BOOL (WINAPI *_SymGetSearchPathW)(
_In_ HANDLE hProcess,
_Out_ PWSTR SearchPath,
_In_ DWORD SearchPathLength
);
typedef BOOL (WINAPI *_SymSetSearchPath)(
_In_ HANDLE hProcess,
_In_opt_ PCSTR SearchPath
);
typedef BOOL (WINAPI *_SymSetSearchPathW)(
_In_ HANDLE hProcess,
_In_opt_ PCWSTR SearchPath
);
typedef BOOL (WINAPI *_SymUnloadModule64)(
_In_ HANDLE hProcess,
_In_ DWORD64 BaseOfDll
);
typedef PVOID (WINAPI *_SymFunctionTableAccess64)(
_In_ HANDLE hProcess,
_In_ DWORD64 AddrBase
);
typedef DWORD64 (WINAPI *_SymGetModuleBase64)(
_In_ HANDLE hProcess,
_In_ DWORD64 dwAddr
);
typedef BOOL (WINAPI *_SymRegisterCallbackW64)(
_In_ HANDLE hProcess,
_In_ PSYMBOL_REGISTERED_CALLBACK64 CallbackFunction,
_In_ ULONG64 UserContext
);
typedef BOOL (WINAPI *_StackWalk64)(
_In_ DWORD MachineType,
_In_ HANDLE hProcess,
_In_ HANDLE hThread,
_Inout_ LPSTACKFRAME64 StackFrame,
_Inout_ PVOID ContextRecord,
_In_opt_ PREAD_PROCESS_MEMORY_ROUTINE64 ReadMemoryRoutine,
_In_opt_ PFUNCTION_TABLE_ACCESS_ROUTINE64 FunctionTableAccessRoutine,
_In_opt_ PGET_MODULE_BASE_ROUTINE64 GetModuleBaseRoutine,
_In_opt_ PTRANSLATE_ADDRESS_ROUTINE64 TranslateAddress
);
typedef BOOL (WINAPI *_MiniDumpWriteDump)(
_In_ HANDLE hProcess,
_In_ DWORD ProcessId,
_In_ HANDLE hFile,
_In_ MINIDUMP_TYPE DumpType,
_In_ PMINIDUMP_EXCEPTION_INFORMATION ExceptionParam,
_In_ PMINIDUMP_USER_STREAM_INFORMATION UserStreamParam,
_In_ PMINIDUMP_CALLBACK_INFORMATION CallbackParam
);
typedef UINT_PTR (CALLBACK *_SymbolServerGetOptions)(
VOID
);
typedef BOOL (CALLBACK *_SymbolServerSetOptions)(
_In_ UINT_PTR options,
_In_ ULONG64 data
);
#endif

7
phlib/include/templ.h Normal file
View File

@@ -0,0 +1,7 @@
#ifndef _PH_TEMPL_H
#define _PH_TEMPL_H
#define TEMPLATE_(f,T) f##_##T
#define T___(f,T) TEMPLATE_(f,T)
#endif

672
phlib/include/treenew.h Normal file
View File

@@ -0,0 +1,672 @@
#ifndef _PH_TREENEW_H
#define _PH_TREENEW_H
#ifdef __cplusplus
extern "C" {
#endif
#define PH_TREENEW_CLASSNAME L"PhTreeNew"
#define PH_TREENEW_SEARCH_TIMEOUT 1000
#define PH_TREENEW_SEARCH_MAXIMUM_LENGTH 1023
typedef struct _PH_TREENEW_COLUMN
{
union
{
ULONG Flags;
struct
{
ULONG Visible : 1;
ULONG CustomDraw : 1;
ULONG Fixed : 1; // Whether this is the fixed column
ULONG SortDescending : 1; // Sort descending on initial click rather than ascending
ULONG DpiScaleOnAdd : 1; // Whether to DPI scale the width (only when adding)
ULONG SpareFlags : 27;
};
};
ULONG Id;
PVOID Context;
PWSTR Text;
LONG Width;
ULONG Alignment;
ULONG DisplayIndex; // -1 for fixed column or invalid
ULONG TextFlags;
struct
{
LONG ViewIndex; // Actual index in header control
LONG ViewX; // 0 for the fixed column, and an offset from the divider for normal columns
} s;
} PH_TREENEW_COLUMN, *PPH_TREENEW_COLUMN;
typedef struct _PH_TREENEW_NODE
{
union
{
ULONG Flags;
struct
{
ULONG Visible : 1;
ULONG Selected : 1;
ULONG Expanded : 1;
ULONG UseAutoForeColor : 1;
ULONG UseTempBackColor : 1;
ULONG Unselectable : 1;
ULONG SpareFlags : 26;
};
};
COLORREF BackColor;
COLORREF ForeColor;
COLORREF TempBackColor;
HFONT Font;
HICON Icon;
PPH_STRINGREF TextCache;
ULONG TextCacheSize;
ULONG Index; // Index within the flat list
ULONG Level; // 0 for root, 1, 2, ...
struct
{
union
{
ULONG Flags2;
struct
{
ULONG IsLeaf : 1;
ULONG CachedColorValid : 1;
ULONG CachedFontValid : 1;
ULONG CachedIconValid : 1;
ULONG PlusMinusHot : 1;
ULONG SpareFlags2 : 27;
};
};
// Temp. drawing data
COLORREF DrawBackColor;
COLORREF DrawForeColor;
} s;
} PH_TREENEW_NODE, *PPH_TREENEW_NODE;
// Styles
#define TN_STYLE_ICONS 0x1
#define TN_STYLE_DOUBLE_BUFFERED 0x2
#define TN_STYLE_NO_DIVIDER 0x4
#define TN_STYLE_ANIMATE_DIVIDER 0x8
#define TN_STYLE_NO_COLUMN_SORT 0x10
#define TN_STYLE_NO_COLUMN_REORDER 0x20
#define TN_STYLE_THIN_ROWS 0x40
#define TN_STYLE_NO_COLUMN_HEADER 0x80
// Extended flags
#define TN_FLAG_ITEM_DRAG_SELECT 0x1
#define TN_FLAG_NO_UNFOLDING_TOOLTIPS 0x2
// Callback flags
#define TN_CACHE 0x1
#define TN_AUTO_FORECOLOR 0x1000
// Column change flags
#define TN_COLUMN_CONTEXT 0x1
#define TN_COLUMN_TEXT 0x2
#define TN_COLUMN_WIDTH 0x4
#define TN_COLUMN_ALIGNMENT 0x8
#define TN_COLUMN_DISPLAYINDEX 0x10
#define TN_COLUMN_TEXTFLAGS 0x20
#define TN_COLUMN_FLAG_VISIBLE 0x100000
#define TN_COLUMN_FLAG_CUSTOMDRAW 0x200000
#define TN_COLUMN_FLAG_FIXED 0x400000
#define TN_COLUMN_FLAG_SORTDESCENDING 0x800000
#define TN_COLUMN_FLAG_NODPISCALEONADD 0x1000000
#define TN_COLUMN_FLAGS 0xfff00000
// Cache flags
#define TN_CACHE_COLOR 0x1
#define TN_CACHE_FONT 0x2
#define TN_CACHE_ICON 0x4
// Cell part input flags
#define TN_MEASURE_TEXT 0x1
// Cell part flags
#define TN_PART_CELL 0x1
#define TN_PART_PLUSMINUS 0x2
#define TN_PART_ICON 0x4
#define TN_PART_CONTENT 0x8
#define TN_PART_TEXT 0x10
// Hit test input flags
#define TN_TEST_COLUMN 0x1
#define TN_TEST_SUBITEM 0x2 // requires TN_TEST_COLUMN
// Hit test flags
#define TN_HIT_LEFT 0x1
#define TN_HIT_RIGHT 0x2
#define TN_HIT_ABOVE 0x4
#define TN_HIT_BELOW 0x8
#define TN_HIT_ITEM 0x10
#define TN_HIT_ITEM_PLUSMINUS 0x20 // requires TN_TEST_SUBITEM
#define TN_HIT_ITEM_ICON 0x40 // requires TN_TEST_SUBITEM
#define TN_HIT_ITEM_CONTENT 0x80 // requires TN_TEST_SUBITEM
#define TN_HIT_DIVIDER 0x100
// Selection flags
#define TN_SELECT_DESELECT 0x1
#define TN_SELECT_TOGGLE 0x2
#define TN_SELECT_RESET 0x4
// Auto-size flags
#define TN_AUTOSIZE_REMAINING_SPACE 0x1
typedef struct _PH_TREENEW_CELL_PARTS
{
ULONG Flags;
RECT RowRect;
RECT CellRect; // TN_PART_CELL
RECT PlusMinusRect; // TN_PART_PLUSMINUS
RECT IconRect; // TN_PART_ICON
RECT ContentRect; // TN_PART_CONTENT
RECT TextRect; // TN_PART_TEXT
PH_STRINGREF Text; // TN_PART_TEXT
HFONT Font; // TN_PART_TEXT
} PH_TREENEW_CELL_PARTS, *PPH_TREENEW_CELL_PARTS;
typedef struct _PH_TREENEW_HIT_TEST
{
POINT Point;
ULONG InFlags;
ULONG Flags;
PPH_TREENEW_NODE Node;
PPH_TREENEW_COLUMN Column; // requires TN_TEST_COLUMN
} PH_TREENEW_HIT_TEST, *PPH_TREENEW_HIT_TEST;
typedef enum _PH_TREENEW_MESSAGE
{
TreeNewGetChildren, // PPH_TREENEW_GET_CHILDREN Parameter1
TreeNewIsLeaf, // PPH_TREENEW_IS_LEAF Parameter1
TreeNewGetCellText, // PPH_TREENEW_GET_CELL_TEXT Parameter1
TreeNewGetNodeColor, // PPH_TREENEW_GET_NODE_COLOR Parameter1
TreeNewGetNodeFont, // PPH_TREENEW_GET_NODE_FONT Parameter1
TreeNewGetNodeIcon, // PPH_TREENEW_GET_NODE_ICON Parameter1
TreeNewGetCellTooltip, // PPH_TREENEW_GET_CELL_TOOLTIP Parameter1
TreeNewCustomDraw, // PPH_TREENEW_CUSTOM_DRAW Parameter1
// Notifications
TreeNewNodeExpanding, // PPH_TREENEW_NODE Parameter1, PPH_TREENEW_NODE_EVENT Parameter2
TreeNewNodeSelecting, // PPH_TREENEW_NODE Parameter1
TreeNewSortChanged,
TreeNewSelectionChanged,
TreeNewKeyDown, // PPH_TREENEW_KEY_EVENT Parameter1
TreeNewLeftClick, // PPH_TREENEW_MOUSE_EVENT Parameter1
TreeNewRightClick, // PPH_TREENEW_MOUSE_EVENT Parameter1
TreeNewLeftDoubleClick, // PPH_TREENEW_MOUSE_EVENT Parameter1
TreeNewRightDoubleClick, // PPH_TREENEW_MOUSE_EVENT Parameter1
TreeNewContextMenu, // PPH_TREENEW_CONTEXT_MENU Parameter1
TreeNewHeaderRightClick, // PPH_TREENEW_HEADER_MOUSE_EVENT Parameter1
TreeNewIncrementalSearch, // PPH_TREENEW_SEARCH_EVENT Parameter1
TreeNewColumnResized, // PPH_TREENEW_COLUMN Parameter1
TreeNewColumnReordered,
TreeNewDestroying,
TreeNewGetDialogCode, // ULONG Parameter1, PULONG Parameter2
MaxTreeNewMessage
} PH_TREENEW_MESSAGE;
typedef BOOLEAN (NTAPI *PPH_TREENEW_CALLBACK)(
_In_ HWND hwnd,
_In_ PH_TREENEW_MESSAGE Message,
_In_opt_ PVOID Parameter1,
_In_opt_ PVOID Parameter2,
_In_opt_ PVOID Context
);
typedef struct _PH_TREENEW_GET_CHILDREN
{
ULONG Flags;
PPH_TREENEW_NODE Node;
ULONG NumberOfChildren;
PPH_TREENEW_NODE *Children; // can be NULL if no children
} PH_TREENEW_GET_CHILDREN, *PPH_TREENEW_GET_CHILDREN;
typedef struct _PH_TREENEW_IS_LEAF
{
ULONG Flags;
PPH_TREENEW_NODE Node;
BOOLEAN IsLeaf;
} PH_TREENEW_IS_LEAF, *PPH_TREENEW_IS_LEAF;
typedef struct _PH_TREENEW_GET_CELL_TEXT
{
ULONG Flags;
PPH_TREENEW_NODE Node;
ULONG Id;
PH_STRINGREF Text;
} PH_TREENEW_GET_CELL_TEXT, *PPH_TREENEW_GET_CELL_TEXT;
typedef struct _PH_TREENEW_GET_NODE_COLOR
{
ULONG Flags;
PPH_TREENEW_NODE Node;
COLORREF BackColor;
COLORREF ForeColor;
} PH_TREENEW_GET_NODE_COLOR, *PPH_TREENEW_GET_NODE_COLOR;
typedef struct _PH_TREENEW_GET_NODE_FONT
{
ULONG Flags;
PPH_TREENEW_NODE Node;
HFONT Font;
} PH_TREENEW_GET_NODE_FONT, *PPH_TREENEW_GET_NODE_FONT;
typedef struct _PH_TREENEW_GET_NODE_ICON
{
ULONG Flags;
PPH_TREENEW_NODE Node;
HICON Icon;
} PH_TREENEW_GET_NODE_ICON, *PPH_TREENEW_GET_NODE_ICON;
typedef struct _PH_TREENEW_GET_CELL_TOOLTIP
{
ULONG Flags;
PPH_TREENEW_NODE Node;
PPH_TREENEW_COLUMN Column;
BOOLEAN Unfolding;
PH_STRINGREF Text;
HFONT Font;
ULONG MaximumWidth;
} PH_TREENEW_GET_CELL_TOOLTIP, *PPH_TREENEW_GET_CELL_TOOLTIP;
typedef struct _PH_TREENEW_CUSTOM_DRAW
{
PPH_TREENEW_NODE Node;
PPH_TREENEW_COLUMN Column;
HDC Dc;
RECT CellRect;
RECT TextRect;
} PH_TREENEW_CUSTOM_DRAW, *PPH_TREENEW_CUSTOM_DRAW;
typedef struct _PH_TREENEW_MOUSE_EVENT
{
POINT Location;
PPH_TREENEW_NODE Node;
PPH_TREENEW_COLUMN Column;
ULONG KeyFlags;
} PH_TREENEW_MOUSE_EVENT, *PPH_TREENEW_MOUSE_EVENT;
typedef struct _PH_TREENEW_KEY_EVENT
{
BOOLEAN Handled;
ULONG VirtualKey;
ULONG Data;
} PH_TREENEW_KEY_EVENT, *PPH_TREENEW_KEY_EVENT;
typedef struct _PH_TREENEW_NODE_EVENT
{
BOOLEAN Handled;
ULONG Flags;
PVOID Reserved1;
PVOID Reserved2;
} PH_TREENEW_NODE_EVENT, *PPH_TREENEW_NODE_EVENT;
typedef struct _PH_TREENEW_CONTEXT_MENU
{
POINT Location;
POINT ClientLocation;
PPH_TREENEW_NODE Node;
PPH_TREENEW_COLUMN Column;
BOOLEAN KeyboardInvoked;
} PH_TREENEW_CONTEXT_MENU, *PPH_TREENEW_CONTEXT_MENU;
typedef struct _PH_TREENEW_HEADER_MOUSE_EVENT
{
POINT ScreenLocation;
POINT Location;
POINT HeaderLocation;
PPH_TREENEW_COLUMN Column;
} PH_TREENEW_HEADER_MOUSE_EVENT, *PPH_TREENEW_HEADER_MOUSE_EVENT;
typedef struct _PH_TREENEW_SEARCH_EVENT
{
LONG FoundIndex;
LONG StartIndex;
PH_STRINGREF String;
} PH_TREENEW_SEARCH_EVENT, *PPH_TREENEW_SEARCH_EVENT;
#define TNM_FIRST (WM_USER + 1)
#define TNM_SETCALLBACK (WM_USER + 1)
#define TNM_NODESADDED (WM_USER + 2) // unimplemented
#define TNM_NODESREMOVED (WM_USER + 3) // unimplemented
#define TNM_NODESSTRUCTURED (WM_USER + 4)
#define TNM_ADDCOLUMN (WM_USER + 5)
#define TNM_REMOVECOLUMN (WM_USER + 6)
#define TNM_GETCOLUMN (WM_USER + 7)
#define TNM_SETCOLUMN (WM_USER + 8)
#define TNM_GETCOLUMNORDERARRAY (WM_USER + 9)
#define TNM_SETCOLUMNORDERARRAY (WM_USER + 10)
#define TNM_SETCURSOR (WM_USER + 11)
#define TNM_GETSORT (WM_USER + 12)
#define TNM_SETSORT (WM_USER + 13)
#define TNM_SETTRISTATE (WM_USER + 14)
#define TNM_ENSUREVISIBLE (WM_USER + 15)
#define TNM_SCROLL (WM_USER + 16)
#define TNM_GETFLATNODECOUNT (WM_USER + 17)
#define TNM_GETFLATNODE (WM_USER + 18)
#define TNM_GETCELLTEXT (WM_USER + 19)
#define TNM_SETNODEEXPANDED (WM_USER + 20)
#define TNM_GETMAXID (WM_USER + 21)
#define TNM_SETMAXID (WM_USER + 22)
#define TNM_INVALIDATENODE (WM_USER + 23)
#define TNM_INVALIDATENODES (WM_USER + 24)
#define TNM_GETFIXEDHEADER (WM_USER + 25)
#define TNM_GETHEADER (WM_USER + 26)
#define TNM_GETTOOLTIPS (WM_USER + 27)
#define TNM_SELECTRANGE (WM_USER + 28)
#define TNM_DESELECTRANGE (WM_USER + 29)
#define TNM_GETCOLUMNCOUNT (WM_USER + 30)
#define TNM_SETREDRAW (WM_USER + 31)
#define TNM_GETVIEWPARTS (WM_USER + 32)
#define TNM_GETFIXEDCOLUMN (WM_USER + 33)
#define TNM_GETFIRSTCOLUMN (WM_USER + 34)
#define TNM_SETFOCUSNODE (WM_USER + 35)
#define TNM_SETMARKNODE (WM_USER + 36)
#define TNM_SETHOTNODE (WM_USER + 37)
#define TNM_SETEXTENDEDFLAGS (WM_USER + 38)
#define TNM_GETCALLBACK (WM_USER + 39)
#define TNM_HITTEST (WM_USER + 40)
#define TNM_GETVISIBLECOLUMNCOUNT (WM_USER + 41)
#define TNM_AUTOSIZECOLUMN (WM_USER + 42)
#define TNM_SETEMPTYTEXT (WM_USER + 43)
#define TNM_SETROWHEIGHT (WM_USER + 44)
#define TNM_ISFLATNODEVALID (WM_USER + 45)
#define TNM_LAST (WM_USER + 45)
#define TreeNew_SetCallback(hWnd, Callback, Context) \
SendMessage((hWnd), TNM_SETCALLBACK, (WPARAM)(Context), (LPARAM)(Callback))
#define TreeNew_NodesStructured(hWnd) \
SendMessage((hWnd), TNM_NODESSTRUCTURED, 0, 0)
#define TreeNew_AddColumn(hWnd, Column) \
SendMessage((hWnd), TNM_ADDCOLUMN, 0, (LPARAM)(Column))
#define TreeNew_RemoveColumn(hWnd, Id) \
SendMessage((hWnd), TNM_REMOVECOLUMN, (WPARAM)(Id), 0)
#define TreeNew_GetColumn(hWnd, Id, Column) \
SendMessage((hWnd), TNM_GETCOLUMN, (WPARAM)(Id), (LPARAM)(Column))
#define TreeNew_SetColumn(hWnd, Mask, Column) \
SendMessage((hWnd), TNM_SETCOLUMN, (WPARAM)(Mask), (LPARAM)(Column))
#define TreeNew_GetColumnOrderArray(hWnd, Count, Array) \
SendMessage((hWnd), TNM_GETCOLUMNORDERARRAY, (WPARAM)(Count), (LPARAM)(Array))
#define TreeNew_SetColumnOrderArray(hWnd, Count, Array) \
SendMessage((hWnd), TNM_SETCOLUMNORDERARRAY, (WPARAM)(Count), (LPARAM)(Array))
#define TreeNew_SetCursor(hWnd, Cursor) \
SendMessage((hWnd), TNM_SETCURSOR, 0, (LPARAM)(Cursor))
#define TreeNew_GetSort(hWnd, Column, Order) \
SendMessage((hWnd), TNM_GETSORT, (WPARAM)(Column), (LPARAM)(Order))
#define TreeNew_SetSort(hWnd, Column, Order) \
SendMessage((hWnd), TNM_SETSORT, (WPARAM)(Column), (LPARAM)(Order))
#define TreeNew_SetTriState(hWnd, TriState) \
SendMessage((hWnd), TNM_SETTRISTATE, (WPARAM)(TriState), 0)
#define TreeNew_EnsureVisible(hWnd, Node) \
SendMessage((hWnd), TNM_ENSUREVISIBLE, 0, (LPARAM)(Node))
#define TreeNew_Scroll(hWnd, DeltaRows, DeltaX) \
SendMessage((hWnd), TNM_SCROLL, (WPARAM)(DeltaRows), (LPARAM)(DeltaX))
#define TreeNew_GetFlatNodeCount(hWnd) \
((ULONG)SendMessage((hWnd), TNM_GETFLATNODECOUNT, 0, 0))
#define TreeNew_GetFlatNode(hWnd, Index) \
((PPH_TREENEW_NODE)SendMessage((hWnd), TNM_GETFLATNODE, (WPARAM)(Index), 0))
#define TreeNew_GetCellText(hWnd, GetCellText) \
SendMessage((hWnd), TNM_GETCELLTEXT, 0, (LPARAM)(GetCellText))
#define TreeNew_SetNodeExpanded(hWnd, Node, Expanded) \
SendMessage((hWnd), TNM_SETNODEEXPANDED, (WPARAM)(Expanded), (LPARAM)(Node))
#define TreeNew_GetMaxId(hWnd) \
((ULONG)SendMessage((hWnd), TNM_GETMAXID, 0, 0))
#define TreeNew_SetMaxId(hWnd, MaxId) \
SendMessage((hWnd), TNM_SETMAXID, (WPARAM)(MaxId), 0)
#define TreeNew_InvalidateNode(hWnd, Node) \
SendMessage((hWnd), TNM_INVALIDATENODE, 0, (LPARAM)(Node))
#define TreeNew_InvalidateNodes(hWnd, Start, End) \
SendMessage((hWnd), TNM_INVALIDATENODES, (WPARAM)(Start), (LPARAM)(End))
#define TreeNew_GetFixedHeader(hWnd) \
((HWND)SendMessage((hWnd), TNM_GETFIXEDHEADER, 0, 0))
#define TreeNew_GetHeader(hWnd) \
((HWND)SendMessage((hWnd), TNM_GETHEADER, 0, 0))
#define TreeNew_GetTooltips(hWnd) \
((HWND)SendMessage((hWnd), TNM_GETTOOLTIPS, 0, 0))
#define TreeNew_SelectRange(hWnd, Start, End) \
SendMessage((hWnd), TNM_SELECTRANGE, (WPARAM)(Start), (LPARAM)(End))
#define TreeNew_DeselectRange(hWnd, Start, End) \
SendMessage((hWnd), TNM_DESELECTRANGE, (WPARAM)(Start), (LPARAM)(End))
#define TreeNew_GetColumnCount(hWnd) \
((ULONG)SendMessage((hWnd), TNM_GETCOLUMNCOUNT, 0, 0))
#define TreeNew_SetRedraw(hWnd, Redraw) \
((LONG)SendMessage((hWnd), TNM_SETREDRAW, (WPARAM)(Redraw), 0))
#define TreeNew_GetViewParts(hWnd, Parts) \
SendMessage((hWnd), TNM_GETVIEWPARTS, 0, (LPARAM)(Parts))
#define TreeNew_GetFixedColumn(hWnd) \
((PPH_TREENEW_COLUMN)SendMessage((hWnd), TNM_GETFIXEDCOLUMN, 0, 0))
#define TreeNew_GetFirstColumn(hWnd) \
((PPH_TREENEW_COLUMN)SendMessage((hWnd), TNM_GETFIRSTCOLUMN, 0, 0))
#define TreeNew_SetFocusNode(hWnd, Node) \
SendMessage((hWnd), TNM_SETFOCUSNODE, 0, (LPARAM)(Node))
#define TreeNew_SetMarkNode(hWnd, Node) \
SendMessage((hWnd), TNM_SETMARKNODE, 0, (LPARAM)(Node))
#define TreeNew_SetHotNode(hWnd, Node) \
SendMessage((hWnd), TNM_SETHOTNODE, 0, (LPARAM)(Node))
#define TreeNew_SetExtendedFlags(hWnd, Mask, Value) \
SendMessage((hWnd), TNM_SETEXTENDEDFLAGS, (WPARAM)(Mask), (LPARAM)(Value))
#define TreeNew_GetCallback(hWnd, Callback, Context) \
SendMessage((hWnd), TNM_GETCALLBACK, (WPARAM)(Context), (LPARAM)(Callback))
#define TreeNew_HitTest(hWnd, HitTest) \
SendMessage((hWnd), TNM_HITTEST, 0, (LPARAM)(HitTest))
#define TreeNew_GetVisibleColumnCount(hWnd) \
((ULONG)SendMessage((hWnd), TNM_GETVISIBLECOLUMNCOUNT, 0, 0))
#define TreeNew_AutoSizeColumn(hWnd, Id, Flags) \
SendMessage((hWnd), TNM_AUTOSIZECOLUMN, (WPARAM)(Id), (LPARAM)(Flags))
#define TreeNew_SetEmptyText(hWnd, Text, Flags) \
SendMessage((hWnd), TNM_SETEMPTYTEXT, (WPARAM)(Flags), (LPARAM)(Text))
#define TreeNew_SetRowHeight(hWnd, RowHeight) \
SendMessage((hWnd), TNM_SETROWHEIGHT, (WPARAM)(RowHeight), 0)
#define TreeNew_IsFlatNodeValid(hWnd) \
((BOOLEAN)SendMessage((hWnd), TNM_ISFLATNODEVALID, 0, 0))
typedef struct _PH_TREENEW_VIEW_PARTS
{
RECT ClientRect;
LONG HeaderHeight;
LONG RowHeight;
ULONG VScrollWidth;
ULONG HScrollHeight;
LONG VScrollPosition;
LONG HScrollPosition;
LONG FixedWidth;
LONG NormalLeft;
LONG NormalWidth;
} PH_TREENEW_VIEW_PARTS, *PPH_TREENEW_VIEW_PARTS;
PHLIBAPI
BOOLEAN PhTreeNewInitialization(
VOID
);
FORCEINLINE VOID PhInitializeTreeNewNode(
_In_ PPH_TREENEW_NODE Node
)
{
memset(Node, 0, sizeof(PH_TREENEW_NODE));
Node->Visible = TRUE;
Node->Expanded = TRUE;
}
FORCEINLINE VOID PhInvalidateTreeNewNode(
_Inout_ PPH_TREENEW_NODE Node,
_In_ ULONG Flags
)
{
if (Flags & TN_CACHE_COLOR)
Node->s.CachedColorValid = FALSE;
if (Flags & TN_CACHE_FONT)
Node->s.CachedFontValid = FALSE;
if (Flags & TN_CACHE_ICON)
Node->s.CachedIconValid = FALSE;
}
FORCEINLINE BOOLEAN PhAddTreeNewColumn(
_In_ HWND hwnd,
_In_ ULONG Id,
_In_ BOOLEAN Visible,
_In_ PWSTR Text,
_In_ ULONG Width,
_In_ ULONG Alignment,
_In_ ULONG DisplayIndex,
_In_ ULONG TextFlags
)
{
PH_TREENEW_COLUMN column;
memset(&column, 0, sizeof(PH_TREENEW_COLUMN));
column.Id = Id;
column.Visible = Visible;
column.Text = Text;
column.Width = Width;
column.Alignment = Alignment;
column.DisplayIndex = DisplayIndex;
column.TextFlags = TextFlags;
column.DpiScaleOnAdd = TRUE;
if (DisplayIndex == -2)
column.Fixed = TRUE;
return !!TreeNew_AddColumn(hwnd, &column);
}
FORCEINLINE BOOLEAN PhAddTreeNewColumnEx(
_In_ HWND hwnd,
_In_ ULONG Id,
_In_ BOOLEAN Visible,
_In_ PWSTR Text,
_In_ ULONG Width,
_In_ ULONG Alignment,
_In_ ULONG DisplayIndex,
_In_ ULONG TextFlags,
_In_ BOOLEAN SortDescending
)
{
PH_TREENEW_COLUMN column;
memset(&column, 0, sizeof(PH_TREENEW_COLUMN));
column.Id = Id;
column.Visible = Visible;
column.Text = Text;
column.Width = Width;
column.Alignment = Alignment;
column.DisplayIndex = DisplayIndex;
column.TextFlags = TextFlags;
column.DpiScaleOnAdd = TRUE;
if (DisplayIndex == -2)
column.Fixed = TRUE;
if (SortDescending)
column.SortDescending = TRUE;
return !!TreeNew_AddColumn(hwnd, &column);
}
FORCEINLINE BOOLEAN PhAddTreeNewColumnEx2(
_In_ HWND hwnd,
_In_ ULONG Id,
_In_ BOOLEAN Visible,
_In_ PWSTR Text,
_In_ ULONG Width,
_In_ ULONG Alignment,
_In_ ULONG DisplayIndex,
_In_ ULONG TextFlags,
_In_ ULONG ExtraFlags
)
{
PH_TREENEW_COLUMN column;
memset(&column, 0, sizeof(PH_TREENEW_COLUMN));
column.Id = Id;
column.Visible = Visible;
column.Text = Text;
column.Width = Width;
column.Alignment = Alignment;
column.DisplayIndex = DisplayIndex;
column.TextFlags = TextFlags;
if (DisplayIndex == -2)
column.Fixed = TRUE;
if (ExtraFlags & TN_COLUMN_FLAG_CUSTOMDRAW)
column.CustomDraw = TRUE;
if (ExtraFlags & TN_COLUMN_FLAG_SORTDESCENDING)
column.SortDescending = TRUE;
if (!(ExtraFlags & TN_COLUMN_FLAG_NODPISCALEONADD))
column.DpiScaleOnAdd = TRUE;
return !!TreeNew_AddColumn(hwnd, &column);
}
#ifdef __cplusplus
}
#endif
#endif

802
phlib/include/treenewp.h Normal file
View File

@@ -0,0 +1,802 @@
#ifndef _PH_TREENEWP_H
#define _PH_TREENEWP_H
// Important notes about pointers:
//
// All memory allocation for nodes and strings is handled by the user. This usually means there is a
// very limited time during which they can be safely accessed.
//
// Node pointers are valid through the duration of message processing, and also up to the next
// restructure operation, either user- or control- initiated. This means that state such as the
// focused node, hot node and mark node must be carefully preserved through restructuring. If
// restructuring is suspended by a set-redraw call, all nodes must be considered invalid and no user
// input can be handled.
//
// Strings are valid only through the duration of message processing.
typedef struct _PH_TREENEW_CONTEXT
{
HWND Handle;
PVOID InstanceHandle;
HWND FixedHeaderHandle;
HWND HeaderHandle;
HWND VScrollHandle;
HWND HScrollHandle;
HWND FillerBoxHandle;
HWND TooltipsHandle;
union
{
struct
{
ULONG FontOwned : 1;
ULONG Tracking : 1; // tracking for fixed divider
ULONG VScrollVisible : 1;
ULONG HScrollVisible : 1;
ULONG FixedColumnVisible : 1;
ULONG FixedDividerVisible : 1;
ULONG AnimateDivider : 1;
ULONG AnimateDividerFadingIn : 1;
ULONG AnimateDividerFadingOut : 1;
ULONG CanAnyExpand : 1;
ULONG TriState : 1;
ULONG HasFocus : 1;
ULONG ThemeInitialized : 1; // delay load theme data
ULONG ThemeActive : 1;
ULONG ThemeHasItemBackground : 1;
ULONG ThemeHasGlyph : 1;
ULONG ThemeHasHotGlyph : 1;
ULONG FocusNodeFound : 1; // used to preserve the focused node across restructuring
ULONG SearchFailed : 1; // used to prevent multiple beeps
ULONG SearchSingleCharMode : 1; // LV style single-character search
ULONG TooltipUnfolding : 1; // whether the current tooltip is unfolding
ULONG DoubleBuffered : 1;
ULONG SuspendUpdateStructure : 1;
ULONG SuspendUpdateLayout : 1;
ULONG SuspendUpdateMoveMouse : 1;
ULONG DragSelectionActive : 1;
ULONG SelectionRectangleAlpha : 1; // use alpha blending for the selection rectangle
ULONG CustomRowHeight : 1;
ULONG Spare : 4;
};
ULONG Flags;
};
ULONG Style;
ULONG ExtendedStyle;
ULONG ExtendedFlags;
HFONT Font;
HCURSOR Cursor;
HCURSOR DividerCursor;
RECT ClientRect;
LONG HeaderHeight;
LONG RowHeight;
ULONG VScrollWidth;
ULONG HScrollHeight;
LONG VScrollPosition;
LONG HScrollPosition;
LONG FixedWidth; // width of the fixed part of the tree list
LONG FixedWidthMinimum;
LONG NormalLeft; // FixedWidth + 1 if there is a fixed column, otherwise 0
PPH_TREENEW_NODE FocusNode;
ULONG HotNodeIndex;
ULONG MarkNodeIndex; // selection mark
ULONG MouseDownLast;
POINT MouseDownLocation;
PPH_TREENEW_CALLBACK Callback;
PVOID CallbackContext;
PPH_TREENEW_COLUMN *Columns; // columns, indexed by ID
ULONG NextId;
ULONG AllocatedColumns;
ULONG NumberOfColumns; // just a statistic; do not use for actual logic
PPH_TREENEW_COLUMN *ColumnsByDisplay; // columns, indexed by display order (excluding the fixed column)
ULONG AllocatedColumnsByDisplay;
ULONG NumberOfColumnsByDisplay; // the number of visible columns (excluding the fixed column)
LONG TotalViewX; // total width of normal columns
PPH_TREENEW_COLUMN FixedColumn;
PPH_TREENEW_COLUMN FirstColumn; // first column, by display order (including the fixed column)
PPH_TREENEW_COLUMN LastColumn; // last column, by display order (including the fixed column)
PPH_TREENEW_COLUMN ResizingColumn;
LONG OldColumnWidth;
LONG TrackStartX;
LONG TrackOldFixedWidth;
ULONG DividerHot; // 0 for un-hot, 100 for completely hot
PPH_LIST FlatList;
ULONG SortColumn; // ID of the column to sort by
PH_SORT_ORDER SortOrder;
FLOAT VScrollRemainder;
FLOAT HScrollRemainder;
LONG SearchMessageTime;
PWSTR SearchString;
ULONG SearchStringCount;
ULONG AllocatedSearchString;
ULONG TooltipIndex;
ULONG TooltipId;
PPH_STRING TooltipText;
RECT TooltipRect; // text rectangle of an unfolding tooltip
HFONT TooltipFont;
HFONT NewTooltipFont;
ULONG TooltipColumnId;
WNDPROC FixedHeaderOldWndProc;
WNDPROC HeaderOldWndProc;
TEXTMETRIC TextMetrics;
HTHEME ThemeData;
LONG SystemBorderX;
LONG SystemBorderY;
LONG SystemEdgeX;
LONG SystemEdgeY;
HDC BufferedContext;
HBITMAP BufferedOldBitmap;
HBITMAP BufferedBitmap;
RECT BufferedContextRect;
LONG SystemDragX;
LONG SystemDragY;
RECT DragRect;
LONG EnableRedraw;
HRGN SuspendUpdateRegion;
PH_STRINGREF EmptyText;
} PH_TREENEW_CONTEXT, *PPH_TREENEW_CONTEXT;
LRESULT CALLBACK PhTnpWndProc(
_In_ HWND hwnd,
_In_ UINT uMsg,
_In_ WPARAM wParam,
_In_ LPARAM lParam
);
BOOLEAN NTAPI PhTnpNullCallback(
_In_ HWND hwnd,
_In_ PH_TREENEW_MESSAGE Message,
_In_opt_ PVOID Parameter1,
_In_opt_ PVOID Parameter2,
_In_opt_ PVOID Context
);
VOID PhTnpCreateTreeNewContext(
_Out_ PPH_TREENEW_CONTEXT *Context
);
VOID PhTnpDestroyTreeNewContext(
_In_ PPH_TREENEW_CONTEXT Context
);
// Event handlers
BOOLEAN PhTnpOnCreate(
_In_ HWND hwnd,
_In_ PPH_TREENEW_CONTEXT Context,
_In_ CREATESTRUCT *CreateStruct
);
VOID PhTnpOnSize(
_In_ HWND hwnd,
_In_ PPH_TREENEW_CONTEXT Context
);
VOID PhTnpOnSetFont(
_In_ HWND hwnd,
_In_ PPH_TREENEW_CONTEXT Context,
_In_opt_ HFONT Font,
_In_ LOGICAL Redraw
);
VOID PhTnpOnStyleChanged(
_In_ HWND hwnd,
_In_ PPH_TREENEW_CONTEXT Context,
_In_ LONG Type,
_In_ STYLESTRUCT *StyleStruct
);
VOID PhTnpOnSettingChange(
_In_ HWND hwnd,
_In_ PPH_TREENEW_CONTEXT Context
);
VOID PhTnpOnThemeChanged(
_In_ HWND hwnd,
_In_ PPH_TREENEW_CONTEXT Context
);
ULONG PhTnpOnGetDlgCode(
_In_ HWND hwnd,
_In_ PPH_TREENEW_CONTEXT Context,
_In_ ULONG VirtualKey,
_In_opt_ PMSG Message
);
VOID PhTnpOnPaint(
_In_ HWND hwnd,
_In_ PPH_TREENEW_CONTEXT Context
);
VOID PhTnpOnPrintClient(
_In_ HWND hwnd,
_In_ PPH_TREENEW_CONTEXT Context,
_In_ HDC hdc,
_In_ ULONG Flags
);
BOOLEAN PhTnpOnNcPaint(
_In_ HWND hwnd,
_In_ PPH_TREENEW_CONTEXT Context,
_In_opt_ HRGN UpdateRegion
);
BOOLEAN PhTnpOnSetCursor(
_In_ HWND hwnd,
_In_ PPH_TREENEW_CONTEXT Context,
_In_ HWND CursorWindowHandle
);
VOID PhTnpOnTimer(
_In_ HWND hwnd,
_In_ PPH_TREENEW_CONTEXT Context,
_In_ ULONG Id
);
VOID PhTnpOnMouseMove(
_In_ HWND hwnd,
_In_ PPH_TREENEW_CONTEXT Context,
_In_ ULONG VirtualKeys,
_In_ LONG CursorX,
_In_ LONG CursorY
);
VOID PhTnpOnMouseLeave(
_In_ HWND hwnd,
_In_ PPH_TREENEW_CONTEXT Context
);
VOID PhTnpOnXxxButtonXxx(
_In_ HWND hwnd,
_In_ PPH_TREENEW_CONTEXT Context,
_In_ ULONG Message,
_In_ ULONG VirtualKeys,
_In_ LONG CursorX,
_In_ LONG CursorY
);
VOID PhTnpOnCaptureChanged(
_In_ HWND hwnd,
_In_ PPH_TREENEW_CONTEXT Context
);
VOID PhTnpOnKeyDown(
_In_ HWND hwnd,
_In_ PPH_TREENEW_CONTEXT Context,
_In_ ULONG VirtualKey,
_In_ ULONG Data
);
VOID PhTnpOnChar(
_In_ HWND hwnd,
_In_ PPH_TREENEW_CONTEXT Context,
_In_ ULONG Character,
_In_ ULONG Data
);
VOID PhTnpOnMouseWheel(
_In_ HWND hwnd,
_In_ PPH_TREENEW_CONTEXT Context,
_In_ LONG Distance,
_In_ ULONG VirtualKeys,
_In_ LONG CursorX,
_In_ LONG CursorY
);
VOID PhTnpOnMouseHWheel(
_In_ HWND hwnd,
_In_ PPH_TREENEW_CONTEXT Context,
_In_ LONG Distance,
_In_ ULONG VirtualKeys,
_In_ LONG CursorX,
_In_ LONG CursorY
);
VOID PhTnpOnContextMenu(
_In_ HWND hwnd,
_In_ PPH_TREENEW_CONTEXT Context,
_In_ LONG CursorScreenX,
_In_ LONG CursorScreenY
);
VOID PhTnpOnVScroll(
_In_ HWND hwnd,
_In_ PPH_TREENEW_CONTEXT Context,
_In_ ULONG Request,
_In_ USHORT Position
);
VOID PhTnpOnHScroll(
_In_ HWND hwnd,
_In_ PPH_TREENEW_CONTEXT Context,
_In_ ULONG Request,
_In_ USHORT Position
);
BOOLEAN PhTnpOnNotify(
_In_ HWND hwnd,
_In_ PPH_TREENEW_CONTEXT Context,
_In_ NMHDR *Header,
_Out_ LRESULT *Result
);
ULONG_PTR PhTnpOnUserMessage(
_In_ HWND hwnd,
_In_ PPH_TREENEW_CONTEXT Context,
_In_ ULONG Message,
_In_ ULONG_PTR WParam,
_In_ ULONG_PTR LParam
);
// Misc.
VOID PhTnpSetFont(
_In_ PPH_TREENEW_CONTEXT Context,
_In_opt_ HFONT Font,
_In_ BOOLEAN Redraw
);
VOID PhTnpUpdateSystemMetrics(
_In_ PPH_TREENEW_CONTEXT Context
);
VOID PhTnpUpdateTextMetrics(
_In_ PPH_TREENEW_CONTEXT Context
);
VOID PhTnpUpdateThemeData(
_In_ PPH_TREENEW_CONTEXT Context
);
VOID PhTnpInitializeThemeData(
_In_ PPH_TREENEW_CONTEXT Context
);
VOID PhTnpCancelTrack(
_In_ PPH_TREENEW_CONTEXT Context
);
VOID PhTnpLayout(
_In_ PPH_TREENEW_CONTEXT Context
);
VOID PhTnpLayoutHeader(
_In_ PPH_TREENEW_CONTEXT Context
);
VOID PhTnpSetFixedWidth(
_In_ PPH_TREENEW_CONTEXT Context,
_In_ ULONG FixedWidth
);
VOID PhTnpSetRedraw(
_In_ PPH_TREENEW_CONTEXT Context,
_In_ BOOLEAN Redraw
);
VOID PhTnpSendMouseEvent(
_In_ PPH_TREENEW_CONTEXT Context,
_In_ PH_TREENEW_MESSAGE Message,
_In_ LONG CursorX,
_In_ LONG CursorY,
_In_ PPH_TREENEW_NODE Node,
_In_ PPH_TREENEW_COLUMN Column,
_In_ ULONG VirtualKeys
);
// Columns
PPH_TREENEW_COLUMN PhTnpLookupColumnById(
_In_ PPH_TREENEW_CONTEXT Context,
_In_ ULONG Id
);
BOOLEAN PhTnpAddColumn(
_In_ PPH_TREENEW_CONTEXT Context,
_In_ PPH_TREENEW_COLUMN Column
);
BOOLEAN PhTnpRemoveColumn(
_In_ PPH_TREENEW_CONTEXT Context,
_In_ ULONG Id
);
BOOLEAN PhTnpCopyColumn(
_In_ PPH_TREENEW_CONTEXT Context,
_In_ ULONG Id,
_Out_ PPH_TREENEW_COLUMN Column
);
BOOLEAN PhTnpChangeColumn(
_In_ PPH_TREENEW_CONTEXT Context,
_In_ ULONG Mask,
_In_ ULONG Id,
_In_ PPH_TREENEW_COLUMN Column
);
VOID PhTnpExpandAllocatedColumns(
_In_ PPH_TREENEW_CONTEXT Context
);
VOID PhTnpUpdateColumnMaps(
_In_ PPH_TREENEW_CONTEXT Context
);
// Columns (header control)
LONG PhTnpInsertColumnHeader(
_In_ PPH_TREENEW_CONTEXT Context,
_In_ PPH_TREENEW_COLUMN Column
);
VOID PhTnpChangeColumnHeader(
_In_ PPH_TREENEW_CONTEXT Context,
_In_ ULONG Mask,
_In_ PPH_TREENEW_COLUMN Column
);
VOID PhTnpDeleteColumnHeader(
_In_ PPH_TREENEW_CONTEXT Context,
_Inout_ PPH_TREENEW_COLUMN Column
);
VOID PhTnpUpdateColumnHeaders(
_In_ PPH_TREENEW_CONTEXT Context
);
VOID PhTnpProcessResizeColumn(
_In_ PPH_TREENEW_CONTEXT Context,
_In_ PPH_TREENEW_COLUMN Column,
_In_ LONG Delta
);
VOID PhTnpProcessSortColumn(
_In_ PPH_TREENEW_CONTEXT Context,
_In_ PPH_TREENEW_COLUMN NewColumn
);
BOOLEAN PhTnpSetColumnHeaderSortIcon(
_In_ PPH_TREENEW_CONTEXT Context,
_In_opt_ PPH_TREENEW_COLUMN SortColumnPointer
);
VOID PhTnpAutoSizeColumnHeader(
_In_ PPH_TREENEW_CONTEXT Context,
_In_ HWND HeaderHandle,
_In_ PPH_TREENEW_COLUMN Column,
_In_ ULONG Flags
);
// Nodes
BOOLEAN PhTnpGetNodeChildren(
_In_ PPH_TREENEW_CONTEXT Context,
_In_opt_ PPH_TREENEW_NODE Node,
_Out_ PPH_TREENEW_NODE **Children,
_Out_ PULONG NumberOfChildren
);
BOOLEAN PhTnpIsNodeLeaf(
_In_ PPH_TREENEW_CONTEXT Context,
_In_ PPH_TREENEW_NODE Node
);
BOOLEAN PhTnpGetCellText(
_In_ PPH_TREENEW_CONTEXT Context,
_In_ PPH_TREENEW_NODE Node,
_In_ ULONG Id,
_Out_ PPH_STRINGREF Text
);
VOID PhTnpRestructureNodes(
_In_ PPH_TREENEW_CONTEXT Context
);
VOID PhTnpInsertNodeChildren(
_In_ PPH_TREENEW_CONTEXT Context,
_In_ PPH_TREENEW_NODE Node,
_In_ ULONG Level
);
VOID PhTnpSetExpandedNode(
_In_ PPH_TREENEW_CONTEXT Context,
_In_ PPH_TREENEW_NODE Node,
_In_ BOOLEAN Expanded
);
BOOLEAN PhTnpGetCellParts(
_In_ PPH_TREENEW_CONTEXT Context,
_In_ ULONG Index,
_In_opt_ PPH_TREENEW_COLUMN Column,
_In_ ULONG Flags,
_Out_ PPH_TREENEW_CELL_PARTS Parts
);
BOOLEAN PhTnpGetRowRects(
_In_ PPH_TREENEW_CONTEXT Context,
_In_ ULONG Start,
_In_ ULONG End,
_In_ BOOLEAN Clip,
_Out_ PRECT Rect
);
VOID PhTnpHitTest(
_In_ PPH_TREENEW_CONTEXT Context,
_Inout_ PPH_TREENEW_HIT_TEST HitTest
);
VOID PhTnpSelectRange(
_In_ PPH_TREENEW_CONTEXT Context,
_In_ ULONG Start,
_In_ ULONG End,
_In_ ULONG Flags,
_Out_opt_ PULONG ChangedStart,
_Out_opt_ PULONG ChangedEnd
);
VOID PhTnpSetHotNode(
_In_ PPH_TREENEW_CONTEXT Context,
_In_opt_ PPH_TREENEW_NODE NewHotNode,
_In_ BOOLEAN NewPlusMinusHot
);
VOID PhTnpProcessSelectNode(
_In_ PPH_TREENEW_CONTEXT Context,
_In_ PPH_TREENEW_NODE Node,
_In_ LOGICAL ControlKey,
_In_ LOGICAL ShiftKey,
_In_ LOGICAL RightButton
);
BOOLEAN PhTnpEnsureVisibleNode(
_In_ PPH_TREENEW_CONTEXT Context,
_In_ ULONG Index
);
// Mouse
VOID PhTnpProcessMoveMouse(
_In_ PPH_TREENEW_CONTEXT Context,
_In_ LONG CursorX,
_In_ LONG CursorY
);
VOID PhTnpProcessMouseVWheel(
_In_ PPH_TREENEW_CONTEXT Context,
_In_ LONG Distance
);
VOID PhTnpProcessMouseHWheel(
_In_ PPH_TREENEW_CONTEXT Context,
_In_ LONG Distance
);
// Keyboard
BOOLEAN PhTnpProcessFocusKey(
_In_ PPH_TREENEW_CONTEXT Context,
_In_ ULONG VirtualKey
);
BOOLEAN PhTnpProcessNodeKey(
_In_ PPH_TREENEW_CONTEXT Context,
_In_ ULONG VirtualKey
);
VOID PhTnpProcessSearchKey(
_In_ PPH_TREENEW_CONTEXT Context,
_In_ ULONG Character
);
BOOLEAN PhTnpDefaultIncrementalSearch(
_In_ PPH_TREENEW_CONTEXT Context,
_Inout_ PPH_TREENEW_SEARCH_EVENT SearchEvent,
_In_ BOOLEAN Partial,
_In_ BOOLEAN Wrap
);
// Scrolling
VOID PhTnpUpdateScrollBars(
_In_ PPH_TREENEW_CONTEXT Context
);
VOID PhTnpScroll(
_In_ PPH_TREENEW_CONTEXT Context,
_In_ LONG DeltaRows,
_In_ LONG DeltaX
);
VOID PhTnpProcessScroll(
_In_ PPH_TREENEW_CONTEXT Context,
_In_ LONG DeltaRows,
_In_ LONG DeltaX
);
BOOLEAN PhTnpCanScroll(
_In_ PPH_TREENEW_CONTEXT Context,
_In_ BOOLEAN Horizontal,
_In_ BOOLEAN Positive
);
// Drawing
VOID PhTnpPaint(
_In_ HWND hwnd,
_In_ PPH_TREENEW_CONTEXT Context,
_In_ HDC hdc,
_In_ PRECT PaintRect
);
VOID PhTnpPrepareRowForDraw(
_In_ PPH_TREENEW_CONTEXT Context,
_In_ HDC hdc,
_Inout_ PPH_TREENEW_NODE Node
);
VOID PhTnpDrawCell(
_In_ PPH_TREENEW_CONTEXT Context,
_In_ HDC hdc,
_In_ PRECT CellRect,
_In_ PPH_TREENEW_NODE Node,
_In_ PPH_TREENEW_COLUMN Column,
_In_ LONG RowIndex,
_In_ LONG ColumnIndex
);
VOID PhTnpDrawDivider(
_In_ PPH_TREENEW_CONTEXT Context,
_In_ HDC hdc
);
VOID PhTnpDrawPlusMinusGlyph(
_In_ HDC hdc,
_In_ PRECT Rect,
_In_ BOOLEAN Plus
);
VOID PhTnpDrawSelectionRectangle(
_In_ PPH_TREENEW_CONTEXT Context,
_In_ HDC hdc,
_In_ PRECT Rect
);
VOID PhTnpDrawThemedBorder(
_In_ PPH_TREENEW_CONTEXT Context,
_In_ HDC hdc
);
// Tooltips
VOID PhTnpInitializeTooltips(
_In_ PPH_TREENEW_CONTEXT Context
);
VOID PhTnpGetTooltipText(
_In_ PPH_TREENEW_CONTEXT Context,
_In_ PPOINT Point,
_Out_ PWSTR *Text
);
BOOLEAN PhTnpPrepareTooltipShow(
_In_ PPH_TREENEW_CONTEXT Context
);
VOID PhTnpPrepareTooltipPop(
_In_ PPH_TREENEW_CONTEXT Context
);
VOID PhTnpPopTooltip(
_In_ PPH_TREENEW_CONTEXT Context
);
PPH_TREENEW_COLUMN PhTnpHitTestHeader(
_In_ PPH_TREENEW_CONTEXT Context,
_In_ BOOLEAN Fixed,
_In_ PPOINT Point,
_Out_opt_ PRECT ItemRect
);
VOID PhTnpGetHeaderTooltipText(
_In_ PPH_TREENEW_CONTEXT Context,
_In_ BOOLEAN Fixed,
_In_ PPOINT Point,
_Out_ PWSTR *Text
);
PWSTR PhTnpMakeContextAtom(
VOID
);
LRESULT CALLBACK PhTnpHeaderHookWndProc(
_In_ HWND hwnd,
_In_ UINT uMsg,
_In_ WPARAM wParam,
_In_ LPARAM lParam
);
// Drag selection
BOOLEAN PhTnpDetectDrag(
_In_ PPH_TREENEW_CONTEXT Context,
_In_ LONG CursorX,
_In_ LONG CursorY,
_In_ BOOLEAN DispatchMessages,
_Out_opt_ PULONG CancelledByMessage
);
VOID PhTnpDragSelect(
_In_ PPH_TREENEW_CONTEXT Context,
_In_ LONG CursorX,
_In_ LONG CursorY
);
VOID PhTnpProcessDragSelect(
_In_ PPH_TREENEW_CONTEXT Context,
_In_ ULONG VirtualKeys,
_In_ PRECT OldRect,
_In_ PRECT NewRect,
_In_ PRECT TotalRect
);
// Double buffering
VOID PhTnpCreateBufferedContext(
_In_ PPH_TREENEW_CONTEXT Context
);
VOID PhTnpDestroyBufferedContext(
_In_ PPH_TREENEW_CONTEXT Context
);
// Support functions
VOID PhTnpGetMessagePos(
_In_ HWND hwnd,
_Out_ PPOINT ClientPoint
);
// Macros
#define HRGN_FULL ((HRGN)1) // passed by WM_NCPAINT even though it's completely undocumented
#define TNP_CELL_LEFT_MARGIN 6
#define TNP_CELL_RIGHT_MARGIN 6
#define TNP_ICON_RIGHT_PADDING 4
#define TNP_TIMER_NULL 1
#define TNP_TIMER_ANIMATE_DIVIDER 2
#define TNP_TOOLTIPS_ITEM 0
#define TNP_TOOLTIPS_FIXED_HEADER 1
#define TNP_TOOLTIPS_HEADER 2
#define TNP_TOOLTIPS_DEFAULT_MAXIMUM_WIDTH 550
#define TNP_ANIMATE_DIVIDER_INTERVAL 10
#define TNP_ANIMATE_DIVIDER_INCREMENT 17
#define TNP_ANIMATE_DIVIDER_DECREMENT 2
#define TNP_HIT_TEST_FIXED_DIVIDER(X, Context) \
((Context)->FixedDividerVisible && (X) >= (Context)->FixedWidth - 8 && (X) < (Context)->FixedWidth + 8)
#define TNP_HIT_TEST_PLUS_MINUS_GLYPH(X, NodeLevel) \
(((X) >= TNP_CELL_LEFT_MARGIN + ((LONG)(NodeLevel) * SmallIconWidth)) && ((X) < TNP_CELL_LEFT_MARGIN + ((LONG)(NodeLevel) * SmallIconWidth) + SmallIconWidth))
#endif

77
phlib/include/verify.h Normal file
View File

@@ -0,0 +1,77 @@
#ifndef _PH_VERIFY_H
#define _PH_VERIFY_H
#include <wintrust.h>
#include <softpub.h>
#ifdef __cplusplus
extern "C" {
#endif
#define PH_VERIFY_DEFAULT_SIZE_LIMIT (32 * 1024 * 1024)
typedef enum _VERIFY_RESULT
{
VrUnknown = 0,
VrNoSignature,
VrTrusted,
VrExpired,
VrRevoked,
VrDistrust,
VrSecuritySettings,
VrBadSignature
} VERIFY_RESULT, *PVERIFY_RESULT;
#define PH_VERIFY_PREVENT_NETWORK_ACCESS 0x1
#define PH_VERIFY_VIEW_PROPERTIES 0x2
typedef struct _PH_VERIFY_FILE_INFO
{
PWSTR FileName;
ULONG Flags; // PH_VERIFY_*
ULONG FileSizeLimitForHash; // 0 for PH_VERIFY_DEFAULT_SIZE_LIMIT, -1 for unlimited
ULONG NumberOfCatalogFileNames;
PWSTR *CatalogFileNames;
HWND hWnd; // for PH_VERIFY_VIEW_PROPERTIES
} PH_VERIFY_FILE_INFO, *PPH_VERIFY_FILE_INFO;
PHLIBAPI
VERIFY_RESULT
NTAPI
PhVerifyFile(
_In_ PWSTR FileName,
_Out_opt_ PPH_STRING *SignerName
);
PHLIBAPI
NTSTATUS
NTAPI
PhVerifyFileEx(
_In_ PPH_VERIFY_FILE_INFO Information,
_Out_ VERIFY_RESULT *VerifyResult,
_Out_opt_ PCERT_CONTEXT **Signatures,
_Out_opt_ PULONG NumberOfSignatures
);
PHLIBAPI
VOID
NTAPI
PhFreeVerifySignatures(
_In_ PCERT_CONTEXT *Signatures,
_In_ ULONG NumberOfSignatures
);
PHLIBAPI
PPH_STRING
NTAPI
PhGetSignerNameFromCertificate(
_In_ PCERT_CONTEXT Certificate
);
#ifdef __cplusplus
}
#endif
#endif

118
phlib/include/verifyp.h Normal file
View File

@@ -0,0 +1,118 @@
#ifndef _PH_VERIFYP_H
#define _PH_VERIFYP_H
#include <commdlg.h>
typedef struct _CATALOG_INFO
{
DWORD cbStruct;
WCHAR wszCatalogFile[MAX_PATH];
} CATALOG_INFO, *PCATALOG_INFO;
typedef struct tagCRYPTUI_VIEWSIGNERINFO_STRUCT {
DWORD dwSize;
HWND hwndParent;
DWORD dwFlags;
LPCTSTR szTitle;
CMSG_SIGNER_INFO *pSignerInfo;
HCRYPTMSG hMsg;
LPCSTR pszOID;
DWORD_PTR dwReserved;
DWORD cStores;
HCERTSTORE *rghStores;
DWORD cPropSheetPages;
LPCPROPSHEETPAGE rgPropSheetPages;
} CRYPTUI_VIEWSIGNERINFO_STRUCT, *PCRYPTUI_VIEWSIGNERINFO_STRUCT;
typedef BOOL (WINAPI *_CryptCATAdminCalcHashFromFileHandle)(
HANDLE hFile,
DWORD *pcbHash,
BYTE *pbHash,
DWORD dwFlags
);
typedef BOOL (WINAPI *_CryptCATAdminCalcHashFromFileHandle2)(
HCATADMIN hCatAdmin,
HANDLE hFile,
DWORD *pcbHash,
BYTE *pbHash,
DWORD dwFlags
);
typedef BOOL (WINAPI *_CryptCATAdminAcquireContext)(
HANDLE *phCatAdmin,
GUID *pgSubsystem,
DWORD dwFlags
);
typedef BOOL (WINAPI *_CryptCATAdminAcquireContext2)(
HCATADMIN *phCatAdmin,
const GUID *pgSubsystem,
PCWSTR pwszHashAlgorithm,
PCCERT_STRONG_SIGN_PARA pStrongHashPolicy,
DWORD dwFlags
);
typedef HANDLE (WINAPI *_CryptCATAdminEnumCatalogFromHash)(
HANDLE hCatAdmin,
BYTE *pbHash,
DWORD cbHash,
DWORD dwFlags,
HANDLE *phPrevCatInfo
);
typedef BOOL (WINAPI *_CryptCATCatalogInfoFromContext)(
HANDLE hCatInfo,
CATALOG_INFO *psCatInfo,
DWORD dwFlags
);
typedef BOOL (WINAPI *_CryptCATAdminReleaseCatalogContext)(
HANDLE hCatAdmin,
HANDLE hCatInfo,
DWORD dwFlags
);
typedef BOOL (WINAPI *_CryptCATAdminReleaseContext)(
HANDLE hCatAdmin,
DWORD dwFlags
);
typedef PCRYPT_PROVIDER_DATA (WINAPI *_WTHelperProvDataFromStateData)(
HANDLE hStateData
);
typedef PCRYPT_PROVIDER_SGNR (WINAPI *_WTHelperGetProvSignerFromChain)(
CRYPT_PROVIDER_DATA *pProvData,
DWORD idxSigner,
BOOL fCounterSigner,
DWORD idxCounterSigner
);
typedef LONG (WINAPI *_WinVerifyTrust)(
HWND hWnd,
GUID *pgActionID,
LPVOID pWVTData
);
typedef DWORD (WINAPI *_CertNameToStr)(
DWORD dwCertEncodingType,
PCERT_NAME_BLOB pName,
DWORD dwStrType,
LPTSTR psz,
DWORD csz
);
typedef PCCERT_CONTEXT (WINAPI *_CertDuplicateCertificateContext)(
_In_ PCCERT_CONTEXT pCertContext
);
typedef BOOL (WINAPI *_CertFreeCertificateContext)(
_In_ PCCERT_CONTEXT pCertContext
);
typedef BOOL (WINAPI *_CryptUIDlgViewSignerInfo)(
_In_ CRYPTUI_VIEWSIGNERINFO_STRUCT *pcvsi
);
#endif

108
phlib/include/workqueue.h Normal file
View File

@@ -0,0 +1,108 @@
#ifndef _PH_WORKQUEUE_H
#define _PH_WORKQUEUE_H
#ifdef __cplusplus
extern "C" {
#endif
#if defined(DEBUG)
extern PPH_LIST PhDbgWorkQueueList;
extern PH_QUEUED_LOCK PhDbgWorkQueueListLock;
#endif
typedef struct _PH_WORK_QUEUE
{
PH_RUNDOWN_PROTECT RundownProtect;
BOOLEAN Terminating;
LIST_ENTRY QueueListHead;
PH_QUEUED_LOCK QueueLock;
PH_CONDITION QueueEmptyCondition;
ULONG MaximumThreads;
ULONG MinimumThreads;
ULONG NoWorkTimeout;
PH_QUEUED_LOCK StateLock;
HANDLE SemaphoreHandle;
ULONG CurrentThreads;
ULONG BusyCount;
} PH_WORK_QUEUE, *PPH_WORK_QUEUE;
typedef VOID (NTAPI *PPH_WORK_QUEUE_ITEM_DELETE_FUNCTION)(
_In_ PUSER_THREAD_START_ROUTINE Function,
_In_ PVOID Context
);
typedef struct _PH_WORK_QUEUE_ENVIRONMENT
{
LONG BasePriority : 6; // Base priority increment
ULONG IoPriority : 3; // I/O priority hint
ULONG PagePriority : 3; // Page/memory priority
ULONG ForceUpdate : 1; // Always set priorities regardless of cached values
ULONG SpareBits : 19;
} PH_WORK_QUEUE_ENVIRONMENT, *PPH_WORK_QUEUE_ENVIRONMENT;
PHLIBAPI
VOID
NTAPI
PhInitializeWorkQueue(
_Out_ PPH_WORK_QUEUE WorkQueue,
_In_ ULONG MinimumThreads,
_In_ ULONG MaximumThreads,
_In_ ULONG NoWorkTimeout
);
PHLIBAPI
VOID
NTAPI
PhDeleteWorkQueue(
_Inout_ PPH_WORK_QUEUE WorkQueue
);
PHLIBAPI
VOID
NTAPI
PhWaitForWorkQueue(
_Inout_ PPH_WORK_QUEUE WorkQueue
);
PHLIBAPI
VOID
NTAPI
PhQueueItemWorkQueue(
_Inout_ PPH_WORK_QUEUE WorkQueue,
_In_ PUSER_THREAD_START_ROUTINE Function,
_In_opt_ PVOID Context
);
PHLIBAPI
VOID
NTAPI
PhQueueItemWorkQueueEx(
_Inout_ PPH_WORK_QUEUE WorkQueue,
_In_ PUSER_THREAD_START_ROUTINE Function,
_In_opt_ PVOID Context,
_In_opt_ PPH_WORK_QUEUE_ITEM_DELETE_FUNCTION DeleteFunction,
_In_opt_ PPH_WORK_QUEUE_ENVIRONMENT Environment
);
PHLIBAPI
VOID
NTAPI
PhInitializeWorkQueueEnvironment(
_Out_ PPH_WORK_QUEUE_ENVIRONMENT Environment
);
PHLIBAPI
PPH_WORK_QUEUE
NTAPI
PhGetGlobalWorkQueue(
VOID
);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,49 @@
#ifndef _PH_WORKQUEUEP_H
#define _PH_WORKQUEUEP_H
typedef struct _PH_WORK_QUEUE_ITEM
{
LIST_ENTRY ListEntry;
PUSER_THREAD_START_ROUTINE Function;
PVOID Context;
PPH_WORK_QUEUE_ITEM_DELETE_FUNCTION DeleteFunction;
PH_WORK_QUEUE_ENVIRONMENT Environment;
} PH_WORK_QUEUE_ITEM, *PPH_WORK_QUEUE_ITEM;
VOID PhpGetDefaultWorkQueueEnvironment(
_Out_ PPH_WORK_QUEUE_ENVIRONMENT Environment
);
VOID PhpUpdateWorkQueueEnvironment(
_Inout_ PPH_WORK_QUEUE_ENVIRONMENT CurrentEnvironment,
_In_ PPH_WORK_QUEUE_ENVIRONMENT NewEnvironment
);
PPH_WORK_QUEUE_ITEM PhpCreateWorkQueueItem(
_In_ PUSER_THREAD_START_ROUTINE Function,
_In_opt_ PVOID Context,
_In_opt_ PPH_WORK_QUEUE_ITEM_DELETE_FUNCTION DeleteFunction,
_In_opt_ PPH_WORK_QUEUE_ENVIRONMENT Environment
);
VOID PhpDestroyWorkQueueItem(
_In_ PPH_WORK_QUEUE_ITEM WorkQueueItem
);
VOID PhpExecuteWorkQueueItem(
_Inout_ PPH_WORK_QUEUE_ITEM WorkQueueItem
);
HANDLE PhpGetSemaphoreWorkQueue(
_Inout_ PPH_WORK_QUEUE WorkQueue
);
BOOLEAN PhpCreateWorkQueueThread(
_Inout_ PPH_WORK_QUEUE WorkQueue
);
NTSTATUS PhpWorkQueueThreadStart(
_In_ PVOID Parameter
);
#endif